1
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
40
41
42
43
44
45
54
55
56
60
61
62
63
65
66
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
228
229
230
231
238
239
240
247
248
249
256
257
258
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
295
296
297
298
299
300
301
302
303
304
305
310
311
/* ... */
/* ... */
/* ... */
#include "lwip/opt.h"
#if LWIP_IPV4 && LWIP_RAW
#include "ping/ping.h"
#include "lwip/mem.h"
#include "lwip/raw.h"
#include "lwip/icmp.h"
#include "lwip/netif.h"
#include "lwip/sys.h"
#include "lwip/timeouts.h"
#include "lwip/inet_chksum.h"8 includes
#if PING_USE_SOCKETS
#include "lwip/sockets.h"
#include "lwip/inet.h"
#include "esp_task.h"
#include "ping/ping_sock.h"/* ... */
#endif
#ifdef ESP_PING
#include "esp_ping.h"
#include "lwip/ip_addr.h"/* ... */
#endif
/* ... */
#ifndef PING_DEBUG
#define PING_DEBUG LWIP_DBG_OFF
#endif
#ifndef PING_TARGET
#define PING_TARGET (netif_default ? *netif_ip4_gw(netif_default) : (*IP4_ADDR_ANY))
#endif
#ifndef PING_RCV_TIMEO
#define PING_RCV_TIMEO 1000
#endif
#ifndef PING_DELAY
#define PING_DELAY 1000
#endif
#ifndef PING_ID
#define PING_ID 0xAFAF
#endif
#ifndef PING_DATA_SIZE
#define PING_DATA_SIZE 32
#endif
#ifndef PING_RESULT
#define PING_RESULT(ping_ok)
#endif
#define PING_TIME_DIFF_MS(_end, _start) ((uint32_t)(((_end).tv_sec - (_start).tv_sec) * 1000 + (_end.tv_usec - _start.tv_usec)/1000))
#define PING_TIME_DIFF_SEC(_end, _start) ((uint32_t)((_end).tv_sec - (_start).tv_sec))
#if PING_USE_SOCKETS
static esp_ping_handle_t ping = NULL;/* ... */
#else
static struct raw_pcb *ping_pcb;
static u16_t ping_seq_num;
static struct timeval ping_time;
static void
ping_prepare_echo( struct icmp_echo_hdr *iecho, u16_t len)
{
size_t i;
size_t data_len = len - sizeof(struct icmp_echo_hdr);
ICMPH_TYPE_SET(iecho, ICMP_ECHO);
ICMPH_CODE_SET(iecho, 0);
iecho->chksum = 0;
iecho->id = PING_ID;
iecho->seqno = htons(++ping_seq_num);
for(i = 0; i < data_len; i++) {
((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i;
}{...}
iecho->chksum = inet_chksum(iecho, len);
}{...}
static u8_t
ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *addr)
{
struct icmp_echo_hdr *iecho;
struct timeval now;
LWIP_UNUSED_ARG(arg);
LWIP_UNUSED_ARG(pcb);
LWIP_UNUSED_ARG(addr);
LWIP_ASSERT("p != NULL", p != NULL);
if ((p->tot_len >= (PBUF_IP_HLEN + sizeof(struct icmp_echo_hdr))) &&
pbuf_header(p, -PBUF_IP_HLEN) == 0) {
iecho = (struct icmp_echo_hdr *)p->payload;
if ((iecho->id == PING_ID) && (iecho->seqno == htons(ping_seq_num))) {
LWIP_DEBUGF( PING_DEBUG, ("ping: recv "));
ip_addr_debug_print(PING_DEBUG, addr);
gettimeofday(&now, NULL);
LWIP_DEBUGF( PING_DEBUG, (" %"U32_F" ms\n", PING_TIME_DIFF_MS(now, ping_time)));
PING_RESULT(1);
pbuf_free(p);
return 1;
}{...}
pbuf_header(p, PBUF_IP_HLEN);
}{...}
return 0;
}{...}
static void
ping_send(struct raw_pcb *raw, ip_addr_t *addr)
{
struct pbuf *p;
struct icmp_echo_hdr *iecho;
size_t ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE;
LWIP_DEBUGF( PING_DEBUG, ("ping: send "));
ip_addr_debug_print(PING_DEBUG, addr);
LWIP_DEBUGF( PING_DEBUG, ("\n"));
LWIP_ASSERT("ping_size <= 0xffff", ping_size <= 0xffff);
p = pbuf_alloc(PBUF_IP, (u16_t)ping_size, PBUF_RAM);
if (!p) {
return;
}{...}
if ((p->len == p->tot_len) && (p->next == NULL)) {
iecho = (struct icmp_echo_hdr *)p->payload;
ping_prepare_echo(iecho, (u16_t)ping_size);
raw_sendto(raw, p, addr);
ping_time = system_get_time();
}{...}
pbuf_free(p);
}{...}
static void
ping_timeout(void *arg)
{
struct raw_pcb *pcb = (struct raw_pcb*)arg;
ip_addr_t ping_target;
LWIP_ASSERT("ping_timeout: no pcb given!", pcb != NULL);
ip_addr_copy_from_ip4(ping_target, PING_TARGET);
ping_send(pcb, &ping_target);
sys_timeout(PING_DELAY, ping_timeout, pcb);
}{...}
static void
ping_raw_init(void)
{
ping_pcb = raw_new(IP_PROTO_ICMP);
LWIP_ASSERT("ping_pcb != NULL", ping_pcb != NULL);
raw_recv(ping_pcb, ping_recv, NULL);
raw_bind(ping_pcb, IP_ADDR_ANY);
sys_timeout(PING_DELAY, ping_timeout, ping_pcb);
}{...}
void
ping_send_now(void)
{
ip_addr_t ping_target;
LWIP_ASSERT("ping_pcb != NULL", ping_pcb != NULL);
ip_addr_copy_from_ip4(ping_target, PING_TARGET);
ping_send(ping_pcb, &ping_target);
}{...}
/* ... */
#endif
/* ... */
static void
on_ping_success(esp_ping_handle_t hdl, void *args)
{
uint32_t elapsed_time, recv_len;
esp_ping_get_profile(hdl, ESP_PING_PROF_SIZE, &recv_len, sizeof(recv_len));
esp_ping_get_profile(hdl, ESP_PING_PROF_TIMEGAP, &elapsed_time, sizeof(elapsed_time));
esp_ping_result(PING_RES_OK, recv_len, elapsed_time);
}{ ... }
static void
on_ping_timeout(esp_ping_handle_t hdl, void *args)
{
uint32_t elapsed_time, recv_len;
esp_ping_get_profile(hdl, ESP_PING_PROF_SIZE, &recv_len, sizeof(recv_len));
esp_ping_get_profile(hdl, ESP_PING_PROF_TIMEGAP, &elapsed_time, sizeof(elapsed_time));
esp_ping_result(PING_RES_TIMEOUT, recv_len, elapsed_time);
}{ ... }
static void
on_ping_end(esp_ping_handle_t hdl, void *args)
{
esp_ping_result(PING_RES_FINISH, 0, 0);
esp_ping_delete_session(hdl);
}{ ... }
int
ping_init(void)
{
#if PING_USE_SOCKETS
uint32_t tos = 0;
uint32_t ping_timeout = PING_RCV_TIMEO;
uint32_t ping_delay = PING_DELAY;
uint32_t ping_count_max = 3;
uint32_t interface = 0;
ip_addr_t ipaddr;
esp_ping_get_target(PING_TARGET_IP_ADDRESS_COUNT, &ping_count_max, sizeof(ping_count_max));
esp_ping_get_target(PING_TARGET_RCV_TIMEO, &ping_timeout, sizeof(ping_timeout));
esp_ping_get_target(PING_TARGET_DELAY_TIME, &ping_delay, sizeof(ping_delay));
esp_ping_get_target(PING_TARGET_IP_ADDRESS, &ipaddr, sizeof(ip_addr_t));
esp_ping_get_target(PING_TARGET_IP_TOS, &tos, sizeof(tos));
esp_ping_get_target(PING_TARGET_IF_INDEX, &interface, sizeof(interface));
esp_ping_config_t config = ESP_PING_DEFAULT_CONFIG();
config.count = ping_count_max;
config.timeout_ms = ping_timeout;
config.interval_ms = ping_delay;
config.target_addr = ipaddr;
config.tos = tos;
config.interface = interface;
esp_ping_callbacks_t cbs = {
.on_ping_end = on_ping_end,
.on_ping_success = on_ping_success,
.on_ping_timeout = on_ping_timeout,
}{...};
esp_ping_new_session(&config, &cbs, &ping);
esp_ping_start(ping);/* ... */
#else
ping_raw_init();
#endif
return ERR_OK;
}{ ... }
void
ping_deinit(void)
{
esp_ping_stop(ping);
esp_ping_delete_session(ping);
}{ ... }
/* ... */#endif