5
5
6
6
#include " lwip/include/lwip/igmp.h"
7
7
#include " lwip/include/lwip/ip_addr.h"
8
+ #include " utils.h"
9
+ #include " lwippbuf.h"
8
10
9
11
#if LWIP_UDP
10
12
/* *
@@ -25,12 +27,13 @@ void udp_receive_callback(void* arg, struct udp_pcb* pcb, struct pbuf* p,
25
27
/* Send data to the application layer */
26
28
if ((udp_arg != NULL ) && (udp_arg->pcb == pcb)) {
27
29
// 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 ;
30
33
}
31
34
32
- udp_arg->data . p = p;
33
- udp_arg->data . available = p-> len ;
35
+ udp_arg->p = p;
36
+ udp_arg->pbuf_offset = 0 ;
34
37
35
38
ip_addr_copy (udp_arg->ip , *addr);
36
39
udp_arg->port = port;
@@ -64,7 +67,8 @@ uint8_t lwipUDP::begin(IPAddress ip, uint16_t port, bool multicast)
64
67
65
68
ip_addr_t ipaddr;
66
69
err_t err;
67
- // u8_to_ip_addr(rawIPAddress(ip), &ipaddr); // FIXME
70
+ ipaddr = fromArduinoIP (ip);
71
+
68
72
if (multicast) {
69
73
err = udp_bind (_udp.pcb , IP_ADDR_ANY, port);
70
74
} else {
@@ -86,7 +90,7 @@ uint8_t lwipUDP::begin(IPAddress ip, uint16_t port, bool multicast)
86
90
_port = port;
87
91
_remaining = 0 ;
88
92
89
- // CLwipIf::getInstance().lwip_task ();
93
+ CLwipIf::getInstance ().task ();
90
94
91
95
return 1 ;
92
96
}
@@ -107,7 +111,7 @@ void lwipUDP::stop()
107
111
_udp.pcb = NULL ;
108
112
}
109
113
110
- // CLwipIf::getInstance().lwip_task ();
114
+ CLwipIf::getInstance ().task ();
111
115
}
112
116
113
117
int lwipUDP::beginPacket (const char * host, uint16_t port)
@@ -135,7 +139,7 @@ int lwipUDP::beginPacket(IPAddress ip, uint16_t port)
135
139
_sendtoPort = port;
136
140
137
141
udp_recv (_udp.pcb , &udp_receive_callback, &_udp);
138
- // CLwipIf::getInstance().lwip_task ();
142
+ CLwipIf::getInstance ().task ();
139
143
140
144
return 1 ;
141
145
}
@@ -145,18 +149,24 @@ int lwipUDP::endPacket()
145
149
if ((_udp.pcb == NULL ) || (_data == NULL )) {
146
150
return 0 ;
147
151
}
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
+ }
156
166
157
167
_data = NULL ;
158
168
159
- // CLwipIf::getInstance().lwip_task ();
169
+ CLwipIf::getInstance ().task ();
160
170
161
171
return 1 ;
162
172
}
@@ -169,11 +179,20 @@ size_t lwipUDP::write(uint8_t byte)
169
179
size_t lwipUDP::write (const uint8_t * buffer, size_t size)
170
180
{
171
181
__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 ) {
175
185
return 0 ;
176
186
}
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 ();
177
196
178
197
return size;
179
198
}
@@ -188,12 +207,12 @@ int lwipUDP::parsePacket()
188
207
// read();
189
208
// }
190
209
191
- // CLwipIf::getInstance().lwip_task ();
210
+ CLwipIf::getInstance ().task ();
192
211
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 );
195
214
_remotePort = _udp.port ;
196
- _remaining = _udp.data . available ;
215
+ _remaining = _udp.p -> tot_len ;
197
216
198
217
return _remaining;
199
218
}
@@ -205,7 +224,7 @@ int lwipUDP::read()
205
224
{
206
225
uint8_t byte;
207
226
208
- if (_udp.data . p == NULL ) {
227
+ if (_udp.p == NULL ) {
209
228
return -1 ;
210
229
}
211
230
@@ -221,25 +240,19 @@ int lwipUDP::read()
221
240
222
241
int lwipUDP::read (unsigned char * buffer, size_t len)
223
242
{
224
- if (_udp.data . p == NULL ) {
243
+ if (_udp.p == NULL ) {
225
244
return -1 ;
226
245
}
227
246
228
247
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 ();
243
256
244
257
if (got > 0 ) {
245
258
_remaining -= got;
@@ -260,7 +273,7 @@ int lwipUDP::peek()
260
273
if (!_remaining) {
261
274
return -1 ;
262
275
}
263
- b = pbuf_get_at (_udp.data . p , 0 );
276
+ b = pbuf_get_at (_udp.p , 0 );
264
277
return b;
265
278
}
266
279
0 commit comments