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

Station credentials, association, and what the radio reports back. More...

#include <stddef.h>
#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_c6link.h"
#include "ra8_c6link_internal.h"
#include "ra8_c6link_wifi.h"
#include "ra8_secure.h"
Include dependency graph for ra8_c6link_wifi_sta.c:

Go to the source code of this file.

Data Structures

 Writable copies of the credentials, for the codec's binary fields. More...

Typedefs

typedef struct ra8_c6link_sta_wire_buf ra8_c6link_sta_wire_buf_t

Enumerations

enum  ra8_c6link_sta_wire_t : int32_t {
  k_ra8_c6link_iface_sta = 0 ,
  k_ra8_c6link_scan_fast = 0 ,
  k_ra8_c6link_sort_signal = 0 ,
  k_ra8_c6link_auth_open = 0
}
 Co-processor-side numbering the station requests transmit. More...

Functions

static uint8_t internal_c6link_sta_len (const char *text, uint8_t cap)
 Measure a NUL-terminated string without trusting it to be terminated.
ra8_err_t ra8_c6link_sta_cfg_set (ra8_c6link_sta_cfg_t *cfg, const char *ssid, const char *pass)
 Fill a station configuration from an SSID and a passphrase.
static void internal_c6link_sta_stage (ra8_c6link_sta_wire_buf_t *buf, const ra8_c6link_sta_cfg_t *cfg)
 Copy the caller's credentials into writable transmit storage.
static ra8_err_t internal_c6link_sta_set_config (ra8_c6link_t *link, const ra8_c6link_sta_cfg_t *cfg)
 Send Req_WifiSetConfig carrying the station credentials.
ra8_err_t ra8_c6link_wifi_join (ra8_c6link_t *link, const ra8_c6link_sta_cfg_t *cfg)
 Ask the station to associate with the configured network.
static ra8_err_t internal_c6link_take_mac (void *ctx, const void *msg_v)
 Extract the station address from its answer.
ra8_err_t ra8_c6link_wifi_mac (ra8_c6link_t *link, ra8_c6link_mac_t *out)
 Read the station interface's MAC address.
static ra8_err_t internal_c6link_take_ap (void *ctx, const void *msg_v)
 Extract the associated AP's record from its answer.
ra8_err_t ra8_c6link_wifi_ap_info (ra8_c6link_t *link, ra8_c6link_ap_info_t *out)
 Read what the co-processor knows about the associated AP.

Detailed Description

Station credentials, association, and what the radio reports back.

Tag
[Ring 4 / PAL] {World: NS}

The half of the station API that carries data rather than lifecycle: the credentials go up in Req_WifiSetConfig, and the station's own address and its view of the AP come back in Resp_GetMACAddress and Resp_WifiStaGetApInfo.

Why the optional sub-messages are always sent
WifiStaConfig carries a scan threshold and a protected-management-frame configuration as nested messages, and protobuf allows both to be absent. Upstream's own host allocates them unconditionally, so a co-processor that dereferences either without a null check has never been exercised with them missing. Sending them costs a handful of bytes and removes a class of failure this host cannot debug from its side of the wire.
Since
0.1.0

Definition in file ra8_c6link_wifi_sta.c.

Typedef Documentation

◆ ra8_c6link_sta_wire_buf_t

Enumeration Type Documentation

◆ ra8_c6link_sta_wire_t

enum ra8_c6link_sta_wire_t : int32_t

Co-processor-side numbering the station requests transmit.

These cross the link as plain integers and belong to ESP-IDF's enumerations on the far side, so they are named here rather than written as literals.

Invariant
k_ra8_c6link_iface_sta is WIFI_IF_STA (0): the interface index both Req_WifiSetConfig and Req_GetMACAddress select. The Req_GetMACAddress.mode field is named for wifi_mode_t but the co-processor passes it straight to esp_wifi_get_mac(wifi_interface_t, ...), so it is really an interface index: WIFI_IF_STA (0) returns the address the radio associates with, while WIFI_IF_AP (1) returns the SoftAP address (the station address plus one), which never associates – stamping frames with it is why an associated station could not finish DHCP.
Example:
body.iface = (int32_t)k_ra8_c6link_iface_sta;
See also
ra8_c6link_wifi_join
Since
0.1.0
Enumerator
k_ra8_c6link_iface_sta 

