RF24Ethernet - TCP/IP over RF24Network v2.2.6
TMRh20 - Pushing the practical limits of RF24 modules
Loading...
Searching...
No Matches
RF24Udp.cpp
Go to the documentation of this file.
1/*
2 RF24UDP.cpp - Arduino implementation of a uIP wrapper class.
3 Copyright (c) 2014 tmrh20@gmail.com, github.com/TMRh20
4 Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
5 All rights reserved.
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20#include "RF24Ethernet.h"
21
22#if UIP_CONF_UDP > 0 || RF24ETHERNET_USE_UDP > 0
23
24 #if RF24ETHERNET_USE_UDP && USE_LWIP == 1
25
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;
31
32 #if !defined ETHERNET_USING_LWIP_ARDUINO
33 #include "lwip/udp.h"
34 #include "lwip/tcpip.h"
35 #else
36 #include "lwip/include/lwip/udp.h"
37 #include "lwip/include/lwip/tcpip.h"
38 #endif
39 #endif
40 #if RF24ETHERNET_USE_UDP && USE_LWIP == 2
41 #include <zephyr/kernel.h>
42 #include <zephyr/net/socket.h>
43 #include <fcntl.h>
44 #endif
45
46 #ifdef RF24ETHERNET_DEBUG_UDP
47 #include "HardwareSerial.h"
48 #endif
49
50 #if UIP_UDP || RF24ETHERNET_USE_UDP
51 #define UIP_ARPHDRSIZE 42
52 #define UDPBUF ((struct uip_udpip_hdr*)&uip_buf[UIP_LLH_LEN])
53
54 /*******************************************************/
55
56 #ifndef RF24ETHERNET_USE_UDP
57// Constructor
58RF24UDP::RF24UDP() : _uip_udp_conn(NULL)
59{
60 memset(&appdata, 0, sizeof(appdata));
61}
62 #elif defined RF24ETHERNET_USE_UDP && USE_LWIP == 1
66 #elif defined RF24ETHERNET_USE_UDP && USE_LWIP == 2
68{
69 udpSocketOut = -1;
70 udpSocketIn = -1;
71 dataInPos = 0;
72 dataOutPos = 0;
73}
74 #endif
75/*******************************************************/
76
77// initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
78uint8_t RF24UDP::begin(uint16_t port)
79{
80 #ifndef RF24ETHERNET_USE_UDP
81 if (!_uip_udp_conn)
82 {
83 _uip_udp_conn = uip_udp_new(NULL, 0);
84 }
85 if (_uip_udp_conn)
86 {
87 uip_udp_bind(_uip_udp_conn, htons(port));
88 _uip_udp_conn->appstate = &appdata;
89 return 1;
90 }
91 return 0;
92 #elif USE_LWIP == 1
93
94 if (udpPcb == nullptr) {
95 udpPcb = udp_new();
96 }
97 err_t err = udp_bind(udpPcb, IP_ANY_TYPE, port);
98
99 if (err == ERR_OK) {
100 return 1;
101 }
102 return 0;
103 #elif USE_LWIP == 2
104
105 if (udpSocketIn > -1) {
106 zsock_close(udpSocketIn);
107 udpSocketIn = -1;
108 }
109
110 udpSocketIn = zsock_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
111 if (udpSocketIn < 0) {
112 return 0;
113 }
114
115 dataInPos = 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;
120
121 int optval = 1;
122 zsock_setsockopt(udpSocketIn, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
123
124 if (zsock_bind(udpSocketIn, (struct sockaddr*)&udpBindAddr, sizeof(udpBindAddr)) < 0) {
125 zsock_close(udpSocketIn);
126 udpSocketIn = -1;
127 return 0;
128 }
129 int flags = zsock_fcntl(udpSocketIn, F_GETFL, 0);
130 zsock_fcntl(udpSocketIn, F_SETFL, flags | O_NONBLOCK);
131
132 return 1;
133
134 #endif
135}
136
137/*******************************************************/
138
139// Finish with the UDP socket
141{
142 #ifndef RF24ETHERNET_USE_UDP
143 if (_uip_udp_conn)
144 {
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;
151
152 memset(&appdata, 0, sizeof(appdata));
153 }
154 #elif USE_LWIP == 1
155
156 if (udpPcb != nullptr) {
157 udp_disconnect(udpPcb);
158 }
159 #elif USE_LWIP == 2
160 if (udpSocketIn > -1) {
161 zsock_close(udpSocketIn);
162 }
163 dataInPos = 0;
164
165 if (udpSocketOut > -1) {
166 zsock_close(udpSocketOut);
167 udpSocketOut = -1;
168 }
169 dataOutPos = 0;
170 #endif
171}
172
173/*******************************************************/
174
175// Sending UDP packets
176
177// Start building up a packet to send to the remote host specific in ip and port
178// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
179int RF24UDP::beginPacket(IPAddress ip, uint16_t port)
180{
181 #ifndef RF24ETHERNET_USE_UDP
182 RF24EthernetClass::tick();
183 if (ip && port)
184 {
185 uip_ipaddr_t ripaddr;
186 uip_ip_addr(&ripaddr, ip);
187 IF_RF24ETHERNET_DEBUG_UDP(Serial.print(F("RF24UDP udp beginPacket, ")););
188
189 if (_uip_udp_conn)
190 {
191 _uip_udp_conn->rport = htons(port);
192 uip_ipaddr_copy(_uip_udp_conn->ripaddr, &ripaddr);
193 }
194 else
195 {
196 _uip_udp_conn = uip_udp_new(&ripaddr, htons(port));
197 if (_uip_udp_conn)
198 {
199 IF_RF24ETHERNET_DEBUG_UDP(Serial.print(F("RF24UDP New connection, ")););
200 _uip_udp_conn->appstate = &appdata;
201 }
202 else
203 {
204 IF_RF24ETHERNET_DEBUG_UDP(Serial.println(F("RF24UDP Failed to allocate new connection")););
205 return 0;
206 }
207 }
208 IF_RF24ETHERNET_DEBUG_UDP(Serial.print(F("rip: ")); Serial.print(ip); Serial.print(F(", port: ")); Serial.println(port););
209 }
210
211 if (_uip_udp_conn)
212 {
213 if (appdata.packet_out == 0)
214 {
215 appdata.packet_out = 1;
216 appdata.out_pos = 0; // UIP_UDP_PHYH_LEN;
217 if (appdata.packet_out != 0)
218 {
219 return 1;
220 }
221 else
222 {
223 IF_RF24ETHERNET_DEBUG_UDP(Serial.println(F("RF24UDP Failed to allocate memory for packet")););
224 }
225 }
226 else
227 {
228 IF_RF24ETHERNET_DEBUG_UDP(Serial.println(F("RF24UDP Previous packet on that connection not sent yet")););
229 }
230 }
231 return 0;
232 #elif USE_LWIP == 1
233
234 err_t err = ERR_OK;
235 ip4_addr_t myIp;
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);
241 #else
242 IP4_ADDR(&myIp, ip[0], ip[1], ip[2], ip[3]);
243 // Start non-blocking connection
244 err = udp_connect(udpPcb, &myIp, port);
245 #endif
246
247 if (err == ERR_OK) {
248 return 1;
249 }
250 return 0;
251 #elif USE_LWIP == 2
252
253 if (udpSocketOut >= 0) {
254 zsock_close(udpSocketOut);
255 udpSocketOut = -1;
256 }
257
258 udpSocketOut = zsock_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
259 if (udpSocketOut < 0) {
260 return 0;
261 }
262
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;
267
268 if (zsock_inet_pton(AF_INET, ip.toString().c_str(), &udpDestination.sin_addr) != 1) {
269 zsock_close(udpSocketOut);
270 udpSocketOut = -1;
271 return 0;
272 }
273
274 int flags = zsock_fcntl(udpSocketOut, F_GETFL, 0);
275 zsock_fcntl(udpSocketOut, F_SETFL, flags | O_NONBLOCK);
276 return 1;
277 #endif
278}
279
280/*******************************************************/
281
282// Start building up a packet to send to the remote host specific in host and port
283// Returns 1 if successful, 0 if there was a problem resolving the hostname or port
284int RF24UDP::beginPacket(const char* host, uint16_t port)
285{
286 #ifndef RF24ETHERNET_USE_UDP
287 // Look up the host first
288 int ret = 0;
289 DNSClient dns;
290 IPAddress remote_addr;
291
292 dns.begin(RF24Ethernet.dnsServerIP());
293 ret = dns.getHostByName(host, remote_addr);
294 if (ret == 1)
295 {
296 return beginPacket(remote_addr, port);
297 }
298 else
299 {
300 return ret;
301 }
302 #else
303 // Look up the host first
304 int ret = 0;
305 DNSClient dns;
306 IPAddress remote_addr;
307
308 dns.begin(RF24Ethernet.dnsServerIP());
309 ret = dns.getHostByName(host, remote_addr);
310 if (ret == 1)
311 {
312 return beginPacket(remote_addr, port);
313 }
314 else
315 {
316 return ret;
317 }
318
319 #endif
320}
321
322/*******************************************************/
323
324// Finish off this packet and send it
325// Returns 1 if the packet was sent successfully, 0 if there was an error
327{
328 #ifndef RF24ETHERNET_USE_UDP
329 if (_uip_udp_conn && appdata.packet_out != 0)
330 {
331 appdata.send = true;
332 IF_RF24ETHERNET_DEBUG_UDP(Serial.println(F("RF24UDP endpacket")););
333 uip_udp_periodic_conn(_uip_udp_conn);
334 if (uip_len > 0)
335 {
336 _send(&appdata);
337 return 1;
338 }
339 }
340 return 0;
341 #elif USE_LWIP == 1
342
343 if (dataOutPos > 0) {
344 _send();
345 return 1;
346 }
347 return 0;
348 #elif USE_LWIP == 2
349
350 ssize_t ret = zsock_sendto(udpSocketOut, udpDataOut, dataOutPos, 0, (struct sockaddr*)&udpDestination, sizeof(udpDestination));
351 if (ret >= 0) {
352 return 1;
353 }
354 else {
355 return 0;
356 }
357 #endif
358}
359
360/*******************************************************/
361
362// Write a single byte into the packet
363size_t RF24UDP::write(uint8_t c)
364{
365 return write(&c, 1);
366}
367
368/*******************************************************/
369
370// Write size bytes from buffer into the packet
371size_t RF24UDP::write(const uint8_t* buffer, size_t size)
372{
373 #ifndef RF24ETHERNET_USE_UDP
374 if (appdata.packet_out != 0)
375 {
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(""););
377 size_t ret = size;
378 memcpy(RF24Client::all_data[0].myData + appdata.out_pos, buffer, size);
379 appdata.out_pos += ret;
380 return ret;
381 }
382 return 0;
383 #else
384
385 memcpy(&udpDataOut[dataOutPos], buffer, size);
386 dataOutPos += size;
387
388 return size;
389
390 #endif
391}
392
393/*******************************************************/
394
395// Start processing the next available incoming packet
396// Returns the size of the packet in bytes, or 0 if no packets are available
398{
399 RF24EthernetClass::tick();
400
401 #ifndef RF24ETHERNET_USE_UDP
402
403 int size = appdata.packet_in_size;
404
405 IF_RF24ETHERNET_DEBUG_UDP(if (appdata.packet_in != 0) { Serial.print(F("RF24UDP udp parsePacket freeing previous packet: ")); Serial.println(appdata.packet_in); });
406
407 // appdata.packet_in_size = 0;
408
409 // appdata.packet_in = appdata.packet_next;
410 // appdata.packet_next = 0;
411
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););
413
414 return size;
415 #elif USE_LWIP == 1
416
417 return dataInPos;
418 #elif USE_LWIP == 2
419 return available();
420 #endif
421}
422
423/*******************************************************/
424
425// Number of bytes remaining in the current packet
427{
428 RF24EthernetClass::tick();
429 #ifndef RF24ETHERNET_USE_UDP
430 return appdata.packet_in_size;
431 #elif USE_LWIP == 1
432 return dataInPos;
433 #elif USE_LWIP == 2
434
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);
438 if (received >= 0) {
439 dataInPos += received;
440 uint32_t rawIP = udpClientAddr.sin_addr.s_addr;
441 IPAddress remIP(rawIP);
442 udpRemoteIP = remIP;
443 udpRemotePort = ntohs(udpClientAddr.sin_port);
444 return dataInPos;
445 }
446 }
447
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);
451 if (received >= 0) {
452 dataInPos += received;
453 uint32_t rawIP = udpClientAddr.sin_addr.s_addr;
454 IPAddress remIP(rawIP);
455 udpRemoteIP = remIP;
456 udpRemotePort = ntohs(udpClientAddr.sin_port);
457 return dataInPos;
458 }
459 }
460
461 return dataInPos;
462
463 #endif
464}
465
466/*******************************************************/
467
468// Read a single byte from the current packet
470{
471 unsigned char c;
472 if (read(&c, 1) > 0)
473 {
474 return c;
475 }
476 return -1;
477}
478
479/*******************************************************/
480
481// Read up to len bytes from the current packet and place them into buffer
482// Returns the number of bytes read, or 0 if none are available
483int RF24UDP::read(unsigned char* buffer, size_t len)
484{
485
486 //RF24EthernetClass::tick();
487 #ifndef RF24ETHERNET_USE_UDP
488 if (appdata.packet_in != 0)
489 {
490 // Never return more than the packet actually holds, or in_pos walks off
491 // myData and packet_in_size (an int) underflows to a large positive value
492 if (appdata.packet_in_size < 0) {
493 appdata.packet_in_size = 0;
494 }
495 if (len > (size_t)appdata.packet_in_size) {
496 len = (size_t)appdata.packet_in_size;
497 }
498 memcpy(buffer, RF24Client::all_data[0].myData + appdata.in_pos, len);
499 appdata.in_pos += len;
500 appdata.packet_in_size -= len;
501
502 if (appdata.packet_in_size < 1)
503 {
504 appdata.packet_in = 0;
505 }
506 return len;
507 }
508 #elif USE_LWIP == 1 || USE_LWIP == 2
509
510 if (dataInPos >= len) {
511
512 size_t remainder = dataInPos - len;
513 memcpy(&buffer[0], &udpDataIn[0], len);
514 if (remainder > 0) {
515 memmove(udpDataIn, &udpDataIn[len], remainder);
516 }
517 dataInPos = rf24_max(0, remainder);
518 return len;
519 }
520
521 #endif
522 return 0;
523}
524
525/*******************************************************/
526
527// Return the next byte from the current packet without moving on to the next byte
529{
530 #ifndef RF24ETHERNET_USE_UDP
531 RF24EthernetClass::tick();
532
533 if (appdata.packet_in != 0)
534 {
535 return RF24Client::all_data[0].myData[appdata.in_pos];
536 }
537 return -1;
538 #elif USE_LWIP == 1 || USE_LWIP == 1
539
540 if (dataInPos > 0) {
541 return udpDataIn[0];
542 }
543 return -1;
544
545 #endif
546}
547
548/*******************************************************/
549
550// Finish reading the current packet
552{
553 #ifndef RF24ETHERNET_USE_UDP
554 appdata.packet_in = 0;
555 appdata.packet_in_size = 0;
556 #else
557 uint8_t c = 0;
558 while (read() > 0) {
559 };
560 #endif
561 //RF24EthernetClass::tick();
562}
563
564/*******************************************************/
565
566// Return the IP address of the host who sent the current incoming packet
568{
569 #ifndef RF24ETHERNET_USE_UDP
570 return _uip_udp_conn ? ip_addr_uip(_uip_udp_conn->ripaddr) : IPAddress();
571 #elif USE_LWIP == 1
572
573 if (udpPcb != nullptr) {
574 const ip4_addr_t* addr = ip_2_ip4(&udpPcb->remote_ip);
575 return IPAddress(
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));
580 }
581 return IPAddress {0, 0, 0, 0};
582 #elif USE_LWIP == 2
583
584 return udpRemoteIP;
585 #endif
586}
587
588/*******************************************************/
589
590// Return the port of the host who sent the current incoming packet
592{
593 #ifndef RF24ETHERNET_USE_UDP
594 return _uip_udp_conn ? ntohs(_uip_udp_conn->rport) : 0;
595 #elif USE_LWIP == 1
596
597 if (udpPcb != nullptr) {
598 return udpPcb->remote_port;
599 }
600 return 0;
601 #elif USE_LWIP == 2
602
603 return udpRemotePort;
604 #endif
605}
606
607/*******************************************************/
608
609// uIP callback function
610
612{
613 #ifndef RF24ETHERNET_USE_UDP
614 if (uip_udp_userdata_t* data = (uip_udp_userdata_t*)(uip_udp_conn->appstate))
615 {
616 if (uip_newdata())
617 {
618 if (data->packet_next == 0)
619 {
620 uip_udp_conn->rport = UDPBUF->srcport;
621 uip_ipaddr_copy(uip_udp_conn->ripaddr, UDPBUF->srcipaddr);
622
623 // discard Linklevel and IP and udp-header and any trailing bytes:
624 // uip_len is the UDP payload length here; myData is only OUTPUT_BUFFER_SIZE bytes
625 uint16_t udpLen = uip_len;
626 if (udpLen > OUTPUT_BUFFER_SIZE) {
627 udpLen = OUTPUT_BUFFER_SIZE;
628 }
629 memcpy(RF24Client::all_data[0].myData, uip_appdata, udpLen);
630 data->packet_in_size += udpLen;
631 data->packet_in = 1;
632
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(););
634 }
635 }
636 if (uip_poll() && data->send)
637 {
638 // set uip_slen (uip private) by calling uip_udp_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););
640
641 memcpy(uip_appdata, RF24Client::all_data[0].myData, data->out_pos);
642 uip_udp_send(data->out_pos);
643 }
644 }
645
646 #else
647
648 #endif
649}
650
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)
653{
654
655 if (p != NULL) {
656 // p->len is attacker/peer controlled; udpDataIn is a fixed static buffer.
657 // Buffer a single datagram's worth, clamped to the buffer size.
658 uint16_t copyLen = p->len;
659 if (copyLen > sizeof(udpDataIn)) {
660 copyLen = sizeof(udpDataIn);
661 }
662 memcpy(&udpDataIn[0], p->payload, copyLen);
663 dataInPos = copyLen;
664 pbuf_free(p);
665 if (udpState != nullptr) {
666 udpState->dataReceived = true;
667 }
668 }
669}
670
671 #endif
672
673 #if RF24ETHERNET_USE_UDP && USE_LWIP == 1
674void RF24UDP::sendUdp(void* arg)
675{
676
677 struct udp_send_ctx* data = (struct udp_send_ctx*)arg;
678
679 udp_send(data->pcb, data->p);
680}
681 #endif
682 /*******************************************************/
683 #ifndef RF24ETHERNET_USE_UDP
684void RF24UDP::_send(uip_udp_userdata_t* data)
685 #else
686void RF24UDP::_send()
687 #endif
688
689{
690 #ifndef RF24ETHERNET_USE_UDP
691 #if defined(RF24_TAP)
692 uip_arp_out(); // add arp
693 #endif
694 if (uip_len == UIP_ARPHDRSIZE)
695 {
696 // RF24EthernetClass::uip_packet = 0;
697 // RF24EthernetClass::packetstate &= ~UIPETHERNET_SENDPACKET;
698
699 IF_RF24ETHERNET_DEBUG_UDP(Serial.println(F("udp, uip_poll results in ARP-packet")););
700 RF24EthernetClass::network_send();
701 }
702 else
703 {
704 // arp found ethaddr for ip (otherwise packet is replaced by arp-request)
705 data->send = false;
706 data->packet_out = 0;
707 // RF24EthernetClass::packetstate |= UIPETHERNET_SENDPACKET;
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(""););
709
710 RF24NetworkHeader headerOut(00, EXTERNAL_DATA_TYPE);
711 RF24Ethernet.network.write(headerOut, uip_buf, data->out_pos + UIP_UDP_PHYH_LEN);
712 }
713
714 #elif USE_LWIP == 1
715 if (udpState == nullptr) {
716 udpState = new UDPState;
717 }
718 udpState->dataReceived = false;
719 udp_recv(udpPcb, receiveUdp, udpState);
720
721 pbuf* p = pbuf_alloc(PBUF_RAW, dataOutPos, PBUF_RAM);
722 if (p) {
723 memcpy(reinterpret_cast<uint8_t*>(p->payload), &udpDataOut[0], dataOutPos);
724 p->len = dataOutPos;
725
726 udp_send(udpPcb, p);
727
728 dataOutPos = 0;
729 Ethernet.update();
730
731 pbuf_free(p);
732 }
733
734 #elif USE_LWIP == 2
735
736 #endif
737}
738 /*******************************************************/
739
740 #endif // UIP_UDP
741#endif // UDP Enabled
#define uip_ip_addr(addr, ip)
#define ip_addr_uip(a)
RF24EthernetClass RF24Ethernet
#define UIP_ARPHDRSIZE
Definition RF24Udp.cpp:51
void uipudp_appcall(void)
Definition RF24Udp.cpp:611
#define UDPBUF
Definition RF24Udp.cpp:52
#define UIP_UDP_PHYH_LEN
Definition RF24Udp.h:33
static UDPState * udpState
Definition RF24Udp.h:55
void begin(const IPAddress &aDNSServer)
Definition Dns.cpp:45
int getHostByName(const char *aHostname, IPAddress &aResult)
Definition Dns.cpp:110
int endPacket()
Finish off this packet and send it.
Definition RF24Udp.cpp:326
void flush()
Definition RF24Udp.cpp:551
int read()
Definition RF24Udp.cpp:469
int parsePacket()
Definition RF24Udp.cpp:397
size_t write(uint8_t)
Write a single byte into the packet.
Definition RF24Udp.cpp:363
uint16_t remotePort()
Definition RF24Udp.cpp:591
IPAddress remoteIP()
Definition RF24Udp.cpp:567
RF24UDP()
Constructor.
Definition RF24Udp.cpp:63
void stop()
Finish with the UDP socket.
Definition RF24Udp.cpp:140
int peek()
Definition RF24Udp.cpp:528
int beginPacket(IPAddress ip, uint16_t port)
Sending UDP packets.
Definition RF24Udp.cpp:179
int available()
Definition RF24Udp.cpp:426
uint8_t begin(uint16_t)
initialize, start listening on specified port.
Definition RF24Udp.cpp:78
#define Ethernet
#define IF_RF24ETHERNET_DEBUG_UDP(x)
#define OUTPUT_BUFFER_SIZE
Definition uip-conf.h:153
volatile bool dataReceived
Definition RF24Udp.h:52
uint16_t u16_t
16 bit datatype
Definition uip-conf.h:245