ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_wifi.c
Go to the documentation of this file.
1
22
23#include "ra8_wifi.h"
24
25#include <stdint.h>
26
27#include "ra8_attributes.h"
28#include "ra8_check.h"
29#include "ra8_err.h"
30#include "ra8_wifi_backend.h"
31
33#define RA8_WIFI_TAG "WIFI"
34
59{
60 RA8_CHECK_NULL_PTR(b, RA8_WIFI_TAG, "backend");
61 RA8_CHECK_NULL_PTR(b->open, RA8_WIFI_TAG, "backend.open");
62 RA8_CHECK_NULL_PTR(b->close, RA8_WIFI_TAG, "backend.close");
63 RA8_CHECK_NULL_PTR(b->radio_up, RA8_WIFI_TAG, "backend.radio_up");
64 RA8_CHECK_NULL_PTR(b->radio_down, RA8_WIFI_TAG, "backend.radio_down");
65 return k_ra8_ok;
66}
67
91{
92 RA8_CHECK_NULL_PTR(b, RA8_WIFI_TAG, "backend");
93 RA8_CHECK_NULL_PTR(b->join, RA8_WIFI_TAG, "backend.join");
94 RA8_CHECK_NULL_PTR(b->leave, RA8_WIFI_TAG, "backend.leave");
95 return k_ra8_ok;
96}
97
122{
123 RA8_CHECK_NULL_PTR(b, RA8_WIFI_TAG, "backend");
124 RA8_CHECK_NULL_PTR(b->service, RA8_WIFI_TAG, "backend.service");
125 RA8_CHECK_NULL_PTR(b->get_mac, RA8_WIFI_TAG, "backend.get_mac");
126 RA8_CHECK_NULL_PTR(b->get_ap, RA8_WIFI_TAG, "backend.get_ap");
127 RA8_CHECK_NULL_PTR(b->idle, RA8_WIFI_TAG, "backend.idle");
128 return k_ra8_ok;
129}
130
154{
155 const ra8_err_t lifecycle = internal_check_backend_lifecycle(b);
156 if (lifecycle != k_ra8_ok) {
157 return lifecycle;
158 }
159 const ra8_err_t session = internal_check_backend_session(b);
160 if (session != k_ra8_ok) {
161 return session;
162 }
164}
165
167{
168 RA8_CHECK_NULL_PTR(wifi, RA8_WIFI_TAG, "wifi");
169 RA8_CHECK_NULL_PTR(cfg, RA8_WIFI_TAG, "cfg");
170 RA8_CHECK_NULL_PTR(cfg->ip_bind, RA8_WIFI_TAG, "cfg.ip_bind");
171
172 const ra8_err_t table = internal_check_backend(cfg->backend);
173 if (table != k_ra8_ok) {
174 return table;
175 }
176 if (wifi->open) {
178 }
179
180 const ra8_err_t opened = cfg->backend->open(cfg->backend_ctx);
181 if (opened != k_ra8_ok) {
182 return opened;
183 }
184
185 *wifi = (ra8_wifi_t){};
186 wifi->backend = cfg->backend;
187 wifi->backend_ctx = cfg->backend_ctx;
188 wifi->ip_bind = cfg->ip_bind;
189 wifi->ip_ctx = cfg->ip_ctx;
191 wifi->open = true;
192 return k_ra8_ok;
193}
194
196{
197 RA8_CHECK_NULL_PTR(wifi, RA8_WIFI_TAG, "wifi");
198 if (!wifi->open) {
200 }
201
202 const ra8_err_t closed = wifi->backend->close(wifi->backend_ctx);
203 wifi->open = false;
204 wifi->radio_on = false;
206 return closed;
207}
208
233{
234 RA8_CHECK_NULL_PTR(wifi, RA8_WIFI_TAG, "wifi");
235 if (wifi->radio_on) {
236 return k_ra8_ok;
237 }
238 const ra8_err_t up = wifi->backend->radio_up(wifi->backend_ctx);
239 if (up != k_ra8_ok) {
240 return up;
241 }
242 wifi->radio_on = true;
243 return k_ra8_ok;
244}
245
283{
284 RA8_CHECK_NULL_PTR(wifi, RA8_WIFI_TAG, "wifi");
285 ra8_err_t last_fault = k_ra8_ok;
286 bool answered = false;
287
288 for (uint16_t i = 0U; i < (uint16_t)k_ra8_wifi_join_polls; i++) {
290 const ra8_err_t serviced = wifi->backend->service(wifi->backend_ctx, &link);
291 if (serviced != k_ra8_ok) {
292 last_fault = serviced;
293 } else {
294 answered = true;
295 if (link == k_ra8_wifi_link_up) {
296 wifi->state = k_ra8_wifi_state_associated;
297 return k_ra8_ok;
298 }
299 }
300 wifi->backend->idle(wifi->backend_ctx, (uint16_t)k_ra8_wifi_poll_gap_ms);
301 }
302
303 /* Nothing answered across the whole budget: the radio is absent, not slow, so
304 * name the fault it kept reporting rather than calling it a plain timeout. */
305 if (!answered) {
306 return last_fault;
307 }
308 return k_ra8_err_timeout;
309}
310
311ra8_err_t ra8_wifi_connect(ra8_wifi_t* wifi, const char* ssid, const char* psk)
312{
313 RA8_CHECK_NULL_PTR(wifi, RA8_WIFI_TAG, "wifi");
314 RA8_CHECK_NULL_PTR(ssid, RA8_WIFI_TAG, "ssid");
315 if (!wifi->open) {
317 }
318
319 const ra8_err_t powered = internal_ensure_radio_up(wifi);
320 if (powered != k_ra8_ok) {
321 return powered;
322 }
323
324 const ra8_err_t got_mac = wifi->backend->get_mac(wifi->backend_ctx, &wifi->mac);
325 if (got_mac != k_ra8_ok) {
326 return got_mac;
327 }
328 wifi->mac_valid = true;
329
331 const ra8_err_t asked = wifi->backend->join(wifi->backend_ctx, ssid, psk);
332 if (asked != k_ra8_ok) {
333 return asked;
334 }
335 return internal_await_association(wifi);
336}
337
339{
340 RA8_CHECK_NULL_PTR(wifi, RA8_WIFI_TAG, "wifi");
341 if (!wifi->open) {
343 }
344
345 const ra8_err_t left = wifi->backend->leave(wifi->backend_ctx);
346 const ra8_err_t stopped = wifi->backend->radio_down(wifi->backend_ctx);
347 wifi->radio_on = false;
349 wifi->lease = (ra8_wifi_lease_t){};
350 return (left != k_ra8_ok) ? left : stopped;
351}
352
354{
355 RA8_CHECK_NULL_PTR(wifi, RA8_WIFI_TAG, "wifi");
356 RA8_CHECK_NULL_PTR(out, RA8_WIFI_TAG, "out");
357 *out = (ra8_wifi_lease_t){};
358 if (!wifi->open) {
360 }
363 }
364
365 ra8_wifi_lease_t lease = {};
366 const ra8_err_t bound = wifi->ip_bind(wifi->ip_ctx, &wifi->mac, &lease);
367 if (bound != k_ra8_ok) {
368 wifi->lease = (ra8_wifi_lease_t){};
369 return bound;
370 }
371 lease.bound = (lease.ip != 0U);
372 if (!lease.bound) {
373 wifi->lease = (ra8_wifi_lease_t){};
374 return k_ra8_err_timeout;
375 }
376
377 wifi->lease = lease;
379 *out = lease;
380 return k_ra8_ok;
381}
382
384{
385 RA8_CHECK_NULL_PTR(wifi, RA8_WIFI_TAG, "wifi");
386 RA8_CHECK_NULL_PTR(out, RA8_WIFI_TAG, "out");
387 if (!wifi->open) {
389 }
390 *out = wifi->lease;
391 return k_ra8_ok;
392}
393
395{
396 RA8_CHECK_NULL_PTR(wifi, RA8_WIFI_TAG, "wifi");
397 RA8_CHECK_NULL_PTR(out, RA8_WIFI_TAG, "out");
398 if (!wifi->open) {
400 }
401
402 *out = (ra8_wifi_status_t){};
403 out->state = wifi->state;
405 out->ip_bound = (wifi->state == k_ra8_wifi_state_ip_bound);
406 out->rssi = wifi->rssi;
407 out->ip = wifi->lease;
408 return k_ra8_ok;
409}
410
412{
413 RA8_CHECK_NULL_PTR(wifi, RA8_WIFI_TAG, "wifi");
414 RA8_CHECK_NULL_PTR(out, RA8_WIFI_TAG, "out");
416 if (!wifi->open) {
418 }
419 if (wifi->state == k_ra8_wifi_state_ip_bound) {
421 }
422
424 const ra8_err_t serviced = wifi->backend->service(wifi->backend_ctx, &link);
425 if (serviced != k_ra8_ok) {
426 return serviced;
427 }
428
430 *out = link;
431 return k_ra8_ok;
432}
433
435{
436 RA8_CHECK_NULL_PTR(wifi, RA8_WIFI_TAG, "wifi");
437 RA8_CHECK_NULL_PTR(out, RA8_WIFI_TAG, "out");
438 if (!wifi->open) {
440 }
441
442 const ra8_err_t got = wifi->backend->get_mac(wifi->backend_ctx, out);
443 if (got != k_ra8_ok) {
444 /* A station's own address does not change while it is associated, so a
445 * cached one is the right answer when the radio cannot be re-asked. It
446 * routinely cannot: once the AP starts forwarding broadcast traffic this
447 * query competes with it for the link, and handing the caller
448 * 00:00:00:00:00:00 instead is how the bench first printed a null MAC into
449 * a run that had in fact associated. */
450 if (wifi->mac_valid) {
451 *out = wifi->mac;
452 return k_ra8_ok;
453 }
454 *out = (ra8_wifi_mac_t){};
455 return got;
456 }
457 wifi->mac = *out;
458 wifi->mac_valid = true;
459 return k_ra8_ok;
460}
461
463{
464 RA8_CHECK_NULL_PTR(wifi, RA8_WIFI_TAG, "wifi");
465 RA8_CHECK_NULL_PTR(out, RA8_WIFI_TAG, "out");
466 if (!wifi->open) {
468 }
471 }
472
473 const ra8_err_t got = wifi->backend->get_ap(wifi->backend_ctx, out);
474 if (got != k_ra8_ok) {
475 *out = (ra8_wifi_ap_t){};
476 return got;
477 }
478 wifi->rssi = out->rssi;
479 return k_ra8_ok;
480}
Annotation-attribute framework macros for ra8-firmware.
#define RA8_BOUNDED_LOOP(symbol)
NASA Power-of-10 Rule 2: every loop in a FUNCTION has a constant bound.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Definition ra8_check.h:243
Error Code Definitions for ra8-firmware.
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
Definition ra8_err.h:161
@ 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_timeout
Operation exceeded its time budget.
Definition ra8_err.h:188
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
ra8_err_t ra8_wifi_deinit(ra8_wifi_t *wifi)
Release a handle and power its radio down.
Definition ra8_wifi.c:195
ra8_err_t ra8_wifi_init(ra8_wifi_t *wifi, const ra8_wifi_cfg_t *cfg)
Bring the radio and its link up and make a handle usable.
Definition ra8_wifi.c:166
ra8_err_t ra8_wifi_get_mac(ra8_wifi_t *wifi, ra8_wifi_mac_t *out)
Read the station's own MAC address.
Definition ra8_wifi.c:434
static ra8_err_t internal_check_backend_query(const ra8_wifi_backend_t *b)
Validate the backend rows that report state or pace a wait.
Definition ra8_wifi.c:121
static ra8_err_t internal_check_backend_session(const ra8_wifi_backend_t *b)
Validate the backend rows that join and leave a network.
Definition ra8_wifi.c:90
static ra8_err_t internal_await_association(ra8_wifi_t *wifi)
Pump the backend until the station associates or the budget runs out.
Definition ra8_wifi.c:282
ra8_err_t ra8_wifi_get_ap(ra8_wifi_t *wifi, ra8_wifi_ap_t *out)
Read what the backend knows about the associated AP.
Definition ra8_wifi.c:462
ra8_err_t ra8_wifi_get_ip(const ra8_wifi_t *wifi, ra8_wifi_lease_t *out)
Read the cached DHCP lease without touching the wire.
Definition ra8_wifi.c:383
ra8_err_t ra8_wifi_wait_ip(ra8_wifi_t *wifi, ra8_wifi_lease_t *out)
Obtain an IP address for the associated station, blocking until bound.
Definition ra8_wifi.c:353
static ra8_err_t internal_check_backend(const ra8_wifi_backend_t *b)
Validate every row of a candidate backend table.
Definition ra8_wifi.c:153
ra8_err_t ra8_wifi_status(const ra8_wifi_t *wifi, ra8_wifi_status_t *out)
Read a handle's cached status without touching the wire.
Definition ra8_wifi.c:394
static ra8_err_t internal_check_backend_lifecycle(const ra8_wifi_backend_t *b)
Validate the backend rows that change the radio's state.
Definition ra8_wifi.c:58
ra8_err_t ra8_wifi_disconnect(ra8_wifi_t *wifi)
Disassociate the station and power the radio down.
Definition ra8_wifi.c:338
#define RA8_WIFI_TAG
Component tag for this facade's log lines.
Definition ra8_wifi.c:33
ra8_err_t ra8_wifi_connect(ra8_wifi_t *wifi, const char *ssid, const char *psk)
Join a network by SSID and passphrase, blocking until associated.
Definition ra8_wifi.c:311
static ra8_err_t internal_ensure_radio_up(ra8_wifi_t *wifi)
Raise the radio if it is not already up.
Definition ra8_wifi.c:232
ra8_err_t ra8_wifi_poll(ra8_wifi_t *wifi, ra8_wifi_link_t *out)
Service the link once and refresh the cached association state.
Definition ra8_wifi.c:411
A small, uniform Wi-Fi facade: init, connect, get an IP, disconnect.
@ k_ra8_wifi_state_ip_bound
A DHCP lease is held.
Definition ra8_wifi.h:157
@ k_ra8_wifi_state_associating
A join has been asked for.
Definition ra8_wifi.h:155
@ k_ra8_wifi_state_associated
Station is joined; no IP yet.
Definition ra8_wifi.h:156
@ k_ra8_wifi_state_down
Not associated; radio may be off.
Definition ra8_wifi.h:154
struct ra8_wifi_backend ra8_wifi_backend_t
One radio's implementation of the operations this facade dispatches.
Definition ra8_wifi.h:342
struct ra8_wifi_ap ra8_wifi_ap_t
struct ra8_wifi_mac ra8_wifi_mac_t
struct ra8_wifi_lease ra8_wifi_lease_t
struct ra8_wifi ra8_wifi_t
ra8_wifi_link_t
The instantaneous association state a backend reports.
Definition ra8_wifi.h:182
@ k_ra8_wifi_link_up
Station is associated with an AP.
Definition ra8_wifi.h:184
@ k_ra8_wifi_link_down
Station is not associated.
Definition ra8_wifi.h:183
struct ra8_wifi_status ra8_wifi_status_t
struct ra8_wifi_cfg ra8_wifi_cfg_t
@ k_ra8_wifi_join_polls
Times ra8_wifi_connect services the link while waiting for the join to complete.
Definition ra8_wifi.h:122
@ k_ra8_wifi_poll_gap_ms
Milliseconds the facade idles between two association attempts.
Definition ra8_wifi.h:124
The radio-operation seam ra8_wifi dispatches through.
int8_t rssi
Signal level in dBm.
Definition ra8_wifi.h:268
ra8_err_t(* open)(void *ctx)
Bring the radio's link up and prove it answers.
ra8_err_t(* radio_up)(void *ctx)
Start the radio in station mode.
ra8_err_t(* get_mac)(void *ctx, ra8_wifi_mac_t *out)
Read the station's own MAC address.
ra8_err_t(* get_ap)(void *ctx, ra8_wifi_ap_t *out)
Read what the radio knows about the associated AP.
ra8_err_t(* join)(void *ctx, const char *ssid, const char *psk)
Ask the station to associate with a network.
ra8_err_t(* close)(void *ctx)
Release the link the backend opened.
ra8_err_t(* service)(void *ctx, ra8_wifi_link_t *out_link)
Service the link once and report the association state.
ra8_err_t(* radio_down)(void *ctx)
Stop the radio and release its resources.
ra8_err_t(* leave)(void *ctx)
Disassociate the station from its network.
const ra8_wifi_backend_t * backend
Radio operations; every row set.
Definition ra8_wifi.h:370
void * backend_ctx
Opaque state handed to the backend.
Definition ra8_wifi.h:371
ra8_wifi_ip_bind_fn ip_bind
IP-stack hook for ra8_wifi_wait_ip.
Definition ra8_wifi.h:372
void * ip_ctx
Opaque context handed to ip_bind.
Definition ra8_wifi.h:373
bool bound
A usable lease is held.
Definition ra8_wifi.h:238
uint32_t ip
Leased station address, or zero if unbound.
Definition ra8_wifi.h:234
ra8_wifi_state_t state
Lifecycle position.
Definition ra8_wifi.h:296
bool associated
The station is joined.
Definition ra8_wifi.h:297
bool ip_bound
A DHCP lease is held.
Definition ra8_wifi.h:298
int8_t rssi
Last known signal level in dBm, or zero.
Definition ra8_wifi.h:299
ra8_wifi_lease_t ip
The current lease, valid when ip_bound.
Definition ra8_wifi.h:300
ra8_wifi_ip_bind_fn ip_bind
Bound IP-stack hook.
Definition ra8_wifi.h:400
const ra8_wifi_backend_t * backend
Bound radio operations.
Definition ra8_wifi.h:398
void * backend_ctx
Backend's opaque state.
Definition ra8_wifi.h:399
void * ip_ctx
Context for ip_bind.
Definition ra8_wifi.h:401
ra8_wifi_mac_t mac
Cached station address.
Definition ra8_wifi.h:402
bool mac_valid
mac has been read.
Definition ra8_wifi.h:408
bool radio_on
The radio has been started.
Definition ra8_wifi.h:407
ra8_wifi_state_t state
Lifecycle position.
Definition ra8_wifi.h:404
bool open
The handle is initialised.
Definition ra8_wifi.h:406
ra8_wifi_lease_t lease
Cached DHCP lease.
Definition ra8_wifi.h:403
int8_t rssi
Last signal reading, dBm.
Definition ra8_wifi.h:405