WIFI_IF_STA: STA interface index (also the Req_GetMACAddress.mode selector).

k_ra8_c6link_scan_fast 

WIFI_FAST_SCAN: stop at the first acceptable AP, which is what a fixed bench network wants.

k_ra8_c6link_sort_signal 

WIFI_CONNECT_AP_BY_SIGNAL.

k_ra8_c6link_auth_open 

WIFI_AUTH_OPEN as a threshold means "impose no minimum".

Definition at line 63 of file ra8_c6link_wifi_sta.c.

Function Documentation

◆ internal_c6link_sta_len()

uint8_t internal_c6link_sta_len ( const char * text,
uint8_t cap )
static

Measure a NUL-terminated string without trusting it to be terminated.

Bounded by the destination rather than by the string, so a caller that hands over an unterminated buffer gets a refusal instead of a read past its end.

Parameters
[in]textString to measure; must be non-null.
[in]capOctets that may be examined, including the terminator.
Returns
The length in octets, or cap when no terminator was found.
Return values
0The string is empty.
Precondition
cap octets are readable at text.
The caller treats a result equal to cap as "too long".
Postcondition
No buffer is modified.
The result is at most cap.
Note
The loop is bounded by cap (NASA Rule 2), which is why strnlen is not used: its bound is the same but its availability is not.
Since
0.1.0

Definition at line 91 of file ra8_c6link_wifi_sta.c.

References RA8_INTERNAL.

Referenced by ra8_c6link_sta_cfg_set().

◆ internal_c6link_sta_set_config()

ra8_err_t internal_c6link_sta_set_config ( ra8_c6link_t * link,
const ra8_c6link_sta_cfg_t * cfg )
static

Send Req_WifiSetConfig carrying the station credentials.

Sends the credentials and the search hints together: a known channel skips a full scan and a known BSSID pins the association to one radio.

Parameters
[in,out]linkOpen handle; must be non-null.
[in]cfgStation configuration; must be non-null and consistent.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe co-processor stored the configuration.
k_ra8_err_timeoutIt did not answer within the budget.
k_ra8_err_protocol_errorIt refused the configuration.
k_ra8_err_spi_errorThe transport refused a transfer.
Precondition
ra8_c6link_wifi_start has succeeded.
cfg's lengths match its strings.
Postcondition
On success the credentials are held by the co-processor.
On failure the fault slot names this request.
Note
The strings are transmitted as counted binary fields, so an SSID containing a zero octet – which 802.11 permits – survives.
Since
0.1.0

Definition at line 212 of file ra8_c6link_wifi_sta.c.

References ra8_c6link_sta_wire_buf::bssid, ra8_c6link_sta_cfg::bssid_set, ra8_c6link_sta_cfg::channel, internal_c6link_sta_stage(), k_ra8_c6link_auth_open, k_ra8_c6link_iface_sta, k_ra8_c6link_mac_bytes, k_ra8_c6link_scan_fast, k_ra8_c6link_sort_signal, ra8_c6link_sta_wire_buf::pass, ra8_c6link_sta_cfg::pass_len, priv_c6link_rpc_call(), priv_c6link_take_resp(), RA8_INTERNAL, ra8_secure_memzero(), ra8_c6link_sta_wire_buf::ssid, and ra8_c6link_sta_cfg::ssid_len.

Referenced by ra8_c6link_wifi_join().

◆ internal_c6link_sta_stage()

void internal_c6link_sta_stage ( ra8_c6link_sta_wire_buf_t * buf,
const ra8_c6link_sta_cfg_t * cfg )
static

Copy the caller's credentials into writable transmit storage.

The codec's binary fields are non-const because packing and unpacking share one type, so the credentials are copied rather than const-cast out of the caller's record.

