|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Cross-translation-unit contract inside libs/ra8_c6link. More...
#include <stddef.h>#include <stdint.h>#include "ra8_attributes.h"#include "ra8_c6link.h"#include "ra8_err.h"#include "esp_hosted_header.h"#include "esp_hosted_interface.h"#include "esp_hosted_rpc.pb-c.h"#include "esp_hosted_transport.h"#include "protobuf-c/protobuf-c.h"Go to the source code of this file.
Data Structures | |
| struct | ra8_c6link_rx_view |
| Where the payload of a classified frame is, and what it claims to be. More... | |
| struct | ra8_c6link_take_ctx |
| What an answer extractor is given alongside the decoded message. More... | |
Typedefs | |
| typedef struct ra8_c6link_rx_view | ra8_c6link_rx_view_t |
| typedef struct ra8_c6link_take_ctx | ra8_c6link_take_ctx_t |
Functions | |
| void * | priv_c6link_arena_alloc (void *ctx, size_t size) |
| Take a block from the link's decode arena. | |
| void | priv_c6link_arena_free (void *ctx, void *pointer) |
| Return a block to the link's decode arena. | |
| void | priv_c6link_arena_reset (ra8_c6link_t *link) |
| Empty the link's decode arena. | |
| void | priv_c6link_arena_bind (ProtobufCAllocator *out, ra8_c6link_t *link) |
| Bind an allocator descriptor to a link's arena. | |
| void | priv_c6link_frame_filler (uint8_t *tx) |
| Stamp the transmit transaction as the host's idle filler. | |
| void | priv_c6link_frame_seal (uint8_t *tx, uint8_t if_type, uint8_t if_num, uint16_t len) |
| Wrap an already-staged payload in a payload header. | |
| ra8_c6link_frame_class_t | priv_c6link_frame_classify (uint8_t *rx, ra8_c6link_rx_view_t *view) |
| Decide what a received transaction is, and where its payload lies. | |
| uint8_t | priv_c6link_caps (uint8_t *out, uint8_t cap) |
| Build the host-capabilities announcement. | |
| ra8_err_t | priv_c6link_tlv_open (uint8_t *out, uint16_t cap, uint16_t proto_len, uint16_t *body_at) |
| Write both envelope tags ahead of a protobuf payload. | |
| const uint8_t * | priv_c6link_tlv_body (const uint8_t *payload, uint16_t len, uint16_t *proto_len) |
| Strip the envelope off a received serial payload. | |
| ra8_err_t | priv_c6link_take_resp (void *ctx, const void *msg_v) |
| Extract the result code from an answer that carries nothing else. | |
| ra8_err_t | priv_c6link_bare_req (ra8_c6link_t *link, uint32_t req_id) |
| Issue a request whose body carries no fields and whose answer carries only a result code. | |
| ra8_err_t | priv_c6link_rpc_call (ra8_c6link_t *link, Rpc *req, uint32_t resp_id, ra8_c6link_take_fn_t take, void *take_ctx) |
| Issue one request and pump until its answer arrives. | |
| bool | priv_c6link_rpc_consume (ra8_c6link_t *link, const uint8_t *payload, uint16_t len) |
| Decode one control-plane payload and act on it. | |
| ra8_err_t | priv_c6link_resp (ra8_c6link_t *link, uint32_t rpc_id, int32_t resp) |
| Map a co-processor result code onto an ra8 error, recording it. | |
| ra8_err_t | priv_c6link_pump (ra8_c6link_t *link, uint16_t max_transactions, ra8_c6link_stats_t *stats) |
| Clock transactions until the budget or the wait says stop. | |
| bool | priv_c6link_dispatch (ra8_c6link_t *link, const ra8_c6link_rx_view_t *view) |
| Route one well-formed received frame to whatever understands it. | |
| void | priv_c6link_emit (ra8_c6link_t *link, const ra8_c6link_event_t *ev) |
| Deliver one decoded announcement to the registered callback. | |
| uint8_t | priv_c6link_copy_str (char *dst, uint8_t cap, const ProtobufCBinaryData *src) |
| Copy a length-counted binary field into a NUL-terminated string. | |
| bool | priv_c6link_copy_mac (ra8_c6link_mac_t *dst, const ProtobufCBinaryData *src) |
| Copy a binary field into a MAC address, all-or-nothing. | |
Cross-translation-unit contract inside libs/ra8_c6link.
Not public API. Only the six ra8_c6link_*.c translation units include this, plus tests under tests/ driving MC/DC vectors against helpers that no public entry point can reach with the required argument combinations. Application code must use ra8_c6link.h and ra8_c6link_wifi.h.
This is also the only first-party header that names the vendored esp-hosted types. Keeping the includes here is what lets the public headers stay free of the esp-hosted include path.
Definition in file ra8_c6link_internal.h.
| typedef struct ra8_c6link_rx_view ra8_c6link_rx_view_t |
| typedef struct ra8_c6link_take_ctx ra8_c6link_take_ctx_t |
| enum ra8_c6link_caps_t : uint8_t |
The host-capabilities announcement, tag by tag.
Byte for byte the privileged frame upstream's transport_drv.c composes in send_slave_config(): an ESP_PRIV_EVENT_INIT header followed by five LEGACY-OK: send_slave_config() is the upstream esp-hosted symbol name one-octet TLVs. Sending it is not optional politeness – the co-processor treats it as the host's arrival and (re)announces itself with Event_ESPInit in reply, and until it has been sent this co-processor build answers no RPC at all. That was measured: a facade that skipped it answered once, on a co-processor another application had already announced to, and then never again.
The three policy values are the host's own and are restated here rather than included, because the port headers that define them do not exist in the host test build. They match port_esp_hosted_host_config_features.h.
| Enumerator | |
|---|---|
| k_ra8_c6link_caps_type | Offset of the event-type octet. |
| k_ra8_c6link_caps_len | Offset of the event-length octet. |
| k_ra8_c6link_caps_hdr | Octets before the first TLV. |
| k_ra8_c6link_caps_tags | TLVs this host emits. |
| k_ra8_c6link_caps_value_len | Value width of every tag emitted. |
| k_ra8_c6link_caps_stride | Octets one one-valued TLV occupies. |
| k_ra8_c6link_caps_bytes | Whole frame: two header octets plus five three-octet TLVs. |
| k_ra8_c6link_caps_host | Host capability word. Zero, as upstream's own host sends. |
| k_ra8_c6link_caps_chip | ESP_PRIV_FIRMWARE_CHIP_ESP32C6: the part this board carries. |
| k_ra8_c6link_caps_raw_tp | Raw-throughput test direction; disabled, matching H_TEST_RAW_TP_DIR. |
| k_ra8_c6link_caps_throttle_high | Flow-control high-water mark, H_WIFI_TX_DATA_THROTTLE_HIGH_THRESHOLD. |
| k_ra8_c6link_caps_throttle_low | Flow-control low-water mark, H_WIFI_TX_DATA_THROTTLE_LOW_THRESHOLD. |
Definition at line 383 of file ra8_c6link_internal.h.
| enum ra8_c6link_frame_class_t : uint8_t |
What one received transaction turned out to be.
The order the classifier applies these in is upstream's, from process_spi_rx_buf(): zero length first (filler), then the header sanity tests, then the checksum. Judging a filler frame by the rules for a data frame is what once made a healthy link report a failure, so filler is its own verdict and not a malformed data frame.
Definition at line 68 of file ra8_c6link_internal.h.
| enum ra8_c6link_tlv_t : uint16_t |
The serial endpoint's TLV envelope, tag by tag.
Two tags, each a one-byte type followed by a little-endian 16-bit length: the endpoint name, then the protobuf payload. The endpoint-name length is taken from the vendored RPC_EP_NAME_RSP string rather than written down, because upstream requires both endpoint names to be the same length and its parser checks that.
Definition at line 464 of file ra8_c6link_internal.h.
| void * priv_c6link_arena_alloc | ( | void * | ctx, |
| size_t | size ) |
Take a block from the link's decode arena.
The alloc row of the ::ProtobufCAllocator handed to the generated codec. Bumps a pointer through the caller-supplied arena, eight-byte aligned. There is no fallback to a heap: this firmware has none, and an over-request must fail the decode rather than fault.
| [in] | ctx | The ra8_c6link_t whose arena to draw from; must be non-null. |
| [in] | size | Bytes requested; zero yields a non-null zero-length block, which is what protobuf-c expects. |
| NULL | The arena is exhausted, or ctx was null. |
Definition at line 67 of file ra8_c6link_arena.c.
References ra8_c6link::arena, ra8_c6link::arena_bytes, ra8_c6link::arena_last, ra8_c6link::arena_used, k_ra8_c6link_arena_mask, and RA8_PRIV.
Referenced by priv_c6link_arena_bind().
| void priv_c6link_arena_bind | ( | ProtobufCAllocator * | out, |
| ra8_c6link_t * | link ) |
Bind an allocator descriptor to a link's arena.
Fills the ::ProtobufCAllocator the generated codec is handed. Passing null to the codec instead would select protobuf-c's default allocator, which calls malloc; in this firmware _sbrk is a strong symbol that reports a fatal error, so that path faults rather than failing.
| [out] | out | Descriptor to fill; must be non-null. |
| [in] | link | Link whose arena backs it; must be non-null. |
link is open. out outlives every decode it is passed to. out are set. Definition at line 116 of file ra8_c6link_arena.c.
References priv_c6link_arena_alloc(), priv_c6link_arena_free(), and RA8_PRIV.
Referenced by internal_mdl_take_accepted(), internal_mdl_take_cancelled(), internal_mdl_take_chunk(), and priv_c6link_rpc_consume().
| void priv_c6link_arena_free | ( | void * | ctx, |
| void * | pointer ) |
Return a block to the link's decode arena.
The free row of the allocator. A bump arena cannot free out of order, but it can free the newest block: when pointer is the most recent allocation the bump offset rolls back to it, which is what turns the codec's own unwind-on-error path into genuinely reclaimed space rather than waste. Any other pointer is retained until priv_c6link_arena_reset runs, which the RPC layer does after every decode.
| [in] | ctx | The ra8_c6link_t whose arena owns the block; null is ignored. |
| [in] | pointer | Block to release; null is ignored. |
pointer came from priv_c6link_arena_alloc on the same link. pointer. Definition at line 94 of file ra8_c6link_arena.c.
References ra8_c6link::arena, ra8_c6link::arena_last, ra8_c6link::arena_used, and RA8_PRIV.
Referenced by priv_c6link_arena_bind().
| void priv_c6link_arena_reset | ( | ra8_c6link_t * | link | ) |
Empty the link's decode arena.
Called after every message is decoded and released, so each decode starts from a known offset and no leak can accumulate across messages. That is what bounds the arena requirement to one message rather than to a run.
| [in,out] | link | Link whose arena to empty; null is ignored. |
Definition at line 107 of file ra8_c6link_arena.c.
References ra8_c6link::arena_last, ra8_c6link::arena_used, and RA8_PRIV.
Referenced by priv_c6link_rpc_consume().
|
nodiscard |
Issue a request whose body carries no fields and whose answer carries only a result code.
Req_WifiStart, Req_WifiStop, Req_WifiDeinit, Req_WifiConnect and Req_WifiDisconnect are all this shape: an empty body, a result code back. They differ only in which generated initialiser and which pair of ids they name, so they share one implementation.
| [in,out] | link | Open handle; must be non-null. |
| [in] | req_id | RPC_ID__Req_* to send. |
| k_ra8_ok | The co-processor reported success. |
| k_ra8_err_not_supported | req_id is not one of the five. |
| k_ra8_err_timeout | No answer arrived within the budget. |
| k_ra8_err_hw_timeout | The co-processor never armed HANDSHAKE, so no transaction was clocked. |
| k_ra8_err_protocol_error | The answer reported a failure. |
| k_ra8_err_spi_error | The transport refused a transfer. |
link is open. Definition at line 263 of file ra8_c6link_wifi.c.
References internal_c6link_wifi_bare_body(), k_ra8_err_not_supported, k_ra8_err_null_ptr, priv_c6link_rpc_call(), priv_c6link_take_resp(), and RA8_PRIV.
Referenced by ra8_c6link_wifi_join(), ra8_c6link_wifi_leave(), ra8_c6link_wifi_start(), and ra8_c6link_wifi_stop().
|
nodiscard |
Build the host-capabilities announcement.
Pure formatting: no hardware, no link state. Split out so the exact octets can be compared against the protocol in a host test rather than only against the code that wrote them.
| [out] | out | Buffer to fill; must be non-null. |
| [in] | cap | Octets available at out. |
| 0 | out was null or cap is below k_ra8_c6link_caps_bytes. |
cap octets are writable at out. out is not modified.Definition at line 194 of file ra8_c6link_frame.c.
References internal_c6link_caps_tlv(), k_ra8_c6link_caps_bytes, k_ra8_c6link_caps_chip, k_ra8_c6link_caps_hdr, k_ra8_c6link_caps_host, k_ra8_c6link_caps_len, k_ra8_c6link_caps_raw_tp, k_ra8_c6link_caps_stride, k_ra8_c6link_caps_tags, k_ra8_c6link_caps_throttle_high, k_ra8_c6link_caps_throttle_low, k_ra8_c6link_caps_type, and RA8_PRIV.
Referenced by ra8_c6link_await_ready().
|
nodiscard |
Copy a binary field into a MAC address, all-or-nothing.
| [out] | dst | Address to fill; must be non-null. |
| [in] | src | Binary field from a decoded message; null clears dst. |
| true | dst holds the address. |
| false | The field was absent or the wrong length; dst is cleared. |
dst does not overlap src. dst is either fully written or fully cleared. src is not modified.Definition at line 56 of file ra8_c6link.c.
References k_ra8_c6link_mac_bytes, ra8_c6link_mac::octet, and RA8_PRIV.
Referenced by internal_c6link_rpc_ev_connected(), internal_c6link_rpc_ev_disconnected(), internal_c6link_take_ap(), and internal_c6link_take_mac().
| uint8_t priv_c6link_copy_str | ( | char * | dst, |
| uint8_t | cap, | ||
| const ProtobufCBinaryData * | src ) |
Copy a length-counted binary field into a NUL-terminated string.
Shared by the event decoder and the AP-record decoder. The co-processor supplies the bytes, so nothing about them is trusted: the copy is bounded by the destination and terminated whatever the source did.
| [out] | dst | Destination; must be non-null and cap bytes long. |
| [in] | cap | Bytes available at dst, including the terminator. |
| [in] | src | Binary field from a decoded message; null copies nothing. |
| 0 | The field was absent, empty, or cap left no room. |
cap is at least one, so a terminator always fits. dst does not overlap src. dst is NUL-terminated. Definition at line 37 of file ra8_c6link.c.
References RA8_PRIV.
Referenced by internal_c6link_rpc_ev_connected(), internal_c6link_rpc_ev_disconnected(), internal_c6link_take_ap(), and internal_c6link_take_fw().
|
nodiscard |
Route one well-formed received frame to whatever understands it.
Control-plane frames go to the RPC decoder, station and access-point frames to the Ethernet receive callback, and everything else is counted. ESP_PRIV_IF frames are counted rather than decoded: this co-processor build transmits its only privileged frame with a checksum that does not match its own header (#529), so a conformant host never sees a valid one.
| [in,out] | link | Open handle; must be non-null. |
| [in] | view | Payload location from the classifier; must be non-null. |
| true | The awaited answer arrived. |
| false | Keep clocking. |
view is populated. Definition at line 87 of file ra8_c6link.c.
References ra8_c6link::cb_ctx, ra8_c6link_stats::eth_in, ra8_c6link_rx_view::if_type, ra8_c6link_rx_view::len, ra8_c6link_rx_view::offset, priv_c6link_rpc_consume(), RA8_PRIV, ra8_c6link::rx, ra8_c6link::rx_cb, ra8_c6link::stats, and ra8_c6link_stats::unrouted.
Referenced by internal_c6link_pump_receive().
| void priv_c6link_emit | ( | ra8_c6link_t * | link, |
| const ra8_c6link_event_t * | ev ) |
Deliver one decoded announcement to the registered callback.
Lives in ra8_c6link.c beside the rest of the handle's state, and is called from the RPC decoder once it has turned an Event_* message into a first-party record.
| [in,out] | link | Open handle; must be non-null. |
| [in] | ev | Decoded announcement; must be non-null. |
ev is fully populated for its kind. ev is the boot announcement.Definition at line 71 of file ra8_c6link.c.
References ra8_c6link::boot_seen, ra8_c6link::cb_ctx, ra8_c6link::event_cb, ra8_c6link_stats::events, k_ra8_c6link_event_boot, ra8_c6link_event::kind, RA8_PRIV, and ra8_c6link::stats.
Referenced by internal_c6link_rpc_event().
|
nodiscard |
Decide what a received transaction is, and where its payload lies.
Applies upstream's ordering, and verifies the checksum by zeroing the field in place and restoring it, so the value a caller later reports is the one the co-processor actually sent.
| [in,out] | rx | Received transaction; must be non-null. Momentarily modified and restored. |
| [out] | view | Payload location and interface, filled only for a data frame; must be non-null. |
| k_ra8_c6link_frame_data | The payload is real and view describes it. |
| k_ra8_c6link_frame_idle | The co-processor had nothing to send. |
| k_ra8_c6link_frame_malformed | The header could not be believed. |
| k_ra8_c6link_frame_bad_checksum | The integrity check failed. |
rx is stable. rx covers a whole transaction. rx holds exactly the bytes it held on entry. view is written only on k_ra8_c6link_frame_data.rx.Definition at line 227 of file ra8_c6link_frame.c.
References ra8_c6link_rx_view::if_num, ra8_c6link_rx_view::if_type, internal_c6link_frame_sum(), k_ra8_c6link_frame_bad_checksum, k_ra8_c6link_frame_data, k_ra8_c6link_frame_idle, k_ra8_c6link_frame_malformed, k_ra8_c6link_header_bytes, k_ra8_c6link_max_payload, ra8_c6link_rx_view::len, memcpy(), ra8_c6link_rx_view::offset, and RA8_PRIV.
Referenced by internal_c6link_pump_receive().
| void priv_c6link_frame_filler | ( | uint8_t * | tx | ) |
Stamp the transmit transaction as the host's idle filler.
Field for field what the reference host sends when it has nothing queued: if_type = ESP_MAX_IF and every other byte zero, checksum included. The co-processor needs a transaction to answer in, so an idle host still clocks one.
| [out] | tx | Transmit transaction; must be non-null and k_ra8_c6link_frame_bytes long. |
tx. tx covers a whole transaction. Definition at line 136 of file ra8_c6link_frame.c.
References internal_c6link_frame_clear(), k_ra8_c6link_hdr_nibble, memcpy(), and RA8_PRIV.
Referenced by priv_c6link_pump().
| void priv_c6link_frame_seal | ( | uint8_t * | tx, |
| uint8_t | if_type, | ||
| uint8_t | if_num, | ||
| uint16_t | len ) |
Wrap an already-staged payload in a payload header.
The payload is expected to be sitting at tx + k_ra8_c6link_header_bytes already – both the RPC encoder and the Ethernet transmit path write it there directly, so nothing is copied twice. This fills the header in front of it, zeroes the tail, and computes the checksum over header plus payload with the checksum field taken as zero, exactly as get_next_tx_buffer() does upstream.
| [in,out] | tx | Transmit transaction; must be non-null. |
| [in] | if_type | Interface type for the frame, 0..15. |
| [in] | if_num | Interface number for the frame, 0..15. |
| [in] | len | Payload length already staged; at most k_ra8_c6link_max_payload. |
len bytes are staged at tx + k_ra8_c6link_header_bytes. len is within k_ra8_c6link_max_payload. Definition at line 148 of file ra8_c6link_frame.c.
References internal_c6link_frame_clear(), k_ra8_c6link_hdr_nibble, k_ra8_c6link_hdr_seq, k_ra8_c6link_header_bytes, k_ra8_c6link_max_payload, memcpy(), and RA8_PRIV.
Referenced by priv_c6link_pump().
|
nodiscard |
Clock transactions until the budget or the wait says stop.
The implementation behind ra8_c6link_poll, and the loop every request runs inside. Split out so the public entry point stays a validation wrapper and so tests can drive it against a co-processor model directly.
| [in,out] | link | Open handle; must be non-null. |
| [in] | max_transactions | Transactions this call may clock; non-zero. |
| [out] | stats | Counters describing the run; must be non-null. |
| k_ra8_ok | The pump ran to its budget or until the wait was satisfied. |
| k_ra8_err_hw_timeout | HANDSHAKE never went active. |
| k_ra8_err_spi_error | The transport refused a transfer. |
link is open and its transport is bound. stats has been cleared by the caller. max_transactions transactions were clocked. Definition at line 105 of file ra8_c6link_pump.c.
References ra8_c6link_transport::ctx, ra8_c6link_transport::delay_ms, ra8_c6link_stats::hs_timeouts, internal_c6link_pump_handshake(), internal_c6link_pump_receive(), k_ra8_c6link_frame_bytes, k_ra8_c6link_gap_ms, k_ra8_c6link_hs_giveup, k_ra8_err_hw_timeout, k_ra8_err_null_ptr, k_ra8_err_spi_error, k_ra8_ok, priv_c6link_frame_filler(), priv_c6link_frame_seal(), RA8_PRIV, ra8_c6link::rx, ra8_c6link::stats, ra8_c6link_transport::transfer, ra8_c6link_stats::transfers, ra8_c6link::transport, ra8_c6link::tx, ra8_c6link::tx_if, and ra8_c6link::tx_len.
Referenced by priv_c6link_rpc_call(), ra8_c6link_await_ready(), ra8_c6link_eth_send(), and ra8_c6link_poll().
|
nodiscard |
Map a co-processor result code onto an ra8 error, recording it.
Every Resp_* message carries an int32_t resp that is an esp_err_t on the far side. This preserves the general-purpose error's meaning in the RA8 domain while recording both the original value and request id in the fault slot. Unknown and component-specific values remain protocol errors, but the retained raw status still tells bring-up exactly what the C6 reported.
| [in,out] | link | Open handle; must be non-null. |
| [in] | rpc_id | RPC_ID__Req_* the answer belongs to. |
| [in] | resp | The co-processor's result code. |
| k_ra8_ok | resp was zero and the fault slot was cleared. |
| k_ra8_err_* | A mapped general error, or protocol error for an unknown status; the fault slot names rpc_id and the exact raw resp. |
link is open. resp came from a decoded answer, not from a default. Definition at line 153 of file ra8_c6link_rpc.c.
References ra8_c6link::fault, internal_c6link_remote_error(), k_ra8_err_null_ptr, k_ra8_ok, RA8_PRIV, ra8_c6link_fault::resp, and ra8_c6link_fault::rpc_id.
Referenced by internal_c6link_take_ap(), internal_c6link_take_fw(), internal_c6link_take_mac(), internal_mdl_take_response(), and priv_c6link_take_resp().
|
nodiscard |
Issue one request and pump until its answer arrives.
Assigns a fresh UID, packs req into the transmit transaction behind its TLV envelope, arms the link's wait slot, and pumps. Announcements and Ethernet frames that arrive meanwhile are dispatched normally; the pump stops as soon as the answer is extracted.
| [in,out] | link | Open handle; must be non-null. |
| [in,out] | req | Request to send; must be non-null and fully populated apart from its UID, which this call assigns. |
| [in] | resp_id | RPC_ID__Resp_* that answers req. |
| [in] | take | Extractor for the answer's fields; must be non-null. |
| [in] | take_ctx | Context handed to take. |
| k_ra8_ok | The answer arrived and take accepted it. |
| k_ra8_err_null_ptr | An argument was null. |
| k_ra8_err_not_initialized | link is not open. |
| k_ra8_err_busy | A request is already outstanding. |
| k_ra8_err_invalid_size | The packed request does not fit a frame. |
| k_ra8_err_validation_failed | The codec packed a different number of bytes than it predicted. |
| k_ra8_err_timeout | No answer arrived within the budget. |
| k_ra8_err_hw_timeout | The co-processor never armed HANDSHAKE, so no transaction was clocked. |
| k_ra8_err_protocol_error | take rejected the answer. |
| k_ra8_err_spi_error | The transport refused a transfer. |
link. req.Definition at line 168 of file ra8_c6link_rpc.c.
References ra8_c6link_wait::armed, ra8_c6link::fault, internal_c6link_rpc_stage(), k_ra8_c6link_rpc_transfers, k_ra8_err_busy, k_ra8_err_not_initialized, k_ra8_err_null_ptr, k_ra8_err_timeout, k_ra8_ok, ra8_c6link::next_uid, ra8_c6link::open, priv_c6link_pump(), RA8_PRIV, ra8_secure_memzero(), ra8_c6link_fault::resp, ra8_c6link_wait::result, ra8_c6link_fault::rpc_id, ra8_c6link_wait::satisfied, ra8_c6link::tx, ra8_c6link::tx_len, and ra8_c6link::wait.
Referenced by internal_c6link_sta_set_config(), internal_c6link_wifi_do_init(), internal_c6link_wifi_do_mode(), internal_mdl_call(), priv_c6link_bare_req(), ra8_c6link_fw_version(), ra8_c6link_wifi_ap_info(), and ra8_c6link_wifi_mac().
|
nodiscard |
Decode one control-plane payload and act on it.
Unwraps the envelope, decodes the message into the arena, then either satisfies the outstanding wait, delivers an announcement, or drops it. The arena is reset before returning however that goes.
| [in,out] | link | Open handle; must be non-null. |
| [in] | payload | Frame payload; must be non-null. |
| [in] | len | Payload length in bytes. |
| true | The awaited answer arrived and was extracted. |
| false | Anything else, including a delivered announcement. |
len bytes are readable at payload. Definition at line 359 of file ra8_c6link_rpc.c.
References internal_c6link_rpc_answer(), internal_c6link_rpc_event(), priv_c6link_arena_bind(), priv_c6link_arena_reset(), priv_c6link_tlv_body(), RA8_PRIV, ra8_c6link_stats::rpc_in, ra8_c6link::stats, and ra8_c6link_stats::undecodable.
Referenced by priv_c6link_dispatch().
|
nodiscard |
Extract the result code from an answer that carries nothing else.
Most requests are answered by a message whose only field is resp. Which arm of the payload union holds it depends on the message id, so this switches on that rather than existing eight times over.
| [in] | ctx | A ra8_c6link_take_ctx_t naming the link and the request id. |
| [in] | msg_v | The decoded Rpc; must be non-null. |
| k_ra8_ok | The co-processor reported success. |
| k_ra8_err_protocol_error | It reported a failure, or the answer was one this extractor does not know how to read. |
ctx names a live link. msg_v is still owned by the decoder. Definition at line 126 of file ra8_c6link_wifi.c.
References ra8_c6link_take_ctx::link, priv_c6link_resp(), RA8_PRIV, and ra8_c6link_take_ctx::rpc_id.
Referenced by internal_c6link_sta_set_config(), internal_c6link_wifi_do_init(), internal_c6link_wifi_do_mode(), and priv_c6link_bare_req().
|
nodiscard |
Strip the envelope off a received serial payload.
Both endpoint names are accepted, as upstream's parse_tlv() does: a response arrives on RPCRsp and an unsolicited event on RPCEvt, and the two are the same length by construction.
| [in] | payload | Frame payload; must be non-null. |
| [in] | len | Payload length in bytes. |
| [out] | proto_len | Protobuf length found; must be non-null. |
| NULL | The tags, the endpoint name or the lengths did not check out. |
len bytes are readable at payload. proto_len is writable. payload. proto_len is zero.Definition at line 146 of file ra8_c6link_tlv.c.
References internal_c6link_tlv_len(), internal_c6link_tlv_named(), k_ra8_c6link_tlv_ep_len, k_ra8_c6link_tlv_overhead, k_ra8_c6link_tlv_t_data, k_ra8_c6link_tlv_t_epname, k_ra8_c6link_tlv_type, and k_ra8_c6link_tlv_value.
Referenced by priv_c6link_rpc_consume().
|
nodiscard |
Write both envelope tags ahead of a protobuf payload.
| [out] | out | Buffer to fill; must be non-null. |
| [in] | cap | Bytes available at out. |
| [in] | proto_len | Protobuf length that will follow the envelope. |
| [out] | body_at | Offset the protobuf must be written at; must be non-null. |
| k_ra8_ok | The envelope is written and body_at names its payload. |
| k_ra8_err_null_ptr | out or body_at was null. |
| k_ra8_err_invalid_size | cap cannot hold envelope plus payload. |
cap bytes are writable at out. proto_len is the exact packed size, not an estimate. out is not modified and body_at is zero.Definition at line 91 of file ra8_c6link_tlv.c.
References internal_c6link_tlv_tag(), k_ra8_c6link_tlv_ep_len, k_ra8_c6link_tlv_overhead, k_ra8_c6link_tlv_t_data, k_ra8_c6link_tlv_t_epname, k_ra8_err_invalid_size, k_ra8_err_null_ptr, k_ra8_ok, and RA8_PRIV.
Referenced by internal_c6link_rpc_stage().