@@ -18,30 +18,30 @@ bool CLwipIf::pending_eth_rx = false;
1818
1919FspTimer 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
4747ip_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+
153154int 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/* -------------------------------------------------------------------------- */
0 commit comments