NetBurner 3.5.6
PDF Version
UDP

NetBurner User Datagram Protocol (UDP) Implementation. More...

Topics

 UDP Error Codes
 
 UDP Packet API
 
 UDP Socket API
 BSD-style socket functions for UDP communication.
 

Classes

class  UDPPacket
 UDP Packet Class - Complete UDP packet management. More...
 

Typedefs

typedef void udp_data_notify(OS_FIFO *pfifo, uint16_t port)
 UDP packet arrival notification callback function type.
 

Functions

bool RegisterUDPFifo (uint16_t listenPort, OS_FIFO *pFifo)
 Register FIFO to receive UDP packets on specified port.
 
bool RegisterUDPFifoVia (uint16_t listenPort, OS_FIFO *pFifo, int interface)
 Register FIFO to receive UDP packets on specified port via specific network interface.
 
uint16_t RegisterEphemeralFifo (OS_FIFO *pfifo, int ifn=-1)
 Register UDP FIFO on a random unused ephemeral port.
 
bool RegisterUDPFifoWithNotify (uint16_t listenPort, OS_FIFO *pFifo, udp_data_notify *pNotifyFunction)
 Register UDP FIFO with callback notification on packet arrival.
 
bool RegisterUDPFifoWithNotifyVia (uint16_t listenPort, OS_FIFO *pFifo, udp_data_notify *pNotifyFunction, int interface)
 Register UDP FIFO with callback notification on specific network interface.
 
void UnregisterUDPFifo (uint16_t listenPort, bool drain=false)
 Unregister UDP FIFO and stop receiving packets on specified port.
 

Detailed Description

NetBurner User Datagram Protocol (UDP) Implementation.

#include< udp.h>

Complete UDP protocol implementation providing both object-oriented C++ interface (UDPPacket class) and BSD-style socket functions for flexible network communication.

Features

When to Use UDP

UDP is ideal for applications requiring:

Not suitable for: File transfers, critical data, ordered delivery requirements (use TCP for these scenarios)

API Selection Guide

Use UDPPacket Class When:

Use BSD Socket Functions When:

Quick Start Examples

Examples

Example 1: Simple UDP Echo Server (UDPPacket)
#include <ucos.h>
#include <udp.h>
const char *AppName = "UDP Echo Server";
void UserMain(void *pd) {
init();
// Create FIFO for receiving packets
OS_FIFO udpFifo;
OSFifoInit(&udpFifo);
RegisterUDPFifo(5000, &udpFifo); // Listen on port 5000
printf("UDP Echo Server listening on port 5000\r\n");
while (1) {
UDPPacket pkt(&udpFifo, TICKS_PER_SECOND * 60);
if (pkt.Validate()) {
IPADDR srcIP = pkt.GetSourceAddress();
uint16_t srcPort = pkt.GetSourcePort();
uint16_t dataLen = pkt.GetDataSize();
printf("Received %d bytes from %s:%d\r\n",
dataLen, AsciiIP(srcIP).c_str(), srcPort);
// Echo back to sender
pkt.SetDestinationPort(srcPort);
pkt.Send(srcIP);
}
}
}
Used to hold and manipulate IPv4 and IPv6 addresses in dual stack mode.
Definition ipv6_addr.h:41
UDP Packet Class - Complete UDP packet management.
Definition udp.h:602
#define TICKS_PER_SECOND
System clock ticks per second.
Definition constants.h:49
bool RegisterUDPFifo(uint16_t listenPort, OS_FIFO *pFifo)
Register FIFO to receive UDP packets on specified port.
void StartHttp(uint16_t port, bool RunConfigMirror)
Start the HTTP web server. Further documentation in the Initialization section Initialization - Syste...
void init()
System initialization. Ideally called at the beginning of all applications, since the easiest Recover...
bool WaitForActiveNetwork(uint32_t ticks_to_wait=120 *TICKS_PER_SECOND, int interface=-1)
Wait for an active network connection on at least one interface.
Example 2: UDP Sensor Client (UDPPacket)
#include <ucos.h>
#include <udp.h>
void SendSensorData(IPADDR serverIP, uint16_t serverPort, int sensorValue) {
UDPPacket pkt;
pkt.SetSourcePort(0); // Auto-assign ephemeral port
pkt.SetDestinationPort(serverPort);
pkt.SetDSCP(46); // Mark as high-priority (VoIP class)
// Format message directly into packet buffer
uint16_t len = sprintf(pkt.GetDataBuffer(),
"SENSOR:%d,TEMP:%d",
GetDeviceID(), sensorValue);
pkt.SetDataSize(len);
pkt.Send(serverIP); // Send and auto-free buffer
}
void Send(const IPADDR &to, uint8_t ttl=0)
Send and free buffer (recommended - most efficient)
Definition udp.h:3391
void SetDestinationPort(uint16_t port)
Set destination port (standard services: 53=DNS, 80=HTTP, 123=NTP, 161=SNMP)
void SetDSCP(uint8_t dscp)
Set DSCP for QoS (0=best effort, 46=VoIP/EF, 34=video/AF41, 8=bulk/CS1)
void SetSourcePort(uint16_t port)
Set source port (0=auto-assign ephemeral port, 1024-65535=specific port)
void SetDataSize(uint16_t numBytes)
Set data size (REQUIRED after GetDataBuffer() writes)
puint8_t GetDataBuffer(bool bReAllocateIfNeeded=false)
Get data buffer pointer for reading or writing.
Example 3: UDP Server with BSD Sockets
#include <ucos.h>
#include <udp.h>
void UserMain(void *pd) {
init();
int sock = CreateRxUdpSocket(8080);
if (sock < 0) {
printf("Failed to create socket\r\n");
return;
}
uint8_t buffer[1024];
IPADDR clientIP;
uint16_t localPort, remotePort;
while (1) {
int n = recvfrom(sock, buffer, sizeof(buffer),
&clientIP, &localPort, &remotePort);
if (n > 0) {
buffer[n] = '\0'; // Null-terminate for printing
printf("Received: %s from %s:%d\r\n",
buffer, AsciiIP(clientIP).c_str(), remotePort);
// Echo back
sendto(sock, buffer, n, clientIP, remotePort);
}
}
}
int recvfrom(int sock, puint8_t buffer, int len, IPADDR *pAddr, uint16_t *pLocal_port, uint16_t *pRemote_port)
Receive UDP packet from socket with sender information.
Definition udp.h:5960
int sendto(int sock, puint8_t what_to_send, int len_to_send, const IPADDR &to_addr, uint16_t remote_port)
Send UDP packet through socket to specified destination.
Definition udp.h:5876
int CreateRxUdpSocket(uint16_t listening_port)
Create receive-only UDP socket bound to specified port.
Example 4: Multi-Interface UDP Routing
// Send packet via specific network interface
pkt.SetSourcePort(3000);
pkt.AddData("Hello from interface 1");
// Send via interface 1 (e.g., second Ethernet port)
pkt.SendViaInterfaceNum(destIP, 1);
void SendViaInterfaceNum(const IPADDR &to, int interface, uint8_t ttl=0)
Send via specific interface and free buffer.
Definition udp.h:3800
void AddData(puint8_t pData, uint16_t len)
Add binary data (auto-updates size - no SetDataSize() needed)
Example 5: Broadcast UDP Discovery
void SendDiscoveryBroadcast() {
UDPPacket pkt;
pkt.SetSourcePort(5555);
pkt.SetDestinationPort(5555);
pkt.AddData("DISCOVER:NetBurner");
// Broadcast to local subnet
IPADDR broadcastAddr = AsciiToIp("255.255.255.255");
pkt.Send(broadcastAddr);
}

