Skip to content

Commit c115098

Browse files
committed
lwIpWrapper: CNetIf fix ping command
1 parent a74dfbd commit c115098

File tree

2 files changed

+68
-79
lines changed

2 files changed

+68
-79
lines changed

Diff for: libraries/lwIpWrapper/src/CNetIf.cpp

+64-75
Original file line numberDiff line numberDiff line change
@@ -18,30 +18,30 @@ bool CLwipIf::pending_eth_rx = false;
1818

1919
FspTimer CLwipIf::timer;
2020

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)
2222
{
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);
2827

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;
3429

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;
3633

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 */
3939
}
40-
pbuf_free(p);
41-
return 1;
40+
/* not eaten, restore original packet */
41+
pbuf_add_header(p, PBUF_IP_HLEN);
4242
}
4343

44-
return 0;
44+
return 0; /* don't eat the packet */
4545
}
4646

4747
ip_addr_t* u8_to_ip_addr(uint8_t* ipu8, ip_addr_t* ipaddr)
@@ -150,79 +150,68 @@ void CLwipIf::lwip_task()
150150
}
151151
}
152152

153+
153154
int CLwipIf::ping(IPAddress ip, uint8_t ttl)
154155
{
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) };
165161

166162
//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;
187166
}
188167

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);
195170

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;
197174

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);
200176
if (!p) {
201-
goto exit;
177+
raw_remove(s);
178+
return -1;
202179
}
203180

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;
206183

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);
210186

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;
219212
}
220213

221-
exit:
222-
pbuf_free(p);
223-
delete d;
224-
raw_remove(s);
225-
return result;
214+
return requestCbkData.endMillis - requestCbkData.startMillis;
226215
}
227216

228217
/* -------------------------------------------------------------------------- */

Diff for: libraries/lwIpWrapper/src/CNetIf.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,10 @@ ip_addr_t* u8_to_ip_addr(uint8_t* ipu8, ip_addr_t* ipaddr);
131131

132132
uint32_t ip_addr_to_u32(ip_addr_t* ipaddr);
133133

134-
struct ping_data{
135-
uint32_t endMillis;
136-
icmp_echo_hdr echo_req;
137-
struct raw_pcb* s;
134+
struct recv_callback_data{
135+
u32_t startMillis;
136+
u32_t endMillis;
137+
u16_t seqNum;
138138
};
139139

140140
/* Base class implements DHCP, derived class will switch it on or off */

0 commit comments

Comments
 (0)