Parameters
[out]bufStaging storage; must be non-null and zero-initialised.
[in]cfgStation configuration; must be non-null and consistent.
Returns
Nothing.
Precondition
cfg's lengths are within the protocol maxima, which ra8_c6link_wifi_join has already checked.
buf has been zero-initialised, so unused octets are zero.
Postcondition
Every declared octet of the credentials was copied.
cfg is not modified.
Note
The loops are bounded by the caller's declared lengths, which are in turn bounded by the field sizes (NASA Rule 2).
Since
0.1.0

Definition at line 178 of file ra8_c6link_wifi_sta.c.

References ra8_c6link_sta_cfg::bssid, ra8_c6link_sta_wire_buf::bssid, k_ra8_c6link_mac_bytes, ra8_c6link_mac::octet, ra8_c6link_sta_cfg::pass, ra8_c6link_sta_wire_buf::pass, ra8_c6link_sta_cfg::pass_len, RA8_INTERNAL, ra8_c6link_sta_cfg::ssid, ra8_c6link_sta_wire_buf::ssid, and ra8_c6link_sta_cfg::ssid_len.

Referenced by internal_c6link_sta_set_config().

◆ internal_c6link_take_ap()

ra8_err_t internal_c6link_take_ap ( void * ctx,
const void * msg_v )
static

Extract the associated AP's record from its answer.

An unassociated station is answered with a failure code rather than an empty record, so the result code is checked before the record is read.

Parameters
[in]ctxA ra8_c6link_take_ctx_t whose out is an AP record.
[in]msg_vThe decoded Rpc; must be non-null.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe record was copied out.
k_ra8_err_protocol_errorThe answer carried no body or no record, or reported a failure – which is what an unassociated station returns.
Precondition
ctx names a live link and a writable record.
msg_v is still owned by the decoder.
Postcondition
On success every field of the record is set.
On failure the record is left cleared by the caller.
Note
Runs inside the pump, on the polling thread.
Since
0.1.0

Definition at line 378 of file ra8_c6link_wifi_sta.c.

References ra8_c6link_ap_info::authmode, ra8_c6link_ap_info::bssid, ra8_c6link_ap_info::channel, k_ra8_err_protocol_error, k_ra8_ok, ra8_c6link_take_ctx::link, ra8_c6link_take_ctx::out, priv_c6link_copy_mac(), priv_c6link_copy_str(), priv_c6link_resp(), RA8_INTERNAL, ra8_c6link_take_ctx::rpc_id, ra8_c6link_ap_info::rssi, ra8_c6link_ap_info::ssid, and ra8_c6link_ap_info::ssid_len.

Referenced by ra8_c6link_wifi_ap_info().

◆ internal_c6link_take_mac()

ra8_err_t internal_c6link_take_mac ( void * ctx,
const void * msg_v )
static

Extract the station address from its answer.

Checks the co-processor's result code before the address, so a refusal is reported as a refusal rather than as a malformed address.

Parameters
[in]ctxA ra8_c6link_take_ctx_t whose out is a MAC address.
[in]msg_vThe decoded Rpc; must be non-null.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe address was copied out.
k_ra8_err_protocol_errorThe answer carried no body, reported a failure, or held an address of the wrong length.
Precondition
ctx names a live link and a writable address.
msg_v is still owned by the decoder.
Postcondition
On success the address holds six octets.
On failure the address is cleared.
Note
Runs inside the pump, on the polling thread.
Since
0.1.0

Definition at line 307 of file ra8_c6link_wifi_sta.c.

References k_ra8_err_protocol_error, k_ra8_ok, ra8_c6link_take_ctx::link, ra8_c6link_take_ctx::out, priv_c6link_copy_mac(), priv_c6link_resp(), RA8_INTERNAL, and ra8_c6link_take_ctx::rpc_id.

Referenced by ra8_c6link_wifi_mac().

◆ ra8_c6link_sta_cfg_set()