Memory Management

UDPPacket Automatic Cleanup

The UDPPacket class uses RAII (Resource Acquisition Is Initialization):

Buffer Lifecycle Example

void SendToMultipleHosts() {
UDPPacket pkt;
pkt.SetSourcePort(1000);
pkt.SetDestinationPort(2000);
pkt.AddData("Broadcast message");
// Send copies to multiple destinations
pkt.SendAndKeep(host1IP); // Sends copy, keeps buffer
pkt.SendAndKeep(host2IP); // Sends copy, keeps buffer
pkt.Send(host3IP); // Sends and frees buffer
// pkt destructor runs here, but buffer already freed by Send()
}
void SendAndKeep(const IPADDR &to, uint8_t ttl=0)
Send copy, keep original (for sending to multiple destinations)
Definition udp.h:3195

Port Number Guidelines

Common UDP Ports:

Quality of Service (QoS)

Use SetDSCP() to prioritize traffic in QoS-enabled networks:

DSCP Value | Traffic Class | Use Case

UDPPacket voipPacket;
voipPacket.SetDSCP(46); // Mark as VoIP for low latency

Performance Considerations

Buffer Size Limits

Optimization Tips

  1. Use appropriate data insertion method:
    • GetDataBuffer() + SetDataSize(): Best for sprintf/binary writes
    • AddData(): Best for incremental assembly
  2. Minimize packet sends:
    • Batch data when possible
    • Use SendAndKeep() only when necessary
  3. FIFO sizing:
    • Size FIFO based on expected burst traffic
    • Monitor FIFO with GetFifoMessageCount()
  4. Interface binding:
    • Bind sockets to specific interfaces in multi-homed systems
    • Reduces routing overhead

Error Handling

UDPPacket Validation

UDPPacket pkt(&fifo, timeout);
if (!pkt.Validate()) {
// Could be timeout, checksum error, or invalid packet
printf("Packet validation failed\r\n");
return;
}
// Safe to access packet data
puint8_t data = pkt.GetDataBuffer();
BOOL Validate(void)
Validate received packet (checks checksum and data presence)

Socket Error Codes

int sock = CreateRxUdpSocket(port);
if (sock < 0) {
switch (sock) {
printf("Socket does not exist\r\n");
break;
printf("Socket not open for writing\r\n");
break;
printf("Socket not open for reading\r\n");
break;
}
}
#define UDP_ERR_NOTOPEN_TO_READ
Socket not open for read.
Definition udp.h:4764
#define UDP_ERR_NOSUCH_SOCKET
Socket does not exist.
Definition udp.h:4762
#define UDP_ERR_NOTOPEN_TO_WRITE
Socket not open for write.
Definition udp.h:4763

