ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
physical.h
Go to the documentation of this file.
1// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file physical.h
6 * @brief Layer 1 (Physical) - link bring-up, the interface registry, and live egress reporting.
7 *
8 * The IETF host model's lowest layer is the link layer (RFC 1122 sec 1.1.3): it names no physical
9 * layer, and the media themselves are IEEE (802.3 wired, 802.11 wireless). What the IETF defines
10 * for this layer is what the calls below carry - IP over Ethernet (RFC 894), IP over IEEE 802
11 * networks (RFC 1042), the outbound route an interface is chosen by (RFC 1122 sec 3.3.1), IPv6
12 * stateless address autoconfiguration (RFC 4862) and the address forms it produces (RFC 4291
13 * sec 2.5.4 global unicast, sec 2.5.6 link-local), dual IP layer operation (RFC 4213 sec 2), and
14 * the 6-octet hardware address ARP resolves to (RFC 826 sec "Packet format", ar$hln = 6).
15 *
16 * Bring-up runs in the backend the PROTOCORE_VENDOR_* selector compiled
17 * (test/core_setup/physical/<vendor>/), reached through the seam declared below. Failover between
18 * interfaces belongs to the stack, which reselects the default route when a link drops, so this
19 * layer adds no manager and no tick: it reads the live default route each time it is asked which
20 * interface carries outbound traffic (RFC 1122 sec 3.3.1.2 gateway selection).
21 *
22 * @author Douglas Quigg (dstroy0)
23 * @date 2026
24 */
25
26#ifndef PROTOCORE_PHYSICAL_H
27#define PROTOCORE_PHYSICAL_H
28
29#include "config/platform/platform.h" // PROTOCORE_VENDOR_* selector (picks the L1 backend)
30#include "shared/ip/ip.h"
31
32#include "protocore_config.h" // protocore_if_kind
33
34// There is always a physical (L1) backend to drive. The bring-up (radio, Ethernet PHY, the stack's
35// interface access) lives beside its owner - test/core_setup/physical/<vendor>/ for silicon,
36// test/core_setup/hal/host/physical/ everywhere else, which is a link that can actually be up and
37// answers from it. Every build compiles one of the two, so a link is driven for real on a host as
38// well as on a part.
39#ifndef PROTOCORE_PHYSICAL_HAS_BACKEND
40#define PROTOCORE_PHYSICAL_HAS_BACKEND 1
41#endif
42
43// A backend may be written in C++ (it drives the platform's own WiFi and Ethernet objects), so the
44// seam below carries C linkage and links against either language unchanged.
46
47// ---------------------------------------------------------------------------
48// The L1 backend seam. Not the caller API: every name here is defined once per build, by the
49// backend the PROTOCORE_VENDOR_* selector compiled or by the software backend beside it. A caller
50// reaches layer 1 through @ref Physical and never through a seam name.
51// ---------------------------------------------------------------------------
52
53/**
54 * @brief Start an 802.11 station join to an access point.
55 *
56 * Returns immediately; association and address configuration are asynchronous. Poll wifi_ready().
57 *
58 * @param ssid network SSID, null-terminated (IEEE 802.11-2020 9.4.2.2, at most 32 octets).
59 * @param password WPA2 passphrase, null-terminated (IEEE 802.11i, not an IETF protocol).
60 */
61proto_bool init_wifi_physical(const char *ssid, const char *password);
62
63/** @brief True when the station link is associated and holds an IPv4 address. */
65
66/**
67 * @brief Start the radio in station mode without associating.
68 *
69 * Runs the PHY with no IP link, for peer-to-peer radio messaging and promiscuous capture. Pins the
70 * radio to @p channel (1..14) when non-zero; 0 leaves the channel to a capture layer that sets its
71 * own (services/radio/promisc).
72 */
74
75/**
76 * @brief Start a softAP, with AP and station coexistence so a station link runs alongside it.
77 *
78 * @param ssid softAP SSID, null-terminated.
79 * @param password softAP passphrase, null-terminated; >= 8 characters for WPA2, "" for an open AP.
80 */
81proto_bool init_wifi_ap_physical(const char *ssid, const char *password);
82
83/**
84 * @brief Start a wired Ethernet link (PROTOCORE_ENABLE_ETHERNET).
85 *
86 * The PHY pins, type and clock come from the platform's own Ethernet build flags. Returns
87 * immediately; poll eth_ready(). A wired route classifies as PROTOCORE_IF_ETH (RFC 894 framing).
88 */
90
91/** @brief True when the wired link is up and holds an IPv4 address. */
93
94/**
95 * @brief Enable dual IP layer operation on the WiFi interface (RFC 4213 sec 2, PROTOCORE_ENABLE_IPV6).
96 *
97 * The interface autoconfigures a link-local address (RFC 4291 sec 2.5.6) and, when a router
98 * advertises a prefix, a global unicast address (RFC 4862). Returns immediately; poll
99 * protocore_ipv6_ready().
100 */
102
103/**
104 * @brief The interface's global unicast IPv6 address (RFC 4291 sec 2.5.4).
105 * @param[out] out receives the address with family PROTOCORE_IP_V6 when true is returned.
106 */
108
109/** @brief True once a global unicast IPv6 address is configured. */
111
112/**
113 * @brief Which interface carries outbound traffic (RFC 1122 sec 3.3.1.2).
114 *
115 * Reads the live default route, so it reflects the current state after any failover the stack
116 * performed. PROTOCORE_IF_ETH / PROTOCORE_IF_WIFI_STA / PROTOCORE_IF_WIFI_AP, or PROTOCORE_IF_ANY
117 * when no route is up.
118 */
120
121/** @brief IPv4 of the current default-route interface, network byte order (RFC 791 app. B), 0 if none. */
123
124/** @brief softAP IPv4, network byte order, or 0 when the softAP is down. */
125uint32_t protocore_net_ap_ip(void);
126
127/** @brief Station link RSSI in dBm, or 0 when not associated. */
129
130/**
131 * @brief Copy the 802.11 station hardware address into @p out (6 octets, RFC 826 ar$hln = 6).
132 *
133 * The station address, valid once the WiFi driver is up; a wired-only part reads back zeros. For
134 * the address in use on the wire right now whatever the link type, use protocore_net_egress_mac().
135 */
137
138/**
139 * @brief Copy the hardware address of the current default-route interface into @p out (6 octets).
140 *
141 * Link-neutral: the Ethernet PHY's address on a wired route, the station address on a wireless one,
142 * whichever interface protocore_net_egress_ip() reports. False when no route is up.
143 */
145
146/**
147 * @brief Copy the associated SSID into @p out, null-terminated.
148 * @return SSID length in octets, or 0 when not associated or @p cap is 0.
149 */
150size_t protocore_net_ssid(char *out, size_t cap);
151
152/** @brief Station channel (1..14), or 0 when not associated. */
154
155/**
156 * @brief Map a live default-route IPv4 to the interface it belongs to.
157 *
158 * Defined in physical.c, so it answers the same on every backend: an egress IP equal to the station
159 * or softAP IP is that WiFi interface, any other live IP is a wired route, 0 is no route. A backend
160 * calls it from its own egress readout; a caller reaches it as PhysicalNs::classify_ip.
161 *
162 * @param egress_ip default-route IPv4, network byte order, 0 if none.
163 * @param sta_ip station IPv4, network byte order, 0 if not associated.
164 * @param ap_ip softAP IPv4, network byte order, 0 if the softAP is down.
165 */
166protocore_if_kind protocore_net_classify_ip(uint32_t egress_ip, uint32_t sta_ip, uint32_t ap_ip);
167
168/* --------------------------------------------------------------------------------------------
169 * Radio control (L1 capability contract)
170 *
171 * Power save and monitor mode are properties of the radio, so they belong to the layer that owns
172 * the radio. These names carry no platform vocabulary; the flavoring happens at the edge, in
173 * test/core_setup/physical/<vendor>/. Each one reports failure when the selected backend has no radio
174 * (PROTOCORE_PHYSICAL_HAS_BACKEND == 0), so callers build and run headless on any target. They are
175 * reached through PhysicalNs::radio, which is radio_power.h's handle.
176 * ------------------------------------------------------------------------------------------ */
177
178/** @brief Radio power-save mode, in the library's own vocabulary (IEEE 802.11 power management). */
180{
181 PROTOCORE_PHY_PS_NONE = 0, ///< Radio always on: lowest latency, highest average draw.
182 PROTOCORE_PHY_PS_MIN_MODEM = 1, ///< Wake on every DTIM beacon.
183 PROTOCORE_PHY_PS_MAX_MODEM = 2, ///< Wake on a longer listen interval: lowest draw, highest latency.
185
186/**
187 * @brief One received frame, delivered in neutral terms.
188 *
189 * Not the platform's received-packet struct, so no platform type reaches a service. The FCS is
190 * already stripped.
191 *
192 * @param frame frame octets, valid only for the duration of the call.
193 * @param len frame length in octets, FCS excluded.
194 * @param rssi received signal strength, dBm.
195 * @param channel channel the frame arrived on.
196 */
197typedef void (*protocore_phy_frame_fn)(const uint8_t *frame, uint16_t len, int8_t rssi, uint8_t channel);
198
199/** @brief Apply a power-save mode. False when there is no radio backend. */
201
202/** @brief The active power-save mode (PROTOCORE_PHY_PS_NONE when unsupported). */
204
205/**
206 * @brief Cap transmit power.
207 * @param dbm maximum transmit power in whole dBm; the backend converts to its own unit.
208 */
210
211/** @brief Enter monitor mode on @p channel, delivering frames to @p cb. */
213
214/** @brief Retune monitor mode to @p channel. */
216
217/** @brief Leave monitor mode. */
219
220#if PROTOCORE_PHYSICAL_HAS_BACKEND && !PROTOCORE_VENDOR_ESP
221/**
222 * @brief Hand one captured frame up to the armed monitor sink, the way the radio does.
223 *
224 * The mock backend's receive path: with no silicon to put the part in monitor mode, this is where
225 * a frame enters, so a caller above is driven by a real delivery rather than by its own input.
226 *
227 * @return false when monitor mode is not running or the frame is empty.
228 */
229proto_bool protocore_phy_mock_deliver(const uint8_t *frame, uint16_t len, int8_t rssi, uint8_t channel);
230#endif
231
232// ---------------------------------------------------------------------------
233// The interfaces this device has. An interface is an id, a kind, and the callback that puts octets
234// on the wire - all three physical facts, which is why the registry is here and not in the
235// forwarding plane that merely chooses between them. A device can carry several, of mixed kind: two
236// Ethernet ports, a station and a softAP, a bus bridged to a socket.
237// ---------------------------------------------------------------------------
238
239// protocore_if_kind is protocore_config.h's: one vocabulary for the kind and the filter.
240
241/**
242 * @brief Put @p len octets on interface @p if_id.
243 * @return true if the interface accepted them; false drops.
244 */
245typedef proto_bool (*protocore_if_send_fn)(uint8_t if_id, const uint8_t *data, uint16_t len, void *ctx);
246
247/** @brief No interface. Reported by PhysicalNs::iface_at for an empty row. */
248#define PROTOCORE_IF_NONE (-1)
249
250/** @brief What an 802.11 bring-up takes: the station join, the softAP, and the radio-only start. */
251typedef struct
252{
253 const char *ssid; ///< SSID a join or a softAP names (IEEE 802.11-2020 9.4.2.2, <= 32 octets)
254 const char *password; ///< WPA2 passphrase; "" opens the softAP
255 uint8_t channel; ///< channel a radio-only start pins (1..14); 0 leaves it to a capture layer
257
258/** @brief Where a readout copies to. */
259typedef struct
260{
261 uint8_t *mac; ///< receives a 6-octet hardware address (RFC 826 ar$hln = 6)
262 char *text; ///< receives the SSID, null-terminated
263 size_t cap; ///< how much room text has
264 protocore_ip *ip6; ///< receives the global unicast IPv6 address (RFC 4291 sec 2.5.4)
266
267/** @brief What the egress classifier judges: the live route and the two WiFi addresses. */
268typedef struct
269{
270 uint32_t egress_ip; ///< default-route IPv4, network byte order (RFC 791 app. B); 0 if no route
271 uint32_t sta_ip; ///< station IPv4, network byte order; 0 if not associated
272 uint32_t ap_ip; ///< softAP IPv4, network byte order; 0 if the softAP is down
274
275/** @brief What names an interface in the registry, and the frame a send puts on it. */
276typedef struct
277{
278 protocore_if_send_fn send; ///< how octets reach the interface being registered
279 void *ctx; ///< what that callback is handed back
280 const uint8_t *data; ///< the frame a send puts on the wire
281 uint16_t len; ///< its length in octets
282 protocore_if_kind kind; ///< what the interface being registered is
283 uint8_t id; ///< the interface a call acts on
284 uint8_t i; ///< the registry row a lookup names
286
287/**
288 * @brief Layer 1: link bring-up, what the live link reports, and the interfaces this device has.
289 *
290 * A caller sets the members a call takes, invokes it through ::Physical, and reads the outcome off
291 * the same handle. Bring-up and readout run in the compiled backend; the registry rows and the
292 * egress classifier are this module's own, held behind @ref internal.
293 *
294 * @var PhysicalNs::wifi what an 802.11 bring-up takes
295 * @var PhysicalNs::read where a readout copies to
296 * @var PhysicalNs::route what the egress classifier judges (RFC 1122 sec 3.3.1)
297 * @var PhysicalNs::iface what names an interface, and the frame a send puts on it
298 * @var PhysicalNs::ok a call's true/false outcome
299 * @var PhysicalNs::if_kind the interface kind a call reports
300 * @var PhysicalNs::u32 an IPv4 a call reports, network byte order
301 * @var PhysicalNs::n the SSID length a readout wrote
302 * @var PhysicalNs::u8 a channel or a registry count
303 * @var PhysicalNs::i8 the RSSI a readout reports, dBm
304 * @var PhysicalNs::i16 the interface id a registry row holds, or PROTOCORE_IF_NONE
305 * @var PhysicalNs::wifi_init start the station join to the named AP
306 * @var PhysicalNs::wifi_ready whether the station link is associated with an address
307 * @var PhysicalNs::wifi_radio_init start the radio with no IP link, pinned to a channel
308 * @var PhysicalNs::wifi_ap_init start the softAP alongside the station
309 * @var PhysicalNs::wifi_ssid the associated SSID
310 * @var PhysicalNs::wifi_channel the station channel
311 * @var PhysicalNs::wifi_rssi the station RSSI
312 * @var PhysicalNs::wifi_ap_ip the softAP IPv4
313 * @var PhysicalNs::wifi_mac the station hardware address (RFC 826 ar$hln = 6)
314 * @var PhysicalNs::eth_init start the wired link (RFC 894)
315 * @var PhysicalNs::eth_ready whether the wired link is up with an address
316 * @var PhysicalNs::ip6_init enable dual IP layer operation (RFC 4213 sec 2)
317 * @var PhysicalNs::ip6_global the global unicast IPv6 address (RFC 4291 sec 2.5.4)
318 * @var PhysicalNs::ip6_ready whether a global unicast address is configured (RFC 4862)
319 * @var PhysicalNs::egress which interface carries outbound traffic (RFC 1122 sec 3.3.1.2)
320 * @var PhysicalNs::egress_ip that interface's IPv4
321 * @var PhysicalNs::egress_mac that interface's hardware address
322 * @var PhysicalNs::classify_ip map a route's IPv4 to the interface it belongs to
323 * @var PhysicalNs::iface_add register an interface and how to send on it
324 * @var PhysicalNs::iface_reset forget every interface
325 * @var PhysicalNs::iface_present whether the named id is registered
326 * @var PhysicalNs::iface_kind what the named id is
327 * @var PhysicalNs::iface_at the id held in a registry row
328 * @var PhysicalNs::iface_count registered interfaces
329 * @var PhysicalNs::iface_send put the held frame on the named id
330 * @var PhysicalNs::radio the radio handle, radio_power.h's
331 */
346
347/** @brief The operands and the outcome. */
349
350/** @brief The entries. */
351typedef struct
352{
353 void (*const wifi_init)(uint8_t *work);
354 void (*const wifi_ready)(uint8_t *work);
355 void (*const wifi_radio_init)(uint8_t *work);
356 void (*const wifi_ap_init)(uint8_t *work);
357 void (*const wifi_ssid)(uint8_t *work);
358 void (*const wifi_channel)(uint8_t *work);
359 void (*const wifi_rssi)(uint8_t *work);
360 void (*const wifi_ap_ip)(uint8_t *work);
361 void (*const wifi_mac)(uint8_t *work);
362 void (*const eth_init)(uint8_t *work);
363 void (*const eth_ready)(uint8_t *work);
364 void (*const ip6_init)(uint8_t *work);
365 void (*const ip6_global)(uint8_t *work);
366 void (*const ip6_ready)(uint8_t *work);
367 void (*const egress)(uint8_t *work);
368 void (*const egress_ip)(uint8_t *work);
369 void (*const egress_mac)(uint8_t *work);
370 void (*const classify_ip)(uint8_t *work);
371 void (*const iface_add)(uint8_t *work);
372 void (*const iface_reset)(uint8_t *work);
373 void (*const iface_present)(uint8_t *work);
374 void (*const iface_kind)(uint8_t *work);
375 void (*const iface_at)(uint8_t *work);
376 void (*const iface_count)(uint8_t *work);
377 void (*const iface_send)(uint8_t *work);
378} PhysicalNs;
379
380// What the table binds, defined once in the .c and taking one parameter each: everything
381// else an entry needs is an operand in PhysicalV or a region of the borrow at a fixed offset.
390void protocore_physical_wifi_mac(uint8_t *work);
391void protocore_physical_eth_init(uint8_t *work);
393void protocore_physical_ip6_init(uint8_t *work);
396void protocore_physical_egress(uint8_t *work);
404void protocore_physical_iface_at(uint8_t *work);
407
408// `static const`, initialised HERE rather than `extern` against a definition in the .c: a
409// const object whose initializer every translation unit can see is a COMPILE-TIME FACT, so
410// `Physical.wifi_init(work)` resolves to a named function and becomes a DIRECT call. An extern table
411// leaves the call indirect and the symbol live at every level, -O2 -flto included.
412static const PhysicalNs Physical __attribute__((unused)) = {
414 .wifi_ready = protocore_physical_wifi_ready,
415 .wifi_radio_init = protocore_physical_wifi_radio_init,
416 .wifi_ap_init = protocore_physical_wifi_ap_init,
417 .wifi_ssid = protocore_physical_wifi_ssid,
418 .wifi_channel = protocore_physical_wifi_channel,
419 .wifi_rssi = protocore_physical_wifi_rssi,
420 .wifi_ap_ip = protocore_physical_wifi_ap_ip,
421 .wifi_mac = protocore_physical_wifi_mac,
422 .eth_init = protocore_physical_eth_init,
423 .eth_ready = protocore_physical_eth_ready,
424 .ip6_init = protocore_physical_ip6_init,
425 .ip6_global = protocore_physical_ip6_global,
426 .ip6_ready = protocore_physical_ip6_ready,
428 .egress_ip = protocore_physical_egress_ip,
429 .egress_mac = protocore_physical_egress_mac,
430 .classify_ip = protocore_physical_classify_ip,
431 .iface_add = protocore_physical_iface_add,
432 .iface_reset = protocore_physical_iface_reset,
433 .iface_present = protocore_physical_iface_present,
434 .iface_kind = protocore_physical_iface_kind,
435 .iface_at = protocore_physical_iface_at,
436 .iface_count = protocore_physical_iface_count,
437 .iface_send = protocore_physical_iface_send,
438};
439
440/**
441 * @brief The PROTOCORE_PHYSICAL_BORROW bytes this module's state lives in.
442 *
443 * Stated beside the namespace rather than on it: an entry takes a borrow, and this is where
444 * that borrow comes from. Taken once from the end of the pool, which no mark and no release
445 * walks, so the state lasts the life of the program.
446 *
447 * @return the span.
448 */
450
452
453#endif
enum PROTO_ENUM_PACKED protocore_if_kind
What an interface is, and the filter that selects one.
PROTO_ENUM_PACKED
Application protocol spoken on a listener port or connection slot.
Layer 3 (Network) - a family-tagged IP address (IPv4 or IPv6) with RFC-faithful text parsing,...
protocore_if_kind protocore_net_classify_ip(uint32_t egress_ip, uint32_t sta_ip, uint32_t ap_ip)
Map a live default-route IPv4 to the interface it belongs to.
uint8_t protocore_net_channel(void)
Station channel (1..14), or 0 when not associated.
proto_bool init_wifi_radio_physical(uint8_t channel)
Start the radio in station mode without associating.
void protocore_physical_classify_ip(uint8_t *work)
proto_bool net_global_ipv6(protocore_ip *out)
The interface's global unicast IPv6 address (RFC 4291 sec 2.5.4).
proto_bool(* protocore_if_send_fn)(uint8_t if_id, const uint8_t *data, uint16_t len, void *ctx)
Put len octets on interface if_id.
Definition physical.h:245
void protocore_physical_iface_kind(uint8_t *work)
void protocore_physical_wifi_ssid(uint8_t *work)
int8_t protocore_net_rssi(void)
Station link RSSI in dBm, or 0 when not associated.
PhysicalVars PhysicalV
The operands and the outcome.
void protocore_physical_iface_reset(uint8_t *work)
proto_bool init_eth_physical(void)
Start a wired Ethernet link (PROTOCORE_ENABLE_ETHERNET).
proto_bool eth_ready(void)
True when the wired link is up and holds an IPv4 address.
void protocore_physical_ip6_init(uint8_t *work)
void protocore_physical_wifi_init(uint8_t *work)
size_t protocore_net_ssid(char *out, size_t cap)
Copy the associated SSID into out, null-terminated.
void protocore_physical_wifi_ready(uint8_t *work)
proto_bool init_ipv6_physical(void)
Enable dual IP layer operation on the WiFi interface (RFC 4213 sec 2, PROTOCORE_ENABLE_IPV6).
void protocore_physical_wifi_ap_ip(uint8_t *work)
void protocore_physical_wifi_channel(uint8_t *work)
uint8_t * protocore_physical_span(void)
The PROTOCORE_PHYSICAL_BORROW bytes this module's state lives in.
uint32_t protocore_net_egress_ip(void)
IPv4 of the current default-route interface, network byte order (RFC 791 app. B), 0 if none.
void protocore_physical_iface_add(uint8_t *work)
void protocore_physical_iface_count(uint8_t *work)
proto_bool protocore_net_egress_mac(uint8_t out[6])
Copy the hardware address of the current default-route interface into out (6 octets).
proto_bool protocore_net_mac(uint8_t out[6])
Copy the 802.11 station hardware address into out (6 octets, RFC 826 ar$hln = 6).
proto_bool protocore_phy_tx_power_set(int8_t dbm)
Cap transmit power.
proto_bool protocore_phy_monitor_begin(uint8_t channel, protocore_phy_frame_fn cb)
Enter monitor mode on channel, delivering frames to cb.
PROTOCORE_BEGIN_DECLS proto_bool init_wifi_physical(const char *ssid, const char *password)
Start an 802.11 station join to an access point.
protocore_if_kind protocore_net_egress(void)
Which interface carries outbound traffic (RFC 1122 sec 3.3.1.2).
void protocore_phy_monitor_set_channel(uint8_t channel)
Retune monitor mode to channel.
proto_bool wifi_ready(void)
True when the station link is associated and holds an IPv4 address.
uint32_t protocore_net_ap_ip(void)
softAP IPv4, network byte order, or 0 when the softAP is down.
void protocore_physical_wifi_rssi(uint8_t *work)
@ PROTOCORE_PHY_PS_NONE
Radio always on: lowest latency, highest average draw.
Definition physical.h:181
@ PROTOCORE_PHY_PS_MAX_MODEM
Wake on a longer listen interval: lowest draw, highest latency.
Definition physical.h:183
@ PROTOCORE_PHY_PS_MIN_MODEM
Wake on every DTIM beacon.
Definition physical.h:182
void protocore_physical_egress_mac(uint8_t *work)
void protocore_physical_wifi_radio_init(uint8_t *work)
void protocore_physical_eth_init(uint8_t *work)
protocore_phy_ps protocore_phy_ps_get(void)
The active power-save mode (PROTOCORE_PHY_PS_NONE when unsupported).
enum PROTO_ENUM_PACKED protocore_phy_ps
Radio power-save mode, in the library's own vocabulary (IEEE 802.11 power management).
void protocore_physical_ip6_global(uint8_t *work)
void protocore_physical_eth_ready(uint8_t *work)
void protocore_physical_iface_at(uint8_t *work)
void protocore_physical_egress(uint8_t *work)
void protocore_physical_wifi_mac(uint8_t *work)
void protocore_physical_iface_send(uint8_t *work)
void protocore_physical_egress_ip(uint8_t *work)
void(* protocore_phy_frame_fn)(const uint8_t *frame, uint16_t len, int8_t rssi, uint8_t channel)
One received frame, delivered in neutral terms.
Definition physical.h:197
void protocore_physical_iface_present(uint8_t *work)
void protocore_phy_monitor_end(void)
Leave monitor mode.
void protocore_physical_wifi_ap_init(uint8_t *work)
proto_bool protocore_ipv6_ready(void)
True once a global unicast IPv6 address is configured.
proto_bool protocore_phy_ps_set(protocore_phy_ps mode)
Apply a power-save mode. False when there is no radio backend.
void protocore_physical_ip6_ready(uint8_t *work)
proto_bool init_wifi_ap_physical(const char *ssid, const char *password)
Start a softAP, with AP and station coexistence so a station link runs alongside it.
The platform contract: what the library asks of a target, in the library's own words.
What names an interface in the registry, and the frame a send puts on it.
Definition physical.h:277
uint8_t id
the interface a call acts on
Definition physical.h:283
const uint8_t * data
the frame a send puts on the wire
Definition physical.h:280
void * ctx
what that callback is handed back
Definition physical.h:279
uint16_t len
its length in octets
Definition physical.h:281
uint8_t i
the registry row a lookup names
Definition physical.h:284
protocore_if_send_fn send
how octets reach the interface being registered
Definition physical.h:278
protocore_if_kind kind
what the interface being registered is
Definition physical.h:282
The entries.
Definition physical.h:352
void(*const wifi_init)(uint8_t *work)
Definition physical.h:353
Where a readout copies to.
Definition physical.h:260
uint8_t * mac
receives a 6-octet hardware address (RFC 826 ar$hln = 6)
Definition physical.h:261
size_t cap
how much room text has
Definition physical.h:263
protocore_ip * ip6
receives the global unicast IPv6 address (RFC 4291 sec 2.5.4)
Definition physical.h:264
char * text
receives the SSID, null-terminated
Definition physical.h:262
What the egress classifier judges: the live route and the two WiFi addresses.
Definition physical.h:269
uint32_t egress_ip
default-route IPv4, network byte order (RFC 791 app. B); 0 if no route
Definition physical.h:270
uint32_t ap_ip
softAP IPv4, network byte order; 0 if the softAP is down
Definition physical.h:272
uint32_t sta_ip
station IPv4, network byte order; 0 if not associated
Definition physical.h:271
int16_t i16
Definition physical.h:344
PhysicalWifiArgs wifi
Definition physical.h:334
int8_t i8
Definition physical.h:343
proto_bool ok
Definition physical.h:338
protocore_if_kind if_kind
Definition physical.h:339
uint8_t u8
Definition physical.h:342
PhysicalIfaceArgs iface
Definition physical.h:337
PhysicalReadArgs read
Definition physical.h:335
PhysicalRouteArgs route
Definition physical.h:336
uint32_t u32
Definition physical.h:340
What an 802.11 bring-up takes: the station join, the softAP, and the radio-only start.
Definition physical.h:252
uint8_t channel
channel a radio-only start pins (1..14); 0 leaves it to a capture layer
Definition physical.h:255
const char * ssid
SSID a join or a softAP names (IEEE 802.11-2020 9.4.2.2, <= 32 octets)
Definition physical.h:253
const char * password
WPA2 passphrase; "" opens the softAP.
Definition physical.h:254
A v4 or v6 address in network (big-endian) byte order.
Definition ip.h:56
#define PROTOCORE_BEGIN_DECLS
Give a header's declarations C linkage, so their symbol names carry no parameter types.
Definition types.h:96
_Bool proto_bool
The truth value.
Definition types.h:64
#define PROTOCORE_END_DECLS
Definition types.h:97