ra8_err_t ra8_c6link_sta_cfg_set ( ra8_c6link_sta_cfg_t * cfg,
const char * ssid,
const char * pass )
nodiscard

Fill a station configuration from an SSID and a passphrase.

Copies both strings into the record, bounded, and derives their lengths. An empty or null passphrase means an open network, which is a legitimate configuration and not an error. Everything else in the record is cleared, so a stale channel or BSSID from a previous use cannot survive.

Parameters
[out]cfgRecord to fill; must be non-null.
[in]ssidNUL-terminated SSID; must be non-null and 1.. k_ra8_c6link_ssid_max octets.
[in]passNUL-terminated passphrase, or null for an open network; at most k_ra8_c6link_pass_max octets.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe record is filled and ready for ra8_c6link_wifi_join.
k_ra8_err_null_ptrcfg or ssid was null.
k_ra8_err_invalid_sizessid was empty or either string was longer than its field.
Precondition
ssid is NUL-terminated within k_ra8_c6link_ssid_max + 1 octets.
pass, when non-null, is NUL-terminated within k_ra8_c6link_pass_max + 1 octets.
Postcondition
On success both lengths are consistent with the copied strings.
On failure cfg is left cleared rather than half-filled.
Note
Pure formatting; touches no hardware and is safe from any thread.
Warning
The passphrase is held in the caller's record in plain text for as long as the record lives. Clear it once the join has been issued.
Example:
(void)ra8_c6link_sta_cfg_set(&sta, "ra8-bench", "correct horse battery");
See also
ra8_c6link_wifi_join
Since
0.1.0

Definition at line 100 of file ra8_c6link_wifi_sta.c.

References internal_c6link_sta_len(), k_ra8_c6link_pass_max, k_ra8_c6link_ssid_max, k_ra8_err_invalid_size, k_ra8_err_null_ptr, k_ra8_ok, ra8_c6link_sta_cfg::pass, ra8_c6link_sta_cfg::pass_len, ra8_secure_memzero(), ra8_c6link_sta_cfg::ssid, and ra8_c6link_sta_cfg::ssid_len.

Referenced by c6_join_phase_associate(), internal_c6_cam_associate(), internal_c6link_op_join(), and internal_open_and_join().

◆ ra8_c6link_wifi_ap_info()

ra8_err_t ra8_c6link_wifi_ap_info ( ra8_c6link_t * link,
ra8_c6link_ap_info_t * out )
nodiscard

Read what the co-processor knows about the associated AP.

Parameters
[in,out]linkOpen handle; must be non-null.
[out]outRecord to fill; must be non-null.
Returns
ra8_err_t Error code.
Return values
k_ra8_okout describes the current association.
k_ra8_err_null_ptrlink or out was null.
k_ra8_err_not_initializedlink is not open.
k_ra8_err_busyA request is already outstanding on link.
k_ra8_err_timeoutThe co-processor did not answer.
k_ra8_err_hw_timeoutThe co-processor never armed HANDSHAKE, so no transaction was clocked.
k_ra8_err_protocol_errorThe answer reported a failure – which is what an unassociated station returns – or carried no record.
k_ra8_err_spi_errorThe transport refused a transfer.
Precondition
The station is associated; asking otherwise is answered with a failure code by the co-processor.
The transport is up.
Postcondition
On success out is fully written.
On failure out is cleared rather than left half-written.
Note
Not thread-safe; it pumps.
Example:
(void)ra8_c6link_wifi_ap_info(&link, &ap);
See also
ra8_c6link_ap_info
Since
0.1.0

Definition at line 405 of file ra8_c6link_wifi_sta.c.

References internal_c6link_take_ap(), k_ra8_err_not_initialized, k_ra8_err_null_ptr, priv_c6link_rpc_call(), and ra8_c6link_is_open().

Referenced by internal_c6link_op_get_ap().

◆ ra8_c6link_wifi_join()

ra8_err_t ra8_c6link_wifi_join ( ra8_c6link_t * link,
const ra8_c6link_sta_cfg_t * cfg )
nodiscard

Ask the station to associate with the configured network.