Thread Safety

Advanced Features

IPv6 Dual-Stack

#ifdef IPV6
// Code automatically handles both IPv4 and IPv6
IPADDR destIP = AsciiToIp("2001:db8::1"); // IPv6
// or
IPADDR destIP = AsciiToIp("192.168.1.100"); // IPv4-mapped
pkt.Send(destIP); // Works for both
#endif

Fragment Handling

// Send large packet (>MTU) with automatic fragmentation
uint8_t largeData[8000];
// ... fill largeData ...
destIP,
5000, // source port (0 = auto)
6000, // dest port
largeData,
sizeof(largeData)
);
if (result != sizeof(largeData)) {
printf("Fragmented send failed\r\n");
}
int SendFragmentedUdpPacket(const IPADDR &to, uint16_t source_port, uint16_t dest_port, puint8_t data, int length)
Send large UDP packet (>MTU) with IP fragmentation.
Definition udp.h:6018

MAC Address Access

UDPPacket pkt(&fifo, timeout);
if (pkt.Validate()) {
MACADR srcMAC = pkt.GetMacSource();
printf("From MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n",
srcMAC.bytes[0], srcMAC.bytes[1], srcMAC.bytes[2],
srcMAC.bytes[3], srcMAC.bytes[4], srcMAC.bytes[5]);
}
Used to store and manipulate MAC addresses.
Definition nettypes.h:69
MACADR GetMacSource()
Get sender's MAC address (link-layer identification)

Debugging Tips

  1. Use EnableSystemDiagnostics(): Monitor system resources
  2. Check FIFO overflow: Increase FIFO size if packets dropped
  3. Validate packets: Always call Validate() after receiving
  4. Monitor port conflicts: Ensure unique port assignments
  5. Network tools: Use Wireshark to capture actual packets

Common Pitfalls

[NO] Forgetting to set data size

sprintf(pkt.GetDataBuffer(), "Hello");
pkt.Send(ip); // BUG: Size not set!

[YES] Correct approach

uint16_t len = sprintf(pkt.GetDataBuffer(), "Hello");
pkt.SetDataSize(len); // REQUIRED!
pkt.Send(ip);

[NO] Using packet after Send()

pkt.AddData("Hello");
pkt.Send(ip);
pkt.Send(ip2); // BUG: Buffer freed by first Send()!

[YES] Use SendAndKeep() for multiple sends

pkt.AddData("Hello");
pkt.SendAndKeep(ip);
pkt.Send(ip2); // OK: Buffer kept until last Send()

[NO] Not validating received packets

UDPPacket pkt(&fifo, timeout);
puint8_t data = pkt.GetDataBuffer(); // BUG: Might be null!

[YES] Always validate

UDPPacket pkt(&fifo, timeout);
if (pkt.Validate()) {
puint8_t data = pkt.GetDataBuffer(); // Safe
}

Typedef Documentation

◆ udp_data_notify

typedef void udp_data_notify(OS_FIFO *pfifo, uint16_t port)

#include <udp.h>

UDP packet arrival notification callback function type.

Defines the function signature for callbacks that are invoked when a UDP packet arrives on a registered port. The callback is executed in interrupt context, allowing immediate notification of packet arrival without polling.

Use this callback type when registering a UDP FIFO with notification functions like RegisterUDPFifoWithNotify() or RegisterUDPFifoWithNotifyVia().

Parameters
pfifoPointer to the OS_FIFO where the packet will be queued. This is the same FIFO that was registered with the port.
portThe UDP port number on which the packet was received. Useful when the same callback handles multiple ports.
Note
This callback is invoked from interrupt context - keep processing minimal and fast
Do not perform blocking operations, lengthy calculations, or printf statements
The callback is invoked before the packet is queued to the FIFO
You can use OSFifoPost() or other RTOS primitives to signal tasks
Warning
Never call blocking functions or perform long operations in this callback
Do not call UnregisterUDPFifo() from within this callback
Avoid dynamic memory allocation in interrupt context

Expand for Example Usage

Examples

Example implementation:

// Simple notification - just count packets
void MyUdpNotify(OS_FIFO *pfifo, uint16_t port) {
static volatile uint32_t packetCount = 0;
packetCount++; // Fast operation only
}

Example with task notification:

OS_SEM udpSemaphore;
// Callback signals a semaphore to wake processing task
void UdpArrivalNotify(OS_FIFO *pfifo, uint16_t port) {
OSSemPost(&udpSemaphore); // Wake up processing task
}
// In task context
void ProcessingTask(void *pdata) {
while (1) {
OSSemPend(&udpSemaphore, 0); // Wait for packet arrival
// Now safe to do full packet processing
UDPPacket packet;
if (ReadUDPPacket(&packet, myPort, 0)) {
ProcessPacket(&packet);
ReleaseUDPPacket(packet);
}
}
}

Example with multiple ports:

// Single callback handles multiple ports
void MultiPortNotify(OS_FIFO *pfifo, uint16_t port) {
switch (port) {
case 5000:
controlPacketFlag = true;
break;
case 5001:
dataPacketFlag = true;
break;
default:
unknownPacketFlag = true;
break;
}
}


