ProtoCore v0.0.1
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
udp.h File Reference

Layer 4 (Transport) - connectionless UDP datagram service. More...

#include "protocore_config.h"
#include <stddef.h>
#include <stdint.h>

Go to the source code of this file.

Typedefs

typedef void(* pc_udp_handler) (const uint8_t *data, size_t len, const struct pc_udp_peer *peer, void *ctx)
 Datagram handler invoked for each received UDP packet.
 

Functions

bool pc_udp_listen (uint16_t port, pc_udp_handler handler, void *ctx)
 Bind a UDP port and route incoming datagrams to handler.
 
bool pc_udp_listen_multicast (const char *group_ip, uint16_t port, pc_udp_handler handler, void *ctx)
 Bind a UDP port, join an IPv4 multicast group, and route group datagrams to handler.
 
bool pc_udp_leave_multicast (uint16_t port)
 Leave the multicast group joined on port and release its listener slot.
 
bool pc_udp_send (const struct pc_udp_peer *peer, const uint8_t *data, size_t len)
 Send a datagram back to the peer captured during the handler call.
 
bool pc_udp_sendto (const char *dst_ip, uint16_t dst_port, const uint8_t *data, size_t len)
 Send a UDP datagram to an arbitrary destination (outbound client).
 
bool pc_udp_peer_addr (const struct pc_udp_peer *peer, char *ip_out, size_t ip_cap, uint16_t *port_out)
 Copy a received peer's source IPv4 address (dotted-quad) and port out.
 
bool pc_udp_listener_sendto (uint16_t listen_port, const char *dst_ip, uint16_t dst_port, const uint8_t *data, size_t len)
 Send a datagram from the listener bound on listen_port to an address.
 

Detailed Description

Layer 4 (Transport) - connectionless UDP datagram service.

The transport layer's UDP counterpart to the TCP connection pool (see tcp.h / listener.h). It owns all lwIP UDP plumbing (udp_pcb, pbuf); higher layers (application services such as SNMP and the captive portal's DNS responder) bind a port and exchange datagrams through this API without ever touching lwIP. This keeps the OSI layering honest: transport concerns stay in the transport layer.

Datagram delivery is callback-driven from the lwIP thread (no per-loop polling). The handler receives a contiguous payload and an opaque peer token valid only for the duration of the call; reply synchronously with pc_udp_send(). On non-Arduino (host) builds the functions are no-op stubs so the services that use them stay host-compilable.

Author
Douglas Quigg (dstroy0)
Date
2026

Definition in file udp.h.

Typedef Documentation

◆ pc_udp_handler

typedef void(* pc_udp_handler) (const uint8_t *data, size_t len, const struct pc_udp_peer *peer, void *ctx)

Datagram handler invoked for each received UDP packet.

Parameters
datacontiguous datagram payload (transport-owned scratch).
lenpayload length in bytes.
peerreply token (valid only during this call).
ctxthe opaque context passed to pc_udp_listen().

Definition at line 49 of file udp.h.

Function Documentation

◆ pc_udp_listen()

bool pc_udp_listen ( uint16_t  port,
pc_udp_handler  handler,
void *  ctx 
)

Bind a UDP port and route incoming datagrams to handler.

Parameters
portUDP port to bind (e.g. 161 for SNMP, 53 for captive DNS).
handlercallback for each datagram.
ctxopaque pointer forwarded to handler.
Returns
true on success; false if no listener slot is free, the bind fails, or UDP is unavailable (host builds). ESP32 only; a host build returns false.

Definition at line 226 of file udp.cpp.

References pc_udp_call::base, UdpListener::ctx, UdpListener::handler, UdpCtx::listeners, pc_udp_call::op, PC_MAX_UDP_LISTENERS, UdpListener::pcb, pc_udp_call::port, pc_udp_call::result, pc_udp_call::slot, UDP_OP_LISTEN, and UdpListener::used.

◆ pc_udp_listen_multicast()

bool pc_udp_listen_multicast ( const char *  group_ip,
uint16_t  port,
pc_udp_handler  handler,
void *  ctx 
)

Bind a UDP port, join an IPv4 multicast group, and route group datagrams to handler.

The multicast counterpart to pc_udp_listen(): as well as binding the port it joins group_ip via IGMP on every interface, so the stack accepts datagrams addressed to the group rather than to this host. That is what lets a service observe a shared protocol - counting mDNS announcements on 224.0.0.251:5353, watching SSDP on 239.255.255.250:1900 - instead of only its own traffic.

The socket is bound with SO_REUSEADDR, because a well-known multicast port is normally already bound by whoever implements that protocol (the ESP-IDF mdns component holds 5353). Without it the second bind fails and the observer never sees a packet.

Observation only: joining a group does not make this device a responder for it. Reply with pc_udp_send() only if the protocol expects it.

