@@ -18,30 +18,30 @@ bool CLwipIf::pending_eth_rx = false;
18
18
19
19
FspTimer CLwipIf::timer;
20
20
21
- u8_t icmp_receive_callback (void * arg, struct raw_pcb * pcb, struct pbuf * p, const ip_addr_t * addr)
21
+ static u8_t icmp_receive_callback (void * arg, struct raw_pcb * pcb, struct pbuf * p, const ip_addr_t * addr)
22
22
{
23
- struct ping_data *d = (struct ping_data *)arg;
24
- struct __attribute__ ((__packed__)) {
25
- struct ip_hdr ipHeader;
26
- struct icmp_echo_hdr header;
27
- } response;
23
+ struct icmp_echo_hdr *iecho;
24
+ (void )(pcb);
25
+ (void )(addr);
26
+ LWIP_ASSERT (" p != NULL" , p != NULL );
28
27
29
- if (d->s == pcb) {
30
- if (p->len < sizeof (response)) {
31
- pbuf_free (p);
32
- return 1 ;
33
- }
28
+ recv_callback_data* request = (recv_callback_data*)arg;
34
29
35
- pbuf_copy_partial (p, &response, sizeof (response), 0 );
30
+ if ((p->tot_len >= (PBUF_IP_HLEN + sizeof (struct icmp_echo_hdr ))) &&
31
+ pbuf_remove_header (p, PBUF_IP_HLEN) == 0 ) {
32
+ iecho = (struct icmp_echo_hdr *)p->payload ;
36
33
37
- if (response.header .id == d->echo_req .id && response.header .seqno == d->echo_req .seqno ) {
38
- d->endMillis = millis ();
34
+ if ((iecho->id == 0xAFAF ) && (iecho->seqno == lwip_htons (request->seqNum ))) {
35
+ /* do some ping result processing */
36
+ request->endMillis = millis ();
37
+ pbuf_free (p);
38
+ return 1 ; /* eat the packet */
39
39
}
40
- pbuf_free (p);
41
- return 1 ;
40
+ /* not eaten, restore original packet */
41
+ pbuf_add_header (p, PBUF_IP_HLEN) ;
42
42
}
43
43
44
- return 0 ;
44
+ return 0 ; /* don't eat the packet */
45
45
}
46
46
47
47
ip_addr_t * u8_to_ip_addr (uint8_t * ipu8, ip_addr_t * ipaddr)
@@ -150,79 +150,68 @@ void CLwipIf::lwip_task()
150
150
}
151
151
}
152
152
153
+
153
154
int CLwipIf::ping (IPAddress ip, uint8_t ttl)
154
155
{
155
- uint32_t result = -1 ;
156
- uint32_t timeout = 5000 ;
157
- uint32_t sendTime = 0 ;
158
- uint32_t startWait = 0 ;
159
- struct pbuf *p;
160
- struct raw_pcb * s;
161
- struct ping_data *d = new ping_data;
162
- if (!d){
163
- goto exit ;
164
- }
156
+ /* ttl is not supported. Default value used is 255 */
157
+ (void )ttl;
158
+ ip_addr_t addr;
159
+ addr.addr = ip;
160
+ recv_callback_data requestCbkData = { 0 , 0 , (uint16_t )random (0xffff ) };
165
161
166
162
// Create a raw socket
167
- s = raw_new (IP_PROTO_ICMP);
168
- if (!s) {
169
- goto exit ;
170
- }
171
-
172
- struct __attribute__ ((__packed__)) {
173
- struct icmp_echo_hdr header;
174
- uint8_t data[32 ];
175
- } request;
176
-
177
- ICMPH_TYPE_SET (&request.header , ICMP_ECHO);
178
- ICMPH_CODE_SET (&request.header , 0 );
179
- request.header .chksum = 0 ;
180
- request.header .id = 0xAFAF ;
181
- request.header .seqno = random (0xffff );
182
-
183
- d->echo_req = request.header ;
184
-
185
- for (size_t i = 0 ; i < sizeof (request.data ); i++) {
186
- request.data [i] = i;
163
+ struct raw_pcb * s = raw_new (IP_PROTO_ICMP);
164
+ if (!s) {
165
+ return -1 ;
187
166
}
188
167
189
- request.header .chksum = inet_chksum (&request, sizeof (request));
190
-
191
- ip_addr_t addr;
192
- addr.addr = ip;
193
-
194
- d->endMillis = 0 ;
168
+ raw_recv (s, icmp_receive_callback, (void *)&requestCbkData);
169
+ raw_bind (s, IP_ADDR_ANY);
195
170
196
- raw_recv (s, icmp_receive_callback, d);
171
+ struct pbuf *p;
172
+ struct icmp_echo_hdr *iecho;
173
+ size_t ping_size = sizeof (struct icmp_echo_hdr ) + 32 ;
197
174
198
- // Build the packet
199
- p = pbuf_alloc (PBUF_IP, sizeof (request), PBUF_RAM);
175
+ p = pbuf_alloc (PBUF_IP, (u16_t )ping_size, PBUF_RAM);
200
176
if (!p) {
201
- goto exit ;
177
+ raw_remove (s);
178
+ return -1 ;
202
179
}
203
180
204
- // Load payload into buffer
205
- pbuf_take (p, &request, sizeof (request)) ;
181
+ if ((p-> len == p-> tot_len ) && (p-> next == NULL )) {
182
+ iecho = ( struct icmp_echo_hdr *)p-> payload ;
206
183
207
- // Send the echo request
208
- sendTime = millis ();
209
- raw_sendto (s, p, &addr);
184
+ size_t i;
185
+ size_t data_len = ping_size - sizeof (struct icmp_echo_hdr );
210
186
211
- // Wait for response
212
- startWait = millis ();
213
- do {
214
- lwip_task ();
215
- } while (d->endMillis == 0 && (millis () - startWait) < timeout);
216
-
217
- if (d->endMillis != 0 ) {
218
- result = d->endMillis - sendTime;
187
+ ICMPH_TYPE_SET (iecho, ICMP_ECHO);
188
+ ICMPH_CODE_SET (iecho, 0 );
189
+ iecho->chksum = 0 ;
190
+ iecho->id = 0xAFAF ;
191
+ iecho->seqno = lwip_htons (requestCbkData.seqNum );
192
+
193
+ /* fill the additional data buffer with some data */
194
+ for (i = 0 ; i < data_len; i++) {
195
+ ((char *)iecho)[sizeof (struct icmp_echo_hdr ) + i] = (char )i;
196
+ }
197
+
198
+ iecho->chksum = inet_chksum (iecho, ping_size);
199
+ requestCbkData.startMillis = millis ();
200
+ raw_sendto (s, p, &addr);
201
+
202
+ }
203
+ pbuf_free (p);
204
+
205
+ bool timeout = false ;
206
+ while (!requestCbkData.endMillis && !timeout) {
207
+ timeout = (millis () - requestCbkData.startMillis ) > 5000 ;
208
+ }
209
+
210
+ if (timeout) {
211
+ return -1 ;
219
212
}
220
213
221
- exit :
222
- pbuf_free (p);
223
- delete d;
224
- raw_remove (s);
225
- return result;
214
+ return requestCbkData.endMillis - requestCbkData.startMillis ;
226
215
}
227
216
228
217
/* -------------------------------------------------------------------------- */
0 commit comments