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

Layer 4 UDP datagram service - the only place lwIP UDP is touched. More...

#include "network_drivers/transport/udp.h"
#include <string.h>
#include "diffserv.h"
#include "lwip/igmp.h"
#include "lwip/pbuf.h"
#include "lwip/priv/tcpip_priv.h"
#include "lwip/udp.h"

Go to the source code of this file.

Classes

struct  UdpListener
 
struct  UdpCtx
 
struct  pc_udp_peer
 
struct  pc_udp_call
 

Enumerations

enum class  pc_udp_op : uint8_t {
  UDP_OP_LISTEN , UDP_OP_LISTEN_MCAST , UDP_OP_LEAVE_MCAST , UDP_OP_SEND ,
  UDP_OP_SEND_OUT
}
 

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 UDP datagram service - the only place lwIP UDP is touched.

Definition in file udp.cpp.

Enumeration Type Documentation

◆ pc_udp_op

enum class pc_udp_op : uint8_t
strong
Enumerator
UDP_OP_LISTEN 
UDP_OP_LISTEN_MCAST 
UDP_OP_LEAVE_MCAST 
UDP_OP_SEND 
UDP_OP_SEND_OUT 

Definition at line 99 of file udp.cpp.

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.