NetBurner User Datagram Protocol (UDP) Implementation.
More...
|
typedef void | udp_data_notify(OS_FIFO *pfifo, uint16_t port) |
| UDP packet arrival notification callback function type.
|
|
|
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.
|
|
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
- Dual API Design: Choose between OOP UDPPacket class or familiar BSD sockets
- IPv4 and IPv6 Support: Full dual-stack networking capabilities
- Zero-Copy Operations: Direct buffer access for maximum efficiency
- Quality of Service (QoS): DSCP marking for traffic prioritization
- Multi-Interface Routing: Send packets via specific network interfaces
- Automatic Memory Management: RAII-based resource cleanup in C++ API
- Fragment Handling: Support for large datagrams exceeding MTU
- FIFO-Based Reception: Non-blocking packet queue management
When to Use UDP
UDP is ideal for applications requiring:
- Low latency: No connection overhead or retransmission delays
- Broadcast/Multicast: One-to-many communication patterns
- Real-time data: Streaming sensor data, video, audio, gaming
- Simple request/response: DNS, SNMP, NTP, TFTP protocols
- Custom protocols: Where application handles reliability
Not suitable for: File transfers, critical data, ordered delivery requirements (use TCP for these scenarios)
API Selection Guide
Use UDPPacket Class When:
- Writing new C++ code
- Need automatic memory management
- Sending to multiple destinations
- Require direct buffer manipulation
- Working with NetBurner-specific features (OS_FIFO integration)
Use BSD Socket Functions When:
- Porting existing socket code
- Compatibility with standard POSIX code
- Integration with select()/poll() event loops
- Writing in C (not C++)
- Familiarity with Berkeley sockets
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) {
printf("UDP Echo Server listening on port 5000\r\n");
while (1) {
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);
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:584
#define TICKS_PER_SECOND
System clock ticks per second.
Definition constants.h:49
uint8_t OSFifoInit(OS_FIFO *pFifo)
Initialize a FIFO, which is used to pass structures from one task to another.
Definition nbrtos.h:2214
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) {
"SENSOR:%d,TEMP:%d",
GetDeviceID(), sensorValue);
}
void Send(const IPADDR &to, uint8_t ttl=0)
Send and free buffer (recommended - most efficient)
Definition udp.h:3373
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) {
if (sock < 0) {
printf("Failed to create socket\r\n");
return;
}
uint8_t buffer[1024];
uint16_t localPort, remotePort;
while (1) {
int n =
recvfrom(sock, buffer,
sizeof(buffer),
&clientIP, &localPort, &remotePort);
if (n > 0) {
buffer[n] = '\0';
printf("Received: %s from %s:%d\r\n",
buffer, AsciiIP(clientIP).c_str(), remotePort);
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:5940
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:5856
int CreateRxUdpSocket(uint16_t listening_port)
Create receive-only UDP socket bound to specified port.
- Example 4: Multi-Interface UDP Routing
pkt.
AddData(
"Hello from interface 1");
void SendViaInterfaceNum(const IPADDR &to, int interface, uint8_t ttl=0)
Send via specific interface and free buffer.
Definition udp.h:3782
void AddData(puint8_t pData, uint16_t len)
Add binary data (auto-updates size - no SetDataSize() needed)
- Example 5: Broadcast UDP Discovery
void SendDiscoveryBroadcast() {
IPADDR broadcastAddr = AsciiToIp(
"255.255.255.255");
}
Memory Management
UDPPacket Automatic Cleanup
The UDPPacket class uses RAII (Resource Acquisition Is Initialization):
- Constructor allocates buffer from pool
- Destructor automatically returns buffer to pool
- Send() frees buffer after transmission
- SendAndKeep() retains buffer for multiple sends
Buffer Lifecycle Example
void SendToMultipleHosts() {
}
void SendAndKeep(const IPADDR &to, uint8_t ttl=0)
Send copy, keep original (for sending to multiple destinations)
Definition udp.h:3177
Port Number Guidelines
- 0: Auto-assign ephemeral port (49152-65535 range)
- 1-1023: Well-known ports (requires root on some systems)
- 1024-49151: Registered ports for applications
- 49152-65535: Dynamic/private ports
Common UDP Ports:
- 53: DNS
- 67/68: DHCP
- 123: NTP (Network Time Protocol)
- 161/162: SNMP
- 514: Syslog
- 5353: mDNS
- 1900: SSDP (UPnP)
Quality of Service (QoS)
Use SetDSCP() to prioritize traffic in QoS-enabled networks:
DSCP Value | Traffic Class | Use Case
- 0 (CS0): Best Effort - Normal traffic
- 8 (CS1): Bulk Data - Background transfers
- 10 (AF11): High-throughput data
- 18 (AF21): Low-latency data
- 26 (AF31): Multimedia streaming
- 34 (AF41): Multimedia conferencing
- 46 (EF): Expedited Forwarding - VoIP, real-time gaming
- 48 (CS6): Network control traffic
Performance Considerations
Buffer Size Limits
- IPv4 MTU: 1500 bytes (typical Ethernet)
- UDP Header: 8 bytes
- IP Header: 20 bytes (IPv4), 40 bytes (IPv6)
- Maximum Safe Payload: ~1472 bytes (IPv4), ~1452 bytes (IPv6)
- Fragmentation: Available for larger packets (use SendFragmentedUdpPacket())
Optimization Tips
- Use appropriate data insertion method:
- GetDataBuffer() + SetDataSize(): Best for sprintf/binary writes
- AddData(): Best for incremental assembly
- Minimize packet sends:
- Batch data when possible
- Use SendAndKeep() only when necessary
- FIFO sizing:
- Size FIFO based on expected burst traffic
- Monitor FIFO with GetFifoMessageCount()
- Interface binding:
- Bind sockets to specific interfaces in multi-homed systems
- Reduces routing overhead
Error Handling
UDPPacket Validation
printf("Packet validation failed\r\n");
return;
}
BOOL Validate(void)
Validate received packet (checks checksum and data presence)
Socket Error Codes
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:4740
#define UDP_ERR_NOSUCH_SOCKET
Socket does not exist.
Definition udp.h:4738
#define UDP_ERR_NOTOPEN_TO_WRITE
Socket not open for write.
Definition udp.h:4739
Thread Safety
- UDPPacket: Each packet object should be used by single task
- OS_FIFO: Thread-safe for multiple consumers/producers
- BSD Sockets: Each socket should be accessed by single task
- Multiple packets: Create separate UDPPacket for each task
Advanced Features
IPv6 Dual-Stack
#ifdef IPV6
IPADDR destIP = AsciiToIp(
"2001:db8::1");
IPADDR destIP = AsciiToIp(
"192.168.1.100");
#endif
Fragment Handling
uint8_t largeData[8000];
destIP,
5000,
6000,
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:5998
MAC Address Access
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
- Use EnableSystemDiagnostics(): Monitor system resources
- Check FIFO overflow: Increase FIFO size if packets dropped
- Validate packets: Always call Validate() after receiving
- Monitor port conflicts: Ensure unique port assignments
- Network tools: Use Wireshark to capture actual packets
Common Pitfalls
[NO] Forgetting to set data size
[YES] Correct approach
[NO] Using packet after Send()
[YES] Use SendAndKeep() for multiple sends
[NO] Not validating received packets
[YES] Always validate
◆ 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
-
pfifo | Pointer to the OS_FIFO where the packet will be queued. This is the same FIFO that was registered with the port. |
port | The 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:
void MyUdpNotify(
OS_FIFO *pfifo, uint16_t port) {
static volatile uint32_t packetCount = 0;
packetCount++;
}
Example with task notification:
void UdpArrivalNotify(
OS_FIFO *pfifo, uint16_t port) {
}
void ProcessingTask(void *pdata) {
while (1) {
if (ReadUDPPacket(&packet, myPort, 0)) {
ProcessPacket(&packet);
ReleaseUDPPacket(packet);
}
}
}
uint8_t OSSemPend(OS_SEM *psem, uint16_t timeout)
Wait timeout ticks for the value of the semaphore to be non zero. Note: A timeout value of 0 (zero) w...
Definition nbrtos.h:1987
uint8_t OSSemPost(OS_SEM *psem)
Increases the value of the semaphore by one. Note: If any higher priority tasks were waiting on the s...
Definition nbrtos.h:1968
Semaphores are used to control access to shared resources or or to communicate between tasks in a mul...
Definition nbrtos.h:411
Example with 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()
◆ 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
-
pfifo | Pointer 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. |
ifn | Network 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):
if (myPort == 0) {
printf("Failed to register ephemeral port\n");
return;
}
printf("Listening on ephemeral port %d\n", myPort);
IPADDR server = AsciiToIp(
"192.168.1.100");
SendUdpPacket(server, myPort, 8000, (uint8_t*)"REQUEST", 7);
printf("Got reply from %s\n", reply.sourceIpAddr.toString());
ReleaseUDPPacket(reply);
}
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 {
uint16_t port;
};
ClientConnection connections[5];
for (int i = 0; i < 5; i++) {
if (connections[i].port == 0) {
printf("Failed to register port for connection %d\n", i);
}
}
for (int i = 0; i < 5; i++) {
if (connections[i].port != 0) {
}
}
- 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
-
listenPort | UDP 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. |
pFifo | Pointer 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:
printf("UDP port 1234 registered successfully\n");
} else {
printf("Failed to register port 1234\n");
}
Example with custom FIFO depth:
printf("High-traffic port 5000 registered with 20 packet buffer\n");
while (true) {
printf("Received %d bytes from %s:%d\n",
packet.receivedDataLen,
packet.sourceIpAddr.toString(),
packet.sourcePort);
ProcessPacket(&packet);
ReleaseUDPPacket(packet);
}
}
}
Example with proper cleanup:
printf("Port 8000 unregistered\n");
}
Example - multiple ports:
OS_FIFO controlFifo, dataFifo, statusFifo;
if (ReadUDPPacket(&controlPacket, 5000, 0)) {
HandleControl(&controlPacket);
ReleaseUDPPacket(controlPacket);
}
Example - error handling:
const uint16_t PORT = 9000;
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
-
listenPort | UDP port number to register (1-65535). Must not already be registered on the specified interface. The same port can be registered on different interfaces. |
pFifo | Pointer 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. |
interface | Network 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):
printf("Management port 161 registered on interface 0\n");
}
printf("Data port 5000 registered on interface 1\n");
}
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):
if (ReadUDPPacket(&packet, 8000, 0)) {
printf("Packet received on one of the interfaces\n");
ReleaseUDPPacket(packet);
}
Example (interface availability checking):
int targetInterface = 1;
if (GetInterfaceCount() > targetInterface) {
if (InterfaceActive(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):
const uint16_t SERVICE_PORT = 9000;
const int PRIMARY_IF = 0;
const int FAILOVER_IF = 1;
if (primaryOk && failoverOk) {
printf("Failover system ready on port %d\n", SERVICE_PORT);
while (true) {
if (ReadUDPPacket(&packet, SERVICE_PORT, 0)) {
printf("Packet received - processing\n");
ProcessPacket(&packet);
ReleaseUDPPacket(packet);
}
}
}
void OSTimeDly(uint32_t to_count)
Delay the task until the specified value of the system timer ticks. The number of system ticks per se...
Definition nbrtos.h:1850
Example (WiFi vs Ethernet separation):
#define ETH_INTERFACE 0
#define WIFI_INTERFACE 1
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()
#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
-
listenPort | UDP port number to register (1-65535). Must not already be registered. |
pFifo | Pointer 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. |
pNotifyFunction | Pointer 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):
void PingNotify(uint16_t port, uint8_t* data,
int len,
IPADDR& srcAddr) {
if (len >= 4 && memcmp(data, "PING", 4) == 0) {
SendUdpPacket(srcAddr, port, port, (uint8_t*)"PONG", 4);
}
}
printf("Ping responder registered on port 9000\n");
}
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):
volatile uint32_t packetCount = 0;
volatile uint32_t filteredCount = 0;
void DatagramNotify(uint16_t port, uint8_t* data,
int len,
IPADDR& srcAddr) {
packetCount++;
if (len < 10) {
filteredCount++;
}
}
printf("Received: %lu, Filtered: %lu\n", packetCount, filteredCount);
Example (notification only, no FIFO):
volatile uint32_t statsPackets = 0;
void StatsOnlyNotify(uint16_t port, uint8_t* data,
int len,
IPADDR& srcAddr) {
statsPackets++;
}
- 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
-
listenPort | UDP port number to register (1-65535). Must not already be registered on the specified interface. |
pFifo | Pointer to an OS_FIFO structure for queuing packets. Must be initialized before calling. Can be NULL for notification-only. |
pNotifyFunction | Pointer 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. |
interface | Network 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):
printf("Registered on Ethernet (interface 0)\n");
}
printf("Registered on WiFi (interface 1)\n");
}
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):
if (ReadUDPPacket(&mgmtPacket, 161, 0)) {
printf("Management packet from secure network\n");
ReleaseUDPPacket(mgmtPacket);
}
Example (interface-specific notification):
void PrimaryNotify(uint16_t port, uint8_t* data,
int len,
IPADDR& srcAddr) {
primaryPacketCount++;
}
void BackupNotify(uint16_t port, uint8_t* data,
int len,
IPADDR& srcAddr) {
backupPacketCount++;
TriggerFailoverAlert();
}
Example (checking interface availability first):
int targetInterface = 1;
if (GetInterfaceCount() > targetInterface && InterfaceActive(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
-
listenPort | The UDP port number to unregister (must match a previously registered port) |
drain | If 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):
Example (graceful shutdown - process remaining packets first):
while (ReadUDPPacket(&packet, 5000, 0)) {
ProcessPacket(packet);
ReleaseUDPPacket(packet);
}
Example (application shutdown):
void ShutdownNetworking() {
}
- See also
- RegisterUDPFifo() to register a UDP port for receiving
-
ReadUDPPacket() to read packets from the FIFO
-
ReleaseUDPPacket() to free individual packet buffers