Parameters
group_ipIPv4 multicast group, dotted-quad (224.0.0.0/4).
portUDP port to bind (e.g. 5353 for mDNS).
handlercallback for each datagram received on the group.
ctxopaque pointer forwarded to handler.
Returns
true if the port bound and the group was joined; false if the pool is full, group_ip is not a multicast address, IGMP is unavailable, or on a host build.

Definition at line 255 of file udp.cpp.

References pc_udp_call::addr, pc_udp_call::base, UdpListener::ctx, UdpListener::handler, UdpCtx::listeners, UdpListener::mcast, pc_udp_call::op, PC_MAX_UDP_LISTENERS, UdpListener::pcb, pc_udp_call::port, pc_udp_call::result, pc_udp_call::slot, UDP_OP_LISTEN_MCAST, and UdpListener::used.

◆ pc_udp_leave_multicast()

bool pc_udp_leave_multicast ( uint16_t  port)

Leave the multicast group joined on port and release its listener slot.

Returns
true if a matching multicast listener was found and torn down.

Definition at line 309 of file udp.cpp.

References pc_udp_call::base, UdpListener::ctx, UdpListener::handler, UdpCtx::listeners, UdpListener::mcast, pc_udp_call::op, PC_MAX_UDP_LISTENERS, UdpListener::pcb, pc_udp_call::result, pc_udp_call::slot, UDP_OP_LEAVE_MCAST, and UdpListener::used.

◆ pc_udp_send()

bool pc_udp_send ( const struct pc_udp_peer peer,
const uint8_t *  data,
size_t  len 
)

Send a datagram back to the peer captured during the handler call.

Parameters
peerthe token handed to the pc_udp_handler.
datapayload bytes.
lenpayload length.
Returns
true if the datagram was queued for transmission.

Definition at line 336 of file udp.cpp.

References pc_udp_peer::addr, pc_udp_call::addr, pc_udp_call::base, pc_udp_call::data, UdpCtx::in_tcpip_thread, pc_udp_call::len, pc_udp_call::op, pc_udp_peer::pcb, pc_udp_call::pcb, pc_udp_peer::port, pc_udp_call::port, pc_udp_call::result, and UDP_OP_SEND.

◆ pc_udp_sendto()

bool pc_udp_sendto ( const char *  dst_ip,
uint16_t  dst_port,
const uint8_t *  data,
size_t  len 
)

Send a UDP datagram to an arbitrary destination (outbound client).

Unlike pc_udp_send() - which replies to the peer of a received datagram - this sends to a host given as a dotted-quad IPv4 string and port, using a single shared outbound PCB. Fire-and-forget; for clients such as the syslog sender. ESP32 only; a host build returns false.

Parameters
dst_ipdestination IPv4 address (e.g. "192.168.1.10").
dst_portdestination UDP port.
datapayload bytes.
lenpayload length.
Returns
true if the datagram was queued; false on a bad address, allocation failure, or a host build.

Definition at line 358 of file udp.cpp.

References pc_udp_call::addr, pc_udp_call::base, pc_udp_call::data, UdpCtx::in_tcpip_thread, pc_udp_call::len, pc_udp_call::op, UdpCtx::out, pc_udp_call::port, pc_udp_call::result, and UDP_OP_SEND_OUT.

◆ pc_udp_peer_addr()

bool pc_udp_peer_addr ( const struct pc_udp_peer peer,
char *  ip_out,
size_t  ip_cap,
uint16_t *  port_out 
)

Copy a received peer's source IPv4 address (dotted-quad) and port out.

The pc_udp_peer token is valid only inside the handler; a service that wants to message the peer later (e.g. CoAP Observe notifications) captures its address here and sends with pc_udp_listener_sendto().

Returns
false on a host build or a too-small buffer.

Definition at line 393 of file udp.cpp.

References pc_udp_peer::addr, and pc_udp_peer::port.

◆ pc_udp_listener_sendto()

bool pc_udp_listener_sendto ( uint16_t  listen_port,
const char *  dst_ip,
uint16_t  dst_port,
const uint8_t *  data,
size_t  len 
)

Send a datagram from the listener bound on listen_port to an address.

Unlike pc_udp_sendto() (a shared ephemeral source port), this uses the bound listener's PCB, so the datagram's source is listen_port - required when a peer matches replies by the server endpoint (CoAP Observe notifications come from :5683).

Returns
false if no listener is bound on listen_port.

Definition at line 407 of file udp.cpp.

References pc_udp_call::addr, pc_udp_call::base, pc_udp_call::data, UdpCtx::in_tcpip_thread, pc_udp_call::len, UdpCtx::listeners, pc_udp_call::op, PC_MAX_UDP_LISTENERS, UdpListener::pcb, pc_udp_call::pcb, pc_udp_call::port, pc_udp_call::result, UDP_OP_SEND, and UdpListener::used.