55
66#include " lwip/include/lwip/igmp.h"
77#include " lwip/include/lwip/ip_addr.h"
8+ #include " utils.h"
9+ #include " lwippbuf.h"
810
911#if LWIP_UDP
1012/* *
@@ -25,12 +27,13 @@ void udp_receive_callback(void* arg, struct udp_pcb* pcb, struct pbuf* p,
2527 /* Send data to the application layer */
2628 if ((udp_arg != NULL ) && (udp_arg->pcb == pcb)) {
2729 // Free the old p buffer if not read
28- if (udp_arg->data .p != NULL ) {
29- pbuf_free (udp_arg->data .p );
30+ if (udp_arg->p != NULL ) {
31+ pbuf_free (udp_arg->p );
32+ udp_arg->p = NULL ;
3033 }
3134
32- udp_arg->data . p = p;
33- udp_arg->data . available = p-> len ;
35+ udp_arg->p = p;
36+ udp_arg->pbuf_offset = 0 ;
3437
3538 ip_addr_copy (udp_arg->ip , *addr);
3639 udp_arg->port = port;
@@ -64,7 +67,8 @@ uint8_t lwipUDP::begin(IPAddress ip, uint16_t port, bool multicast)
6467
6568 ip_addr_t ipaddr;
6669 err_t err;
67- // u8_to_ip_addr(rawIPAddress(ip), &ipaddr); // FIXME
70+ ipaddr = fromArduinoIP (ip);
71+
6872 if (multicast) {
6973 err = udp_bind (_udp.pcb , IP_ADDR_ANY, port);
7074 } else {
@@ -86,7 +90,7 @@ uint8_t lwipUDP::begin(IPAddress ip, uint16_t port, bool multicast)
8690 _port = port;
8791 _remaining = 0 ;
8892
89- // CLwipIf::getInstance().lwip_task ();
93+ CLwipIf::getInstance ().task ();
9094
9195 return 1 ;
9296}
@@ -107,7 +111,7 @@ void lwipUDP::stop()
107111 _udp.pcb = NULL ;
108112 }
109113
110- // CLwipIf::getInstance().lwip_task ();
114+ CLwipIf::getInstance ().task ();
111115}
112116
113117int lwipUDP::beginPacket (const char * host, uint16_t port)
@@ -135,7 +139,7 @@ int lwipUDP::beginPacket(IPAddress ip, uint16_t port)
135139 _sendtoPort = port;
136140
137141 udp_recv (_udp.pcb , &udp_receive_callback, &_udp);
138- // CLwipIf::getInstance().lwip_task ();
142+ CLwipIf::getInstance ().task ();
139143
140144 return 1 ;
141145}
@@ -145,18 +149,24 @@ int lwipUDP::endPacket()
145149 if ((_udp.pcb == NULL ) || (_data == NULL )) {
146150 return 0 ;
147151 }
148-
149- ip_addr_t ipaddr;
150- // if (ERR_OK != udp_sendto(_udp.pcb, _data, u8_to_ip_addr(rawIPAddress(_sendtoIP), &ipaddr), _sendtoPort)) {
151- // __disable_irq();
152- // _data = pbuffer_free_data(_data);
153- // __enable_irq();
154- // return 0;
155- // }
152+ /*
153+ * FIXME in this way, the derived classes for wifi and ethernet won't send data through the correct iface
154+ * the solution to this issue is by using udp_sendto_if, by this needs further rework
155+ */
156+ ip_addr_t ipaddr = fromArduinoIP (_sendtoIP);
157+ if (ERR_OK != udp_sendto (
158+ _udp.pcb , _data,
159+ &ipaddr,
160+ _sendtoPort)) {
161+ __disable_irq ();
162+ pbuf_free (_data);
163+ __enable_irq ();
164+ return 0 ;
165+ }
156166
157167 _data = NULL ;
158168
159- // CLwipIf::getInstance().lwip_task ();
169+ CLwipIf::getInstance ().task ();
160170
161171 return 1 ;
162172}
@@ -169,11 +179,20 @@ size_t lwipUDP::write(uint8_t byte)
169179size_t lwipUDP::write (const uint8_t * buffer, size_t size)
170180{
171181 __disable_irq ();
172- _data = pbuffer_put_data (_data, buffer, size );
173- __enable_irq ();
174- if (_data == NULL ) {
182+ struct pbuf *p = pbuf_alloc (PBUF_TRANSPORT, size, PBUF_RAM );
183+
184+ if (p == NULL ) {
175185 return 0 ;
176186 }
187+ pbuf_take (p, buffer, size);
188+
189+ if (_data == NULL ) {
190+ _data = p;
191+ } else {
192+ // no need to increment the reference count of the pbuf, since it is already 1
193+ pbuf_cat (_data, p);
194+ }
195+ __enable_irq ();
177196
178197 return size;
179198}
@@ -188,12 +207,12 @@ int lwipUDP::parsePacket()
188207 // read();
189208 // }
190209
191- // CLwipIf::getInstance().lwip_task ();
210+ CLwipIf::getInstance ().task ();
192211
193- if (_udp.data . available > 0 ) {
194- // _remoteIP = IPAddress(ip_addr_to_u32(&( _udp.ip))); // FIXME
212+ if (_udp.p == nullptr ? 0 : _udp. p -> tot_len ) {
213+ _remoteIP = toArduinoIP (& _udp.ip );
195214 _remotePort = _udp.port ;
196- _remaining = _udp.data . available ;
215+ _remaining = _udp.p -> tot_len ;
197216
198217 return _remaining;
199218 }
@@ -205,7 +224,7 @@ int lwipUDP::read()
205224{
206225 uint8_t byte;
207226
208- if (_udp.data . p == NULL ) {
227+ if (_udp.p == NULL ) {
209228 return -1 ;
210229 }
211230
@@ -221,25 +240,19 @@ int lwipUDP::read()
221240
222241int lwipUDP::read (unsigned char * buffer, size_t len)
223242{
224- if (_udp.data . p == NULL ) {
243+ if (_udp.p == NULL ) {
225244 return -1 ;
226245 }
227246
228247 if (_remaining > 0 ) {
229- int got;
230-
231- if (_remaining <= len) {
232- // data should fit in the buffer
233- __disable_irq ();
234- got = (int )pbuffer_get_data (&(_udp.data ), (uint8_t *)buffer, _remaining);
235- __enable_irq ();
236- } else {
237- // too much data for the buffer,
238- // grab as much as will fit
239- __disable_irq ();
240- got = (int )pbuffer_get_data (&(_udp.data ), (uint8_t *)buffer, len);
241- __enable_irq ();
242- }
248+ __disable_irq ();
249+ int got = pbuf_copy_partial (
250+ _udp.p ,
251+ buffer,
252+ _remaining < len ? _remaining : len, _udp.pbuf_offset );
253+
254+ _udp.p = free_pbuf_chain (_udp.p , got, &_udp.pbuf_offset );
255+ __enable_irq ();
243256
244257 if (got > 0 ) {
245258 _remaining -= got;
@@ -260,7 +273,7 @@ int lwipUDP::peek()
260273 if (!_remaining) {
261274 return -1 ;
262275 }
263- b = pbuf_get_at (_udp.data . p , 0 );
276+ b = pbuf_get_at (_udp.p , 0 );
264277 return b;
265278}
266279
0 commit comments