Issues Req_WifiSetConfig for the station interface and then Req_WifiConnect. Returns as soon as the co-processor has accepted the request; the association result arrives later as an event.

Parameters
[in,out]linkOpen handle; must be non-null.
[in]cfgStation configuration; must be non-null and consistent, which ra8_c6link_sta_cfg_set guarantees.
Returns
ra8_err_t Error code.
Return values
k_ra8_okThe co-processor accepted the association request.
k_ra8_err_null_ptrlink or cfg was null.
k_ra8_err_not_initializedlink is not open.
k_ra8_err_invalid_sizeA length in cfg exceeds its field.
k_ra8_err_busyA request is already outstanding on link.
k_ra8_err_timeoutThe co-processor did not answer a step.
k_ra8_err_hw_timeoutThe co-processor never armed HANDSHAKE, so no transaction was clocked.
k_ra8_err_protocol_errorA step reported a failure code.
k_ra8_err_spi_errorThe transport refused a transfer.
Precondition
ra8_c6link_wifi_start has succeeded on link.
cfg holds credentials for a network that is in range.
Postcondition
On success an association attempt is in progress.
On failure the handle's last fault names the step that failed.
Note
Not thread-safe; it pumps.
Warning
Success here means "asked", not "joined". Wait for k_ra8_c6link_event_sta_connected.
Example:
(void)ra8_c6link_wifi_join(&link, &sta);
See also
ra8_c6link_wifi_leave
Since
0.1.0

Definition at line 270 of file ra8_c6link_wifi_sta.c.

References internal_c6link_sta_set_config(), k_ra8_c6link_pass_max, k_ra8_c6link_ssid_max, k_ra8_err_invalid_size, k_ra8_err_not_initialized, k_ra8_err_null_ptr, k_ra8_ok, ra8_c6link_sta_cfg::pass_len, priv_c6link_bare_req(), ra8_c6link_is_open(), and ra8_c6link_sta_cfg::ssid_len.

Referenced by c6_join_phase_associate(), internal_c6_cam_associate(), internal_c6link_op_join(), and internal_open_and_join().

◆ ra8_c6link_wifi_mac()

ra8_err_t ra8_c6link_wifi_mac ( ra8_c6link_t * link,
ra8_c6link_mac_t * out )
nodiscard

Read the station interface's MAC address.

The address an IP stack above must use as its own. It is a property of the co-processor's efuses, so it is stable across resets and is available as soon as the radio has been initialised.

Parameters
[in,out]linkOpen handle; must be non-null.
[out]outAddress to fill; must be non-null.
Returns
ra8_err_t Error code.
Return values
k_ra8_okout holds the station address.
k_ra8_err_null_ptrlink or out was null.
k_ra8_err_not_initializedlink is not open.
k_ra8_err_busyA request is already outstanding on link.
k_ra8_err_timeoutThe co-processor did not answer.
k_ra8_err_hw_timeoutThe co-processor never armed HANDSHAKE, so no transaction was clocked.
k_ra8_err_protocol_errorThe answer reported a failure, or carried an address of the wrong length.
k_ra8_err_spi_errorThe transport refused a transfer.
Precondition
ra8_c6link_wifi_start has succeeded on link.
The caller treats an all-zero result as a protocol failure, which this call reports rather than returns.
Postcondition
On success out holds k_ra8_c6link_mac_bytes octets.
On failure out is cleared rather than left half-written.
Note
Not thread-safe; it pumps.
Example:
(void)ra8_c6link_wifi_mac(&link, &mac);
See also
ra8_c6link_mac_t
Since
0.1.0

Definition at line 324 of file ra8_c6link_wifi_sta.c.

References internal_c6link_take_mac(), k_ra8_c6link_iface_sta, k_ra8_err_not_initialized, k_ra8_err_null_ptr, priv_c6link_rpc_call(), and ra8_c6link_is_open().

Referenced by c6_join_phase_associate(), c6_wifi_phase_station(), internal_c6_cam_associate(), and internal_c6link_op_get_mac().