See also
RegisterUDPFifoWithNotify()
RegisterUDPFifoWithNotifyVia()

Function Documentation

◆ RegisterEphemeralFifo()

uint16_t RegisterEphemeralFifo ( OS_FIFO * pfifo,
int ifn = -1 )

#include <udp.h>

Register UDP FIFO on a random unused ephemeral port.

Automatically selects and registers an available UDP port from the ephemeral port range (typically 49152-65535). This is particularly useful for client applications that need a source port for receiving replies but don't require a specific port number.

The function ensures the selected port is not already in use and associates it with the provided FIFO for packet queuing. This is the recommended approach for client-side UDP communication where the remote server will reply to the source port.

Parameters
pfifoPointer to an OS_FIFO structure for queuing received packets. The FIFO must be initialized before calling this function. Recommended queue depth: 5-20 packets depending on traffic volume.
ifnNetwork interface number to bind to. Use -1 for default interface (recommended). Specify a specific interface (0, 1, 2, etc.) to receive only on that interface.
Returns
The assigned ephemeral port number (49152-65535) on success, or 0 on failure (e.g., no ports available, invalid FIFO, or interface doesn't exist)
Note
The assigned port remains registered until UnregisterUDPFifo() is called
Ephemeral ports are typically in the range 49152-65535 (IANA recommended)
You must call UnregisterUDPFifo() when done to free the port and resources
Warning
The FIFO must remain valid for the lifetime of the port registration
Multiple calls will allocate multiple ephemeral ports - track and unregister all of them

Expand for Example Usage

Examples

Example (client sending request and receiving reply):
OS_FIFO udpFifo;
OSFifoInit(&udpFifo);
// Get an ephemeral port for receiving replies
uint16_t myPort = RegisterEphemeralFifo(&udpFifo);
if (myPort == 0) {
printf("Failed to register ephemeral port\n");
return;
}
printf("Listening on ephemeral port %d\n", myPort);
// Send request to server (server will reply to myPort)
IPADDR server = AsciiToIp("192.168.1.100");
SendUdpPacket(server, myPort, 8000, (uint8_t*)"REQUEST", 7);
// Wait for reply
UDPPacket reply;
if (ReadUDPPacket(&reply, myPort, TICKS_PER_SECOND * 5)) {
printf("Got reply from %s\n", reply.sourceIpAddr.toString());
ReleaseUDPPacket(reply);
}
// Cleanup
UnregisterUDPFifo(myPort, true);
uint16_t RegisterEphemeralFifo(OS_FIFO *pfifo, int ifn=-1)
Register UDP FIFO on a random unused ephemeral port.
void UnregisterUDPFifo(uint16_t listenPort, bool drain=false)
Unregister UDP FIFO and stop receiving packets on specified port.

Example (multiple concurrent requests):

struct ClientConnection {
OS_FIFO fifo;
uint16_t port;
};
ClientConnection connections[5];
// Create multiple ephemeral ports for parallel requests
for (int i = 0; i < 5; i++) {
OSFifoInit(&connections[i].fifo);
connections[i].port = RegisterEphemeralFifo(&connections[i].fifo);
if (connections[i].port == 0) {
printf("Failed to register port for connection %d\n", i);
}
}
// ... use connections ...
// Cleanup all ports
for (int i = 0; i < 5; i++) {
if (connections[i].port != 0) {
UnregisterUDPFifo(connections[i].port, true);
}
}


See also
RegisterUDPFifo() to register a specific port number
UnregisterUDPFifo() to release the ephemeral port when done
ReadUDPPacket() to read packets from the FIFO

◆ RegisterUDPFifo()

bool RegisterUDPFifo ( uint16_t listenPort,
OS_FIFO * pFifo )

#include <udp.h>

Register FIFO to receive UDP packets on specified port.

Registers a UDP port for receiving packets and associates it with a FIFO queue for packet buffering. This is the standard method for setting up UDP reception on NetBurner devices. Incoming packets are automatically queued to the FIFO and can be retrieved using ReadUDPPacket().

The FIFO depth determines how many packets can be buffered before new packets are dropped. Choose a depth based on your expected traffic volume and processing speed. A depth of 5-10 is typical for low-traffic applications, while 20+ may be needed for high-traffic scenarios.

Parameters
listenPortUDP port number to register (1-65535). Common ports: 80 (HTTP), 443 (HTTPS), 161 (SNMP), etc. Must not already be registered. Port becomes unavailable to other applications.
pFifoPointer to an initialized OS_FIFO structure for queuing received packets. Must be initialized with OSFifoInit() before calling this function. The FIFO depth should match your traffic expectations (typically 5-20). The FIFO must remain valid until UnregisterUDPFifo() is called.
Returns
true if port successfully registered, false on failure (e.g., port already in use, invalid FIFO pointer, or out of resources)
Note
The port remains registered until explicitly unregistered with UnregisterUDPFifo()
Packets exceeding the FIFO depth will be silently dropped
This function registers on all active network interfaces (use RegisterUDPFifoVia for specific interface)
Well-known ports (1-1023) may require special privileges depending on the system
Warning
The FIFO must remain valid for the entire time the port is registered
Always call UnregisterUDPFifo() before destroying or deallocating the FIFO
Port numbers must be unique - attempting to register an in-use port will fail

Expand for Example Usage

Examples

Basic example:

OS_FIFO udpFifo;
OSFifoInit(&udpFifo); // Initialize with default depth
if (RegisterUDPFifo(1234, &udpFifo)) {
printf("UDP port 1234 registered successfully\n");
} else {
printf("Failed to register port 1234\n");
}

Example with custom FIFO depth:

OS_FIFO highTrafficFifo;
OSFifoInit(&highTrafficFifo, 20); // Deep queue for high traffic
if (RegisterUDPFifo(5000, &highTrafficFifo)) {
printf("High-traffic port 5000 registered with 20 packet buffer\n");
// Process packets in a loop
UDPPacket packet;
while (true) {
if (ReadUDPPacket(&packet, 5000, TICKS_PER_SECOND)) {
printf("Received %d bytes from %s:%d\n",
packet.receivedDataLen,
packet.sourceIpAddr.toString(),
packet.sourcePort);
ProcessPacket(&packet);
ReleaseUDPPacket(packet);
}
}
}

Example with proper cleanup:

OS_FIFO myFifo;
OSFifoInit(&myFifo);
if (RegisterUDPFifo(8000, &myFifo)) {
// ... do work ...
// Clean shutdown
UnregisterUDPFifo(8000, true); // Drain queued packets
printf("Port 8000 unregistered\n");
}

Example - multiple ports:

OS_FIFO controlFifo, dataFifo, statusFifo;
OSFifoInit(&controlFifo);
OSFifoInit(&dataFifo);
OSFifoInit(&statusFifo);
// Register multiple ports for different purposes
RegisterUDPFifo(5000, &controlFifo); // Control channel
RegisterUDPFifo(5001, &dataFifo); // Data channel
RegisterUDPFifo(5002, &statusFifo); // Status channel
// Each port has its own FIFO and can be read independently
UDPPacket controlPacket;
if (ReadUDPPacket(&controlPacket, 5000, 0)) {
HandleControl(&controlPacket);
ReleaseUDPPacket(controlPacket);
}

Example - error handling:

OS_FIFO myFifo;
OSFifoInit(&myFifo);
const uint16_t PORT = 9000;
if (!RegisterUDPFifo(PORT, &myFifo)) {
printf("ERROR: Failed to register port %d\n", PORT);
printf("Possible causes:\n");
printf(" - Port already in use\n");
printf(" - Invalid FIFO pointer\n");
printf(" - Out of system resources\n");
return -1;
}
printf("Port %d ready to receive packets\n", PORT);


See also
OSFifoInit() to initialize the FIFO structure
ReadUDPPacket() to read packets from the FIFO
ReleaseUDPPacket() to free packet buffers after processing
UnregisterUDPFifo() to unregister the port and free resources
RegisterUDPFifoVia() to register on a specific network interface
RegisterUDPFifoWithNotify() to add notification callback
RegisterEphemeralFifo() to auto-assign an ephemeral port

◆ RegisterUDPFifoVia()

bool RegisterUDPFifoVia ( uint16_t listenPort,
OS_FIFO * pFifo,
int interface )

#include <udp.h>

Register FIFO to receive UDP packets on specified port via specific network interface.

Similar to RegisterUDPFifo(), but allows explicit selection of which network interface to listen on. This is essential for multi-homed systems (devices with multiple network connections) where you need to receive UDP packets on a specific interface only, such as separating management traffic from data traffic, or implementing failover systems.

Use this function when your device has multiple active network interfaces (Ethernet, WiFi, cellular, etc.) and you need to control which interface receives UDP traffic on a given port. The same port number can be registered on different interfaces simultaneously.

Parameters
listenPortUDP port number to register (1-65535). Must not already be registered on the specified interface. The same port can be registered on different interfaces.
pFifoPointer to an initialized OS_FIFO structure for queuing received packets. Must be initialized with OSFifoInit() before calling. Recommended depth: 5-20 packets depending on traffic. The FIFO must remain valid until UnregisterUDPFifo() is called.
interfaceNetwork interface number (0-based index):
  • 0 = First/primary interface (typically Ethernet)
  • 1 = Second interface (WiFi, secondary Ethernet, etc.)
  • 2+ = Additional interfaces if present The interface must be active and properly configured. Use GetInterfaceCount() to determine available interfaces.
Returns
true if port successfully registered on the specified interface, false on failure (e.g., port already in use on this interface, interface doesn't exist, invalid FIFO)
Note
Only packets arriving on the specified interface will be received
The same port can be registered on multiple interfaces with different FIFOs
Interface numbers are platform and configuration specific
The interface must remain active while the port is registered
Warning
Verify the interface exists and is active before registering
The FIFO must remain valid until UnregisterUDPFifo() is called
If an interface goes down, registered ports on that interface stop receiving packets

Expand for Example Usage

Examples

Example (dual-homed device - management on eth0, data on eth1):

OS_FIFO mgmtFifo, dataFifo;
OSFifoInit(&mgmtFifo);
OSFifoInit(&dataFifo);
// Management interface (interface 0 - secure network)
if (RegisterUDPFifoVia(161, &mgmtFifo, 0)) { // SNMP on eth0
printf("Management port 161 registered on interface 0\n");
}
// Data interface (interface 1 - production network)
if (RegisterUDPFifoVia(5000, &dataFifo, 1)) {
printf("Data port 5000 registered on interface 1\n");
}
// Each interface receives independently
UDPPacket mgmtPacket;
if (ReadUDPPacket(&mgmtPacket, 161, 0)) {
printf("Management packet from secure network\n");
ReleaseUDPPacket(mgmtPacket);
}
bool RegisterUDPFifoVia(uint16_t listenPort, OS_FIFO *pFifo, int interface)
Register FIFO to receive UDP packets on specified port via specific network interface.

Example (same port on multiple interfaces):

OS_FIFO primaryFifo, backupFifo;
OSFifoInit(&primaryFifo);
OSFifoInit(&backupFifo);
// Listen on port 8000 on both interfaces
RegisterUDPFifoVia(8000, &primaryFifo, 0); // Primary Ethernet
RegisterUDPFifoVia(8000, &backupFifo, 1); // Backup WiFi
// Can distinguish which interface received packet by which FIFO
UDPPacket packet;
if (ReadUDPPacket(&packet, 8000, 0)) {
// Check which FIFO had data to know which interface
printf("Packet received on one of the interfaces\n");
ReleaseUDPPacket(packet);
}

Example (interface availability checking):

int targetInterface = 1;
// Verify interface exists before attempting registration
if (GetInterfaceCount() > targetInterface) {
if (InterfaceActive(targetInterface)) {
OS_FIFO myFifo;
OSFifoInit(&myFifo);
if (RegisterUDPFifoVia(7000, &myFifo, targetInterface)) {
printf("Port 7000 registered on interface %d\n", targetInterface);
} else {
printf("Failed to register on interface %d\n", targetInterface);
}
} else {
printf("Interface %d exists but is not active\n", targetInterface);
}
} else {
printf("Interface %d does not exist\n", targetInterface);
}

Example (failover system):

OS_FIFO primaryFifo, failoverFifo;
OSFifoInit(&primaryFifo, 10);
OSFifoInit(&failoverFifo, 10);
const uint16_t SERVICE_PORT = 9000;
const int PRIMARY_IF = 0;
const int FAILOVER_IF = 1;
// Register on both interfaces
bool primaryOk = RegisterUDPFifoVia(SERVICE_PORT, &primaryFifo, PRIMARY_IF);
bool failoverOk = RegisterUDPFifoVia(SERVICE_PORT, &failoverFifo, FAILOVER_IF);
if (primaryOk && failoverOk) {
printf("Failover system ready on port %d\n", SERVICE_PORT);
while (true) {
UDPPacket packet;
// Check primary interface first
if (ReadUDPPacket(&packet, SERVICE_PORT, 0)) {
// Determine which interface by checking both FIFOs
printf("Packet received - processing\n");
ProcessPacket(&packet);
ReleaseUDPPacket(packet);
}
OSTimeDly(TICKS_PER_SECOND / 10);
}
}

Example (WiFi vs Ethernet separation):

#define ETH_INTERFACE 0
#define WIFI_INTERFACE 1
OS_FIFO ethernetFifo, wifiFifo;
OSFifoInit(&ethernetFifo);
OSFifoInit(&wifiFifo);
// Register different services on different interfaces
RegisterUDPFifoVia(80, &ethernetFifo, ETH_INTERFACE); // HTTP on wired only
RegisterUDPFifoVia(53, &wifiFifo, WIFI_INTERFACE); // DNS on WiFi only
printf("HTTP on Ethernet, DNS on WiFi\n");


See also
RegisterUDPFifo() for registration on all interfaces (simpler, most common)
GetInterfaceCount() to determine number of available interfaces
InterfaceActive() to check if an interface is active
GetInterfaceIP() to get interface IP address
UnregisterUDPFifo() to unregister the port
RegisterUDPFifoWithNotifyVia() to add notification callback on specific interface

◆ RegisterUDPFifoWithNotify()

bool RegisterUDPFifoWithNotify ( uint16_t listenPort,
OS_FIFO * pFifo,
udp_data_notify * pNotifyFunction )

#include <udp.h>

Register UDP FIFO with callback notification on packet arrival.

Registers a UDP port for receiving packets and associates it with both a FIFO queue and a notification callback function. When a packet arrives, the callback is invoked immediately (typically from an interrupt context), allowing for prompt handling of time-sensitive data without polling.

The notification function is called before the packet is queued to the FIFO, enabling priority processing or filtering. This is useful for protocols requiring immediate response or for implementing custom packet filtering logic.

Parameters
listenPortUDP port number to register (1-65535). Must not already be registered.
pFifoPointer to an OS_FIFO structure for queuing packets. The FIFO must be initialized before calling this function. Can be NULL if you only want notification callbacks.
pNotifyFunctionPointer to callback function invoked when packet arrives. Function signature: void callback(uint16_t port, uint8_t* data, int len, IPADDR& srcAddr) Called in interrupt context - keep processing minimal and fast. Can be NULL if you only want FIFO queuing without notification.
Returns
true if port successfully registered with notification, false on failure (e.g., port already in use, invalid parameters)
Note
The notification callback is invoked from interrupt context - keep it fast and minimal
Do not perform blocking operations or lengthy processing in the callback
Both pFifo and pNotifyFunction can be provided, or just one (the other can be NULL)
Packets are queued to FIFO after the notification callback returns
Warning
The callback executes in interrupt context - avoid blocking calls, printf, or long operations
The FIFO and callback function must remain valid until UnregisterUDPFifo() is called
Do not call UnregisterUDPFifo() from within the notification callback

Expand for Example Usage

Examples

Example (immediate response protocol):

OS_FIFO pingFifo;
OSFifoInit(&pingFifo);
// Notification callback - responds immediately to ping requests
void PingNotify(uint16_t port, uint8_t* data, int len, IPADDR& srcAddr) {
if (len >= 4 && memcmp(data, "PING", 4) == 0) {
// Immediate pong response
SendUdpPacket(srcAddr, port, port, (uint8_t*)"PONG", 4);
}
}
// Register with notification
if (RegisterUDPFifoWithNotify(9000, &pingFifo, PingNotify)) {
printf("Ping responder registered on port 9000\n");
}
// Packets are also queued for later processing if needed
UDPPacket packet;
while (ReadUDPPacket(&packet, 9000, 0)) {
printf("Logged ping from %s\n", packet.sourceIpAddr.toString());
ReleaseUDPPacket(packet);
}
bool RegisterUDPFifoWithNotify(uint16_t listenPort, OS_FIFO *pFifo, udp_data_notify *pNotifyFunction)
Register UDP FIFO with callback notification on packet arrival.

Example (packet filtering and statistics):

OS_FIFO datagramFifo;
OSFifoInit(&datagramFifo);
volatile uint32_t packetCount = 0;
volatile uint32_t filteredCount = 0;
// Notification for statistics and filtering
void DatagramNotify(uint16_t port, uint8_t* data, int len, IPADDR& srcAddr) {
packetCount++;
// Filter packets - could modify data or reject certain sources
if (len < 10) {
filteredCount++;
// Packet still gets queued to FIFO
}
}
RegisterUDPFifoWithNotify(5000, &datagramFifo, DatagramNotify);
// Main loop can check statistics
printf("Received: %lu, Filtered: %lu\n", packetCount, filteredCount);

Example (notification only, no FIFO):

// Just count packets, don't queue them
volatile uint32_t statsPackets = 0;
void StatsOnlyNotify(uint16_t port, uint8_t* data, int len, IPADDR& srcAddr) {
statsPackets++;
}
// NULL FIFO - only notification callback
RegisterUDPFifoWithNotify(6000, NULL, StatsOnlyNotify);


See also
RegisterUDPFifo() for registration without notification callback
RegisterUDPFifoWithNotifyVia() to specify network interface
UnregisterUDPFifo() to unregister the port

◆ RegisterUDPFifoWithNotifyVia()

bool RegisterUDPFifoWithNotifyVia ( uint16_t listenPort,
OS_FIFO * pFifo,
udp_data_notify * pNotifyFunction,
int interface )

#include <udp.h>

Register UDP FIFO with callback notification on specific network interface.

Similar to RegisterUDPFifoWithNotify(), but allows explicit selection of which network interface to listen on. This is essential for multi-homed systems (devices with multiple network connections) where you need to receive UDP packets on a specific interface only.

Use this function when your device has multiple network interfaces (Ethernet, WiFi, etc.) and you need to isolate UDP traffic by interface. For example, listening for management traffic only on the Ethernet interface while ignoring similar packets from WiFi.

Parameters
listenPortUDP port number to register (1-65535). Must not already be registered on the specified interface.
pFifoPointer to an OS_FIFO structure for queuing packets. Must be initialized before calling. Can be NULL for notification-only.
pNotifyFunctionPointer to callback function invoked when packet arrives. Function signature: void callback(uint16_t port, uint8_t* data, int len, IPADDR& srcAddr) Called in interrupt context. Can be NULL for FIFO-only operation.
interfaceNetwork interface number (0-based):
  • 0 = First interface (typically primary Ethernet)
  • 1 = Second interface (WiFi, secondary Ethernet, etc.)
  • 2+ = Additional interfaces if present The interface must be active and configured.
Returns
true if port successfully registered on the specified interface, false on failure (e.g., port already in use on this interface, interface doesn't exist, invalid parameters)
Note
Only packets arriving on the specified interface will be received
The same port can be registered on different interfaces simultaneously
The notification callback is invoked from interrupt context - keep it minimal
Interface numbers are system-specific - check your platform documentation
Warning
The callback executes in interrupt context - avoid blocking operations
The FIFO and callback must remain valid until UnregisterUDPFifo() is called
Verify the interface exists and is active before registering

Expand for Example Usage

Examples

Example (dual-homed device - different ports per interface):

OS_FIFO ethernetFifo, wifiFifo;
OSFifoInit(&ethernetFifo);
OSFifoInit(&wifiFifo);
// Listen on port 8000 on Ethernet interface only
if (RegisterUDPFifoWithNotifyVia(8000, &ethernetFifo, NULL, 0)) {
printf("Registered on Ethernet (interface 0)\n");
}
// Listen on port 8000 on WiFi interface only (same port, different interface)
if (RegisterUDPFifoWithNotifyVia(8000, &wifiFifo, NULL, 1)) {
printf("Registered on WiFi (interface 1)\n");
}
// Now we can distinguish packets by which FIFO they arrive on
bool RegisterUDPFifoWithNotifyVia(uint16_t listenPort, OS_FIFO *pFifo, udp_data_notify *pNotifyFunction, int interface)
Register UDP FIFO with callback notification on specific network interface.

Example (management vs. data network separation):

OS_FIFO mgmtFifo, dataFifo;
OSFifoInit(&mgmtFifo);
OSFifoInit(&dataFifo);
// Management traffic on dedicated Ethernet interface
RegisterUDPFifoWithNotifyVia(161, &mgmtFifo, NULL, 0); // SNMP on eth0
// High-speed data on separate interface
RegisterUDPFifoWithNotifyVia(5000, &dataFifo, NULL, 1); // Data on eth1
// Process management packets
UDPPacket mgmtPacket;
if (ReadUDPPacket(&mgmtPacket, 161, 0)) {
printf("Management packet from secure network\n");
ReleaseUDPPacket(mgmtPacket);
}

Example (interface-specific notification):

OS_FIFO primaryFifo, backupFifo;
OSFifoInit(&primaryFifo);
OSFifoInit(&backupFifo);
void PrimaryNotify(uint16_t port, uint8_t* data, int len, IPADDR& srcAddr) {
// Log that primary interface received packet
primaryPacketCount++;
}
void BackupNotify(uint16_t port, uint8_t* data, int len, IPADDR& srcAddr) {
// Alert if backup interface is receiving traffic
backupPacketCount++;
TriggerFailoverAlert();
}
// Same port, different interfaces with different callbacks
RegisterUDPFifoWithNotifyVia(9000, &primaryFifo, PrimaryNotify, 0);
RegisterUDPFifoWithNotifyVia(9000, &backupFifo, BackupNotify, 1);

Example (checking interface availability first):

int targetInterface = 1;
// Verify interface exists and is active
if (GetInterfaceCount() > targetInterface && InterfaceActive(targetInterface)) {
OS_FIFO myFifo;
OSFifoInit(&myFifo);
if (RegisterUDPFifoWithNotifyVia(7000, &myFifo, NULL, targetInterface)) {
printf("Successfully registered on interface %d\n", targetInterface);
} else {
printf("Failed to register on interface %d\n", targetInterface);
}
} else {
printf("Interface %d not available\n", targetInterface);
}


See also
RegisterUDPFifoWithNotify() for default interface registration
RegisterUDPFifo() for basic registration without notification
GetInterfaceCount() to determine available interfaces
InterfaceActive() to check if an interface is active
UnregisterUDPFifo() to unregister the port

◆ UnregisterUDPFifo()

void UnregisterUDPFifo ( uint16_t listenPort,
bool drain = false )

#include <udp.h>

Unregister UDP FIFO and stop receiving packets on specified port.

Stops listening for UDP packets on the specified port and removes the associated FIFO queue from the system. This function should be called when a UDP port is no longer needed to free system resources.

If the FIFO has queued packets waiting to be processed, the drain parameter controls whether these packets are discarded or left in the queue. Typically, you should drain the queue unless you have already processed all packets.

Parameters
listenPortThe UDP port number to unregister (must match a previously registered port)
drainIf true, frees all queued packets in the FIFO and releases their memory. If false, leaves queued packets in memory (default: false). In most cases, you should set this to true to prevent memory leaks.
Note
After calling this function, the port becomes available for other applications
Any subsequent packets arriving on this port will be ignored until re-registered
If drain is false and packets remain queued, you may have a memory leak
Warning
Always drain the FIFO (drain=true) unless you have a specific reason not to
Unregistering a port that was never registered has no effect but is safe

Expand for Example Usage

Examples

Example (typical cleanup):

// Registered earlier
RegisterUDPFifo(5000, 10); // Port 5000 with queue depth 10
// ... process packets ...
// Clean shutdown - drain all remaining packets
UnregisterUDPFifo(5000, true);

Example (graceful shutdown - process remaining packets first):

// Process all remaining packets before unregistering
UDPPacket packet;
while (ReadUDPPacket(&packet, 5000, 0)) { // 0 = non-blocking
ProcessPacket(packet);
ReleaseUDPPacket(packet);
}
// Now safe to unregister without drain since we processed everything
UnregisterUDPFifo(5000, false);

Example (application shutdown):

void ShutdownNetworking() {
// Unregister all UDP ports and free resources
UnregisterUDPFifo(5000, true); // Control port
UnregisterUDPFifo(5001, true); // Data port
UnregisterUDPFifo(5002, true); // Status port
}


See also
RegisterUDPFifo() to register a UDP port for receiving
ReadUDPPacket() to read packets from the FIFO
ReleaseUDPPacket() to free individual packet buffers