22#if UIP_CONF_UDP > 0 || RF24ETHERNET_USE_UDP > 0
24 #if RF24ETHERNET_USE_UDP && USE_LWIP == 1
26struct udp_pcb* RF24UDP::udpPcb;
27int8_t RF24UDP::udpDataIn[MAX_PAYLOAD_SIZE - 14];
28int8_t RF24UDP::udpDataOut[MAX_PAYLOAD_SIZE - 14];
29int32_t RF24UDP::dataInPos;
30int32_t RF24UDP::dataOutPos;
32 #if !defined ETHERNET_USING_LWIP_ARDUINO
34 #include "lwip/tcpip.h"
36 #include "lwip/include/lwip/udp.h"
37 #include "lwip/include/lwip/tcpip.h"
40 #if RF24ETHERNET_USE_UDP && USE_LWIP == 2
41 #include <zephyr/kernel.h>
42 #include <zephyr/net/socket.h>
46 #ifdef RF24ETHERNET_DEBUG_UDP
47 #include "HardwareSerial.h"
50 #if UIP_UDP || RF24ETHERNET_USE_UDP
51 #define UIP_ARPHDRSIZE 42
52 #define UDPBUF ((struct uip_udpip_hdr*)&uip_buf[UIP_LLH_LEN])
56 #ifndef RF24ETHERNET_USE_UDP
60 memset(&appdata, 0,
sizeof(appdata));
62 #elif defined RF24ETHERNET_USE_UDP && USE_LWIP == 1
66 #elif defined RF24ETHERNET_USE_UDP && USE_LWIP == 2
80 #ifndef RF24ETHERNET_USE_UDP
83 _uip_udp_conn = uip_udp_new(NULL, 0);
87 uip_udp_bind(_uip_udp_conn, htons(port));
88 _uip_udp_conn->appstate = &appdata;
94 if (udpPcb ==
nullptr) {
97 err_t err = udp_bind(udpPcb, IP_ANY_TYPE, port);
105 if (udpSocketIn > -1) {
106 zsock_close(udpSocketIn);
110 udpSocketIn = zsock_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
111 if (udpSocketIn < 0) {
116 memset(&udpBindAddr, 0,
sizeof(udpBindAddr));
117 udpBindAddr.sin_family = AF_INET;
118 udpBindAddr.sin_port = htons(port);
119 udpBindAddr.sin_addr.s_addr = INADDR_ANY;
122 zsock_setsockopt(udpSocketIn, SOL_SOCKET, SO_REUSEADDR, &optval,
sizeof(optval));
124 if (zsock_bind(udpSocketIn, (
struct sockaddr*)&udpBindAddr,
sizeof(udpBindAddr)) < 0) {
125 zsock_close(udpSocketIn);
129 int flags = zsock_fcntl(udpSocketIn, F_GETFL, 0);
130 zsock_fcntl(udpSocketIn, F_SETFL, flags | O_NONBLOCK);
142 #ifndef RF24ETHERNET_USE_UDP
145 uip_udp_remove(_uip_udp_conn);
146 _uip_udp_conn->appstate = NULL;
147 _uip_udp_conn = NULL;
148 appdata.packet_in = 0;
149 appdata.packet_next = 0;
150 appdata.packet_out = 0;
152 memset(&appdata, 0,
sizeof(appdata));
156 if (udpPcb !=
nullptr) {
157 udp_disconnect(udpPcb);
160 if (udpSocketIn > -1) {
161 zsock_close(udpSocketIn);
165 if (udpSocketOut > -1) {
166 zsock_close(udpSocketOut);
181 #ifndef RF24ETHERNET_USE_UDP
182 RF24EthernetClass::tick();
185 uip_ipaddr_t ripaddr;
191 _uip_udp_conn->rport = htons(port);
192 uip_ipaddr_copy(_uip_udp_conn->ripaddr, &ripaddr);
196 _uip_udp_conn = uip_udp_new(&ripaddr, htons(port));
200 _uip_udp_conn->appstate = &appdata;
208 IF_RF24ETHERNET_DEBUG_UDP(Serial.print(F(
"rip: ")); Serial.print(ip); Serial.print(F(
", port: ")); Serial.println(port););
213 if (appdata.packet_out == 0)
215 appdata.packet_out = 1;
217 if (appdata.packet_out != 0)
236 #if defined ARDUINO_ARCH_ESP32 || defined ARDUINO_ARCH_ESP8266 || defined ARDUINO_ARCH_RP2040 || defined ARDUINO_ARCH_RP2350
237 IP4_ADDR(&myIp, ip[0], ip[1], ip[2], ip[3]);
238 ip_addr_t generic_addr;
239 ip_addr_copy_from_ip4(generic_addr, myIp);
240 err = udp_connect(udpPcb, &generic_addr, port);
242 IP4_ADDR(&myIp, ip[0], ip[1], ip[2], ip[3]);
244 err = udp_connect(udpPcb, &myIp, port);
253 if (udpSocketOut >= 0) {
254 zsock_close(udpSocketOut);
258 udpSocketOut = zsock_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
259 if (udpSocketOut < 0) {
263 memset(&udpDestination, 0,
sizeof(udpDestination));
264 udpDestination.sin_family = AF_INET;
265 udpDestination.sin_port = htons(port);
266 udpDestination.sin_addr.s_addr = (uint32_t)ip;
268 if (zsock_inet_pton(AF_INET, ip.toString().c_str(), &udpDestination.sin_addr) != 1) {
269 zsock_close(udpSocketOut);
274 int flags = zsock_fcntl(udpSocketOut, F_GETFL, 0);
275 zsock_fcntl(udpSocketOut, F_SETFL, flags | O_NONBLOCK);
286 #ifndef RF24ETHERNET_USE_UDP
290 IPAddress remote_addr;
306 IPAddress remote_addr;
328 #ifndef RF24ETHERNET_USE_UDP
329 if (_uip_udp_conn && appdata.packet_out != 0)
333 uip_udp_periodic_conn(_uip_udp_conn);
343 if (dataOutPos > 0) {
350 ssize_t ret = zsock_sendto(udpSocketOut, udpDataOut, dataOutPos, 0, (
struct sockaddr*)&udpDestination,
sizeof(udpDestination));
373 #ifndef RF24ETHERNET_USE_UDP
374 if (appdata.packet_out != 0)
376 IF_RF24ETHERNET_DEBUG_UDP(Serial.println(
"RF24UDP Write: "); Serial.println(size); for (
int i = 0; i < size; i++) { Serial.print((
char)buffer[i]); Serial.print(
" "); } Serial.println(
""););
378 memcpy(RF24Client::all_data[0].myData + appdata.out_pos, buffer, size);
379 appdata.out_pos += ret;
385 memcpy(&udpDataOut[dataOutPos], buffer, size);
399 RF24EthernetClass::tick();
401 #ifndef RF24ETHERNET_USE_UDP
403 int size = appdata.packet_in_size;
405 IF_RF24ETHERNET_DEBUG_UDP(
if (appdata.packet_in != 0) { Serial.print(F(
"RF24UDP udp parsePacket freeing previous packet: ")); Serial.println(appdata.packet_in); });
412 IF_RF24ETHERNET_DEBUG_UDP(
if (appdata.packet_in != 0) { Serial.print(F(
"RF24UDP udp parsePacket received packet: ")); Serial.print(appdata.packet_in); } Serial.print(F(
", size: ")); Serial.println(size););
428 RF24EthernetClass::tick();
429 #ifndef RF24ETHERNET_USE_UDP
430 return appdata.packet_in_size;
435 if (udpSocketOut >= 0) {
436 socklen_t client_addr_len =
sizeof(udpClientAddr);
437 ssize_t received = zsock_recvfrom(udpSocketOut, udpDataIn,
sizeof(udpDataIn) - 1, 0, (
struct sockaddr*)&udpClientAddr, &client_addr_len);
439 dataInPos += received;
440 uint32_t rawIP = udpClientAddr.sin_addr.s_addr;
441 IPAddress remIP(rawIP);
443 udpRemotePort = ntohs(udpClientAddr.sin_port);
448 if (udpSocketIn >= 0) {
449 socklen_t client_addr_len =
sizeof(udpClientAddr);
450 ssize_t received = zsock_recvfrom(udpSocketIn, udpDataIn,
sizeof(udpDataIn) - 1, 0, (
struct sockaddr*)&udpClientAddr, &client_addr_len);
452 dataInPos += received;
453 uint32_t rawIP = udpClientAddr.sin_addr.s_addr;
454 IPAddress remIP(rawIP);
456 udpRemotePort = ntohs(udpClientAddr.sin_port);
487 #ifndef RF24ETHERNET_USE_UDP
488 if (appdata.packet_in != 0)
492 if (appdata.packet_in_size < 0) {
493 appdata.packet_in_size = 0;
495 if (len > (
size_t)appdata.packet_in_size) {
496 len = (size_t)appdata.packet_in_size;
498 memcpy(buffer, RF24Client::all_data[0].myData + appdata.in_pos, len);
499 appdata.in_pos += len;
500 appdata.packet_in_size -= len;
502 if (appdata.packet_in_size < 1)
504 appdata.packet_in = 0;
508 #elif USE_LWIP == 1 || USE_LWIP == 2
510 if (dataInPos >= len) {
512 size_t remainder = dataInPos - len;
513 memcpy(&buffer[0], &udpDataIn[0], len);
515 memmove(udpDataIn, &udpDataIn[len], remainder);
517 dataInPos = rf24_max(0, remainder);
530 #ifndef RF24ETHERNET_USE_UDP
531 RF24EthernetClass::tick();
533 if (appdata.packet_in != 0)
535 return RF24Client::all_data[0].myData[appdata.in_pos];
538 #elif USE_LWIP == 1 || USE_LWIP == 1
553 #ifndef RF24ETHERNET_USE_UDP
554 appdata.packet_in = 0;
555 appdata.packet_in_size = 0;
569 #ifndef RF24ETHERNET_USE_UDP
570 return _uip_udp_conn ?
ip_addr_uip(_uip_udp_conn->ripaddr) : IPAddress();
573 if (udpPcb !=
nullptr) {
574 const ip4_addr_t* addr = ip_2_ip4(&udpPcb->remote_ip);
576 ip4_addr_get_byte(addr, 0),
577 ip4_addr_get_byte(addr, 1),
578 ip4_addr_get_byte(addr, 2),
579 ip4_addr_get_byte(addr, 3));
581 return IPAddress {0, 0, 0, 0};
593 #ifndef RF24ETHERNET_USE_UDP
594 return _uip_udp_conn ? ntohs(_uip_udp_conn->rport) : 0;
597 if (udpPcb !=
nullptr) {
598 return udpPcb->remote_port;
603 return udpRemotePort;
613 #ifndef RF24ETHERNET_USE_UDP
614 if (uip_udp_userdata_t* data = (uip_udp_userdata_t*)(uip_udp_conn->appstate))
618 if (data->packet_next == 0)
620 uip_udp_conn->rport =
UDPBUF->srcport;
621 uip_ipaddr_copy(uip_udp_conn->ripaddr,
UDPBUF->srcipaddr);
625 uint16_t udpLen = uip_len;
629 memcpy(RF24Client::all_data[0].myData, uip_appdata, udpLen);
630 data->packet_in_size += udpLen;
633 IF_RF24ETHERNET_DEBUG_UDP(Serial.print(F(
"RF24UDP udp, uip_newdata received packet: ")); Serial.print(data->packet_next); Serial.print(F(
", size: ")); Serial.println(data->packet_in_size); for (
int i = 0; i < data->packet_in_size; i++) { Serial.print(RF24Client::all_data[0].myData[i],HEX); Serial.print(F(
" : ")); } Serial.println(););
636 if (uip_poll() && data->send)
639 IF_RF24ETHERNET_DEBUG_UDP(Serial.print(F(
"udp, uip_poll preparing packet to send: ")); Serial.print(data->packet_out); Serial.print(F(
", size: ")); Serial.println(data->out_pos););
641 memcpy(uip_appdata, RF24Client::all_data[0].myData, data->out_pos);
642 uip_udp_send(data->out_pos);
651 #if RF24ETHERNET_USE_UDP && USE_LWIP == 1
652void RF24UDP::receiveUdp(
void* arg,
struct udp_pcb* pcb,
struct pbuf* p,
const ip_addr_t* addr,
u16_t port)
658 uint16_t copyLen = p->len;
659 if (copyLen >
sizeof(udpDataIn)) {
660 copyLen =
sizeof(udpDataIn);
662 memcpy(&udpDataIn[0], p->payload, copyLen);
673 #if RF24ETHERNET_USE_UDP && USE_LWIP == 1
674void RF24UDP::sendUdp(
void* arg)
677 struct udp_send_ctx* data = (
struct udp_send_ctx*)arg;
679 udp_send(data->pcb, data->p);
683 #ifndef RF24ETHERNET_USE_UDP
684void RF24UDP::_send(uip_udp_userdata_t* data)
690 #ifndef RF24ETHERNET_USE_UDP
691 #if defined(RF24_TAP)
700 RF24EthernetClass::network_send();
706 data->packet_out = 0;
708 IF_RF24ETHERNET_DEBUG_UDP(Serial.println(data->out_pos); Serial.print(F(
"udp, uip_packet to send: "));
for (
int i = 0; i < data->out_pos; i++) { Serial.print((
char)RF24Client::all_data[0].myData[i]); } Serial.println(
""););
710 RF24NetworkHeader headerOut(00, EXTERNAL_DATA_TYPE);
719 udp_recv(udpPcb, receiveUdp,
udpState);
721 pbuf* p = pbuf_alloc(PBUF_RAW, dataOutPos, PBUF_RAM);
723 memcpy(
reinterpret_cast<uint8_t*
>(p->payload), &udpDataOut[0], dataOutPos);
#define uip_ip_addr(addr, ip)
RF24EthernetClass RF24Ethernet
void uipudp_appcall(void)
static UDPState * udpState
void begin(const IPAddress &aDNSServer)
int getHostByName(const char *aHostname, IPAddress &aResult)
int endPacket()
Finish off this packet and send it.
size_t write(uint8_t)
Write a single byte into the packet.
void stop()
Finish with the UDP socket.
int beginPacket(IPAddress ip, uint16_t port)
Sending UDP packets.
uint8_t begin(uint16_t)
initialize, start listening on specified port.
#define IF_RF24ETHERNET_DEBUG_UDP(x)
#define OUTPUT_BUFFER_SIZE
volatile bool dataReceived
uint16_t u16_t
16 bit datatype