ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_c6link_rpc.c
Go to the documentation of this file.
1
36
37#include <stddef.h>
38#include <stdint.h>
39
40#include "ra8_attributes.h"
41#include "ra8_c6link.h"
42#include "ra8_c6link_internal.h"
43#include "ra8_secure.h"
44
58
79{
80 link->tx_len = 0U;
81
82 const size_t packed = rpc__get_packed_size(req);
83 if (packed > (size_t)k_ra8_c6link_max_payload) {
85 }
86
87 uint8_t* payload = &link->tx[k_ra8_c6link_header_bytes];
88 uint16_t body_at = 0U;
89 const ra8_err_t opened =
90 priv_c6link_tlv_open(payload, (uint16_t)k_ra8_c6link_max_payload, (uint16_t)packed, &body_at);
91 if (opened != k_ra8_ok) {
92 return opened;
93 }
94 if (rpc__pack(req, &payload[body_at]) != packed) {
96 }
97
98 link->tx_len = (uint16_t)((uint32_t)body_at + (uint32_t)packed);
99 link->tx_if = (uint8_t)ESP_SERIAL_IF;
100 return k_ra8_ok;
101}
102
152
153RA8_PRIV ra8_err_t priv_c6link_resp(ra8_c6link_t* link, uint32_t rpc_id, int32_t resp)
154{
155 if (link == nullptr) {
156 return k_ra8_err_null_ptr;
157 }
158 if (resp != 0) {
159 link->fault.rpc_id = rpc_id;
160 link->fault.resp = resp;
161 return internal_c6link_remote_error(resp);
162 }
163 link->fault.rpc_id = 0U;
164 link->fault.resp = 0;
165 return k_ra8_ok;
166}
167
169 Rpc* req,
170 uint32_t resp_id,
172 void* take_ctx)
173{
174 if ((link == nullptr) || (req == nullptr) || (take == nullptr)) {
175 return k_ra8_err_null_ptr;
176 }
177 if (!link->open) {
179 }
180 if (link->wait.armed || (link->tx_len != 0U)) {
181 return k_ra8_err_busy;
182 }
183
184 link->next_uid = link->next_uid + 1U;
185 req->uid = link->next_uid;
186
187 const ra8_err_t staged = internal_c6link_rpc_stage(link, req);
188 if (staged != k_ra8_ok) {
189 ra8_secure_memzero(link->tx, sizeof(link->tx));
190 return staged;
191 }
192
193 link->wait = (ra8_c6link_wait_t){
194 .uid = req->uid,
195 .resp_id = resp_id,
196 .take = take,
197 .take_ctx = take_ctx,
198 .result = k_ra8_ok,
199 .armed = true,
200 .satisfied = false,
201 };
202
203 ra8_c6link_stats_t stats = {};
204 const ra8_err_t pumped = priv_c6link_pump(link, (uint16_t)k_ra8_c6link_rpc_transfers, &stats);
205 const bool got = link->wait.satisfied;
206 const ra8_err_t result = link->wait.result;
207 link->wait = (ra8_c6link_wait_t){};
208 link->tx_len = 0U;
209 ra8_secure_memzero(link->tx, sizeof(link->tx));
210
211 if (pumped != k_ra8_ok) {
212 return pumped;
213 }
214 if (!got) {
215 link->fault.rpc_id = (uint32_t)req->msg_id;
216 link->fault.resp = 0;
217 return k_ra8_err_timeout;
218 }
219 return result;
220}
221
238 const WifiEventStaConnected* body)
239{
240 if (body == nullptr) {
241 return;
242 }
243 ev->ssid_len = priv_c6link_copy_str(ev->ssid, (uint8_t)sizeof ev->ssid, &body->ssid);
244 ev->channel = (uint8_t)body->channel;
245 (void)priv_c6link_copy_mac(&ev->bssid, &body->bssid);
246}
247
264 const WifiEventStaDisconnected* body)
265{
266 if (body == nullptr) {
267 return;
268 }
269 ev->ssid_len = priv_c6link_copy_str(ev->ssid, (uint8_t)sizeof ev->ssid, &body->ssid);
270 ev->reason = (uint16_t)body->reason;
271 ev->rssi = (int8_t)body->rssi;
272 (void)priv_c6link_copy_mac(&ev->bssid, &body->bssid);
273}
274
291RA8_INTERNAL static void internal_c6link_rpc_event(ra8_c6link_t* link, const Rpc* msg)
292{
293 ra8_c6link_event_t ev = {};
294
295 switch ((int32_t)msg->msg_id) {
296 case (int32_t)RPC_ID__Event_ESPInit:
298 if (msg->event_esp_init != nullptr) {
299 ev.reset_reason = msg->event_esp_init->cp_reset_reason;
300 }
301 break;
302 case (int32_t)RPC_ID__Event_StaConnected:
304 if (msg->event_sta_connected != nullptr) {
305 internal_c6link_rpc_ev_connected(&ev, msg->event_sta_connected->sta_connected);
306 }
307 break;
308 case (int32_t)RPC_ID__Event_StaDisconnected:
310 if (msg->event_sta_disconnected != nullptr) {
311 internal_c6link_rpc_ev_disconnected(&ev, msg->event_sta_disconnected->sta_disconnected);
312 }
313 break;
314 case (int32_t)RPC_ID__Event_WifiEventNoArgs:
316 if (msg->event_wifi_event_no_args != nullptr) {
317 ev.wifi_event_id = msg->event_wifi_event_no_args->event_id;
318 }
319 break;
320 default:
321 return;
322 }
323 priv_c6link_emit(link, &ev);
324}
325
348RA8_INTERNAL static bool internal_c6link_rpc_answer(ra8_c6link_t* link, const Rpc* msg)
349{
350 if (!link->wait.armed || (msg->uid != link->wait.uid) ||
351 ((uint32_t)msg->msg_id != link->wait.resp_id)) {
352 return false;
353 }
354 link->wait.result = link->wait.take(link->wait.take_ctx, msg);
355 link->wait.satisfied = true;
356 return true;
357}
358
359RA8_PRIV bool priv_c6link_rpc_consume(ra8_c6link_t* link, const uint8_t* payload, uint16_t len)
360{
361 if ((link == nullptr) || (payload == nullptr)) {
362 return false;
363 }
364
365 uint16_t proto_len = 0U;
366 const uint8_t* proto = priv_c6link_tlv_body(payload, len, &proto_len);
367 if (proto == nullptr) {
368 if (link->stats != nullptr) {
369 link->stats->undecodable++;
370 }
371 return false;
372 }
373
374 ProtobufCAllocator alloc = {};
375 priv_c6link_arena_bind(&alloc, link);
377
378 Rpc* msg = rpc__unpack(&alloc, (size_t)proto_len, proto);
379 if (msg == nullptr) {
380 if (link->stats != nullptr) {
381 link->stats->undecodable++;
382 }
384 return false;
385 }
386 if (link->stats != nullptr) {
387 link->stats->rpc_in++;
388 }
389
390 bool stop = false;
391 if (msg->msg_type == RPC_TYPE__Event) {
392 internal_c6link_rpc_event(link, msg);
393 } else if (msg->msg_type == RPC_TYPE__Resp) {
394 stop = internal_c6link_rpc_answer(link, msg);
395 } else {
396 /* A request arriving at a host is a co-processor defect, not a message
397 this side has any handler for. Counted, dropped, never acted on. */
398 if (link->stats != nullptr) {
399 link->stats->undecodable++;
400 }
401 }
402
403 rpc__free_unpacked(msg, &alloc);
405 return stop;
406}
Annotation-attribute framework macros for ra8-firmware.
#define RA8_PRIV
Module-private helper: shared across TUs but only inside one library.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
@ k_ra8_err_not_supported
Requested feature not compiled in, not wired, or not supported by this MCU variant.
Definition ra8_err.h:180
@ k_ra8_err_no_mem
Static buffer exhausted (no dynamic memory on this project).
Definition ra8_err.h:142
@ k_ra8_err_busy
Resource busy – blocking operation cannot proceed.
Definition ra8_err.h:195
@ k_ra8_err_checksum_mismatch
Stored / transmitted checksum does not match computed value.
Definition ra8_err.h:465
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
Definition ra8_err.h:161
@ k_ra8_err_validation_failed
Validation rule failed (caller-supplied invariant not satisfied).
Definition ra8_err.h:459
@ k_ra8_err_not_initialized
Module not initialized – _init() not yet called successfully.
Definition ra8_err.h:235
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
@ k_ra8_err_null_ptr
Pointer was NULL where a valid pointer was required.
Definition ra8_err.h:478
@ k_ra8_err_access_denied
Operation refused because the target is protected against it.
Definition ra8_err.h:276
@ k_ra8_err_protocol_error
Protocol-level error (e.g.
Definition ra8_err.h:429
@ k_ra8_err_timeout
Operation exceeded its time budget.
Definition ra8_err.h:188
@ k_ra8_err_not_found
Requested item not found (lookup / search missed).
Definition ra8_err.h:173
@ k_ra8_err_invalid_size
Invalid size parameter (too large, too small, or misaligned).
Definition ra8_err.h:167
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
Secure-comparison primitives for the crypto / secure-boot paths.
void ra8_secure_memzero(void *ptr, size_t len)
Securely zero a buffer such that the write cannot be optimised away.
Definition ra8_secure.c:37