File espos_net.h¶
File List > espos_net > include > espos_net.h
Go to the documentation of this file
/*
* SPDX-FileCopyrightText: 2026 Dirk Wahrheit
* SPDX-License-Identifier: Apache-2.0
*
* espos_net — the one place espOS answers "is the network up, and how".
*
* Every transport (espos_wifi today; Ethernet and 802.15.4 next) reports its
* link into this component with espos_net_report(). espos_net keeps one
* record per interface, picks the interface that carries the default route
* (Ethernet over WiFi station over Thread when several are up), owns the
* device's hostname (config key net.hostname, default espos-<id>) and its
* mDNS responder (espos_mdns.h), and tells everyone else about changes:
* ESPOS_EVENT_NETWORK_UP / NETWORK_DOWN on the event bus, espos_net_subscribe()
* callbacks, the "net" SSE event and GET /api/v1/net/status.
*
* SignalK, OTA and mDNS depend on this component and not on a radio, which is
* what lets a firmware leave espos_wifi out — an Ethernet gateway, an H-series
* device without WiFi — without touching them.
*
* Threading: espos_net_get_status(), espos_net_is_up() and
* espos_net_short_id() never call a driver or wait on one; a status snapshot
* must not depend on a radio answering (the hosted ESP32-P4 rule, docs/wifi.md).
* espos_net_report() is thread-safe and is called by a transport from its own
* task. Subscribe callbacks run on that reporting task — for WiFi the default
* event loop task — with no espos_net lock held: copy the status out and
* return, never block there.
*/
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Buffer sizes of espos_net_status_t, NUL included. Values are part of the ABI. */
#define ESPOS_NET_IP_MAX 16 /* dotted IPv4 */
#define ESPOS_NET_IP6_MAX 40 /* textual IPv6 */
#define ESPOS_NET_HOSTNAME_MAX 33 /* 32 characters, the DHCP/mDNS label limit */
#define ESPOS_NET_SHORT_ID_MAX 5 /* "1a2b" */
/* The interfaces a transport can report. Values are ABI: append before _MAX,
* never renumber. espos_net_sm_t is sized by ESPOS_NET_IF_MAX, so appending
* one is an ESPOS_ABI_VERSION bump. */
typedef enum {
ESPOS_NET_IF_NONE = 0, /* no default route */
ESPOS_NET_IF_WIFI_STA = 1, /* espos_wifi's station */
ESPOS_NET_IF_ETH = 2, /* wired Ethernet (espos_eth) */
ESPOS_NET_IF_THREAD = 3, /* 802.15.4 / Thread (future transport) */
ESPOS_NET_IF_MAX = 4,
} espos_net_if_t;
/* One snapshot of the network as the rest of espOS sees it: the interface that
* carries the default route and the device's identity on it. */
typedef struct {
bool up; /* a default route exists */
espos_net_if_t iface; /* the interface carrying it; NONE when down */
char ip[ESPOS_NET_IP_MAX]; /* "" when down */
char netmask[ESPOS_NET_IP_MAX]; /* "" when down */
char gateway[ESPOS_NET_IP_MAX]; /* "" when down or none */
char ip6_ll[ESPOS_NET_IP6_MAX]; /* link-local IPv6 of that interface; "" when none or unknown */
uint8_t mac[6]; /* the base MAC (eFuse); all zero on the host */
char hostname[ESPOS_NET_HOSTNAME_MAX]; /* what the device answers to as <hostname>.local */
int8_t rssi; /* dBm of the WiFi station carrying the route; 0 on any other interface */
uint32_t up_count; /* how often the default route came up (or moved) since boot */
uint32_t up_since_ms; /* milliseconds the current default route has been up; 0 when down */
} espos_net_status_t;
esp_err_t espos_net_start(void);
esp_err_t espos_net_get_status(espos_net_status_t *out);
bool espos_net_is_up(void);
typedef void (*espos_net_cb_t)(const espos_net_status_t *st, void *arg);
esp_err_t espos_net_subscribe(espos_net_cb_t cb, void *arg);
esp_err_t espos_net_unsubscribe(espos_net_cb_t cb, void *arg);
const char *espos_net_short_id(void);
uint32_t espos_net_backoff_ms(uint32_t round, uint32_t cap_ms, uint32_t rnd);
esp_err_t espos_net_status_json(char **out_json);
const char *espos_net_if_str(espos_net_if_t iface);
/* ------------------------------------------------ for transports to call */
esp_err_t espos_net_register_if(espos_net_if_t iface, void *esp_netif);
void espos_net_report(espos_net_if_t iface, bool up, const char *ip, const char *netmask, const char *gateway, int8_t rssi);
#ifdef __cplusplus
}
#endif