ping: refactor with new esp_ping_xxx APIs

This refactor is only for backwards compatible.
This commit is contained in:
suda-morris 2019-10-17 14:26:05 +08:00 committed by bot
parent a77e69c408
commit fa32a4bd93
12 changed files with 91 additions and 518 deletions

View file

@ -128,7 +128,7 @@ esp_err_t esp_ping_get_target(ping_target_id_t opt_id, void *opt_val, uint32_t o
return ret;
}
esp_err_t esp_ping_result(uint8_t res_val, uint16_t ping_len, uint32_t ping_time, uint32_t seqno)
esp_err_t esp_ping_result(uint8_t res_val, uint16_t ping_len, uint32_t ping_time)
{
esp_err_t ret = ESP_OK;
@ -154,7 +154,6 @@ esp_err_t esp_ping_result(uint8_t res_val, uint16_t ping_len, uint32_t ping_time
ping_option_info->ping_res.total_time += ping_time;
ping_option_info->ping_res.recv_count ++;
ping_option_info->ping_res.ping_seqno = seqno;
}
}

View file

@ -5,7 +5,7 @@
*/
/*
* Redistribution and use in source and binary forms, with or without modification,
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
@ -14,24 +14,24 @@
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
*
*/
/**
/**
* This is an example of a "ping" sender (with raw API and socket API).
* It can be used as a start point to maintain opened a network connection, or
* like a network "watchdog" for your device.
@ -55,6 +55,7 @@
#if PING_USE_SOCKETS
#include "lwip/sockets.h"
#include "lwip/inet.h"
#include "ping/ping_sock.h"
#endif /* PING_USE_SOCKETS */
#ifdef ESP_PING
@ -98,20 +99,17 @@
#define PING_RESULT(ping_ok)
#endif
/* ping variables */
static u16_t ping_seq_num;
static struct timeval ping_time;
#if ESP_PING
static sys_sem_t ping_sem = NULL;
static bool ping_init_flag = false;
#endif
#if !PING_USE_SOCKETS
static struct raw_pcb *ping_pcb;
#endif /* PING_USE_SOCKETS */
#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
/* ping handle */
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;
/** Prepare a echo ICMP request */
static void
ping_prepare_echo( struct icmp_echo_hdr *iecho, u16_t len)
@ -133,213 +131,6 @@ ping_prepare_echo( struct icmp_echo_hdr *iecho, u16_t len)
iecho->chksum = inet_chksum(iecho, len);
}
#if PING_USE_SOCKETS
/* Ping using the socket ip */
static err_t
ping_send(int s, ip_addr_t *addr)
{
int err;
struct icmp_echo_hdr *iecho;
struct sockaddr_in to;
size_t ping_size;
#ifdef ESP_PING
size_t ping_data_len = 0;
esp_ping_get_target(PING_TARGET_DATA_LEN, &ping_data_len, sizeof(ping_data_len));
if (ping_data_len > 0) {
ping_size = sizeof(struct icmp_echo_hdr) + ping_data_len;
} else {
ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE;
}
#else
ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE;
#endif
LWIP_ASSERT("ping_size is too big", ping_size <= 0xffff);
LWIP_ASSERT("ping: expect IPv4 address", !IP_IS_V6(addr));
iecho = (struct icmp_echo_hdr *)mem_malloc((mem_size_t)ping_size);
if (!iecho) {
return ERR_MEM;
}
ping_prepare_echo(iecho, (u16_t)ping_size);
to.sin_len = sizeof(to);
to.sin_family = AF_INET;
inet_addr_from_ip4addr(&to.sin_addr, ip_2_ip4(addr));
err = sendto(s, iecho, ping_size, 0, (struct sockaddr*)&to, sizeof(to));
mem_free(iecho);
return (err ? ERR_OK : ERR_VAL);
}
static void
ping_recv(int s)
{
char buf[64];
int len;
struct sockaddr_in from;
struct ip_hdr *iphdr;
struct icmp_echo_hdr *iecho;
int fromlen = sizeof(from);
struct timeval now;
while((len = recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr*)&from, (socklen_t*)&fromlen)) > 0) {
if (len >= (int)(sizeof(struct ip_hdr)+sizeof(struct icmp_echo_hdr))) {
if (from.sin_family != AF_INET) {
/* Ping is not IPv4 */
LWIP_DEBUGF( PING_DEBUG, ("ping: invalid sin_family\n"));
} else {
ip4_addr_t fromaddr;
inet_addr_to_ip4addr(&fromaddr, &from.sin_addr);
iphdr = (struct ip_hdr *)buf;
iecho = (struct icmp_echo_hdr *)(buf + (IPH_HL(iphdr) * 4));
LWIP_DEBUGF( PING_DEBUG, ("ping: recv seq=%d ", ntohs(iecho->seqno)));
ip4_addr_debug_print(PING_DEBUG, &fromaddr);
gettimeofday(&now, NULL);
LWIP_DEBUGF( PING_DEBUG, (" %"U32_F" ms\n", PING_TIME_DIFF_MS(now, ping_time)));
if ((iecho->id == PING_ID) && (iecho->seqno == htons(ping_seq_num))) {
/* do some ping result processing */
#ifdef ESP_PING
esp_ping_result((ICMPH_TYPE(iecho) == ICMP_ER), len, PING_TIME_DIFF_MS(now, ping_time), ntohs(iecho->seqno));
#else
PING_RESULT((ICMPH_TYPE(iecho) == ICMP_ER));
#endif
return;
} else {
LWIP_DEBUGF( PING_DEBUG, ("ping: drop\n"));
}
}
}
fromlen = sizeof(from);
}
gettimeofday(&now, NULL);
if (len == 0) {
LWIP_DEBUGF( PING_DEBUG, ("ping: recv - %"U32_F" ms - timeout\n", PING_TIME_DIFF_MS(now, ping_time)));
}
/* do some ping result processing */
#ifdef ESP_PING
esp_ping_result(0, len, PING_TIME_DIFF_MS(now, ping_time),0);
#else
PING_RESULT(0);
#endif
}
static void
ping_thread(void *arg)
{
uint32_t ping_timeout = PING_RCV_TIMEO;
uint32_t ping_delay = PING_DELAY;
ip_addr_t ping_target;
int ret;
int s;
#ifdef ESP_PING
uint32_t ping_count_cur = 0;
uint32_t ping_count_max = 3;
ip4_addr_t ipaddr;
int lev;
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.addr, sizeof(uint32_t));
ip_addr_copy_from_ip4(ping_target, ipaddr);
#else
ip_addr_copy_from_ip4(ping_target, PING_TARGET);
#endif
#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD
int timeout = ping_timeout;
#else
struct timeval timeout;
timeout.tv_sec = ping_timeout/1000;
timeout.tv_usec = (ping_timeout%1000)*1000;
#endif
LWIP_UNUSED_ARG(arg);
if ((s = socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0) {
goto _exit_new_socket_failed;
}
ret = setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
LWIP_ASSERT("setting receive timeout failed", ret == 0);
LWIP_UNUSED_ARG(ret);
#ifdef ESP_PING
int tos = 0;
esp_ping_get_target(PING_TARGET_IP_TOS, &tos, sizeof(int));
if (tos > 0) {
tos <<= 5;
ret = setsockopt(s, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
LWIP_ASSERT("setting IP_TOS failed", ret == 0);
LWIP_UNUSED_ARG(ret);
}
#endif
while (1) {
#ifdef ESP_PING
if (ping_count_cur++ >= ping_count_max) {
goto _exit;
}
if (ping_init_flag == false) {
goto _exit;
}
#endif
if (ping_send(s, &ping_target) == ERR_OK) {
LWIP_DEBUGF( PING_DEBUG, ("ping: send seq=%d ", ping_seq_num));
ip_addr_debug_print(PING_DEBUG, &ping_target);
LWIP_DEBUGF( PING_DEBUG, ("\n"));
gettimeofday(&ping_time, NULL);
ping_recv(s);
} else {
LWIP_DEBUGF( PING_DEBUG, ("ping: send "));
ip_addr_debug_print(PING_DEBUG, &ping_target);
LWIP_DEBUGF( PING_DEBUG, (" - error\n"));
}
sys_msleep(ping_delay);
}
#ifdef ESP_PING
_exit:
close(s);
_exit_new_socket_failed:
esp_ping_result(PING_RES_FINISH, 0, 0, 0);
SYS_ARCH_PROTECT(lev);
if (ping_init_flag) { /* Ping closed by this thread */
LWIP_DEBUGF( PING_DEBUG, ("ping: closed by self "));
if (ping_sem) {
sys_sem_free(&ping_sem);
}
ping_sem = NULL;
ping_init_flag = false;
SYS_ARCH_UNPROTECT(lev);
} else { /* Ping closed by task calls ping_deinit */
LWIP_DEBUGF( PING_DEBUG, ("ping: closed by other"));
SYS_ARCH_UNPROTECT(lev);
if (ping_sem) {
sys_sem_signal(&ping_sem);
}
}
vTaskDelete(NULL);
#endif
}
#else /* PING_USE_SOCKETS */
/* Ping using the raw ip */
static u8_t
ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *addr)
@ -436,27 +227,72 @@ ping_send_now(void)
#endif /* PING_USE_SOCKETS */
/**
*
* Re-implement ping_init and ping_deinit with the APIs from ping_sock.h for back-ward compatibility sake.
* It's highly recommended that users should use the new APIs from ping_sock.h.
* ToDo: ping.h and esp_ping.h are deprecated now and should be removed in idf v5.x.
*
*/
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)
{
int ret;
int lev;
SYS_ARCH_PROTECT(lev);
if (ping_init_flag) {
SYS_ARCH_UNPROTECT(lev);
/* Currently we only support one ping, call ping_deinit to kill the running ping before start new ping */
return ERR_INPROGRESS;
}
ret = sys_sem_new(&ping_sem, 0);
if (ERR_OK != ret) {
SYS_ARCH_UNPROTECT(lev);
return ERR_MEM;
}
ping_init_flag = true;
SYS_ARCH_UNPROTECT(lev);
#if PING_USE_SOCKETS
sys_thread_new("ping_thread", ping_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
uint32_t tos = 0;
uint32_t ping_timeout = PING_RCV_TIMEO;
uint32_t ping_delay = PING_DELAY;
uint32_t ping_count_max = 3;
ip_addr_t ping_target;
ip4_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.addr, sizeof(uint32_t));
esp_ping_get_target(PING_TARGET_IP_TOS, &tos, sizeof(tos));
ip_addr_copy_from_ip4(ping_target, ipaddr);
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 = ping_target;
config.tos = tos;
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_USE_SOCKETS */
ping_raw_init();
#endif /* PING_USE_SOCKETS */
@ -466,24 +302,8 @@ ping_init(void)
void
ping_deinit(void)
{
int lev;
SYS_ARCH_PROTECT(lev);
if (ping_init_flag == false) {
SYS_ARCH_UNPROTECT(lev);
return;
}
ping_init_flag = false;
SYS_ARCH_UNPROTECT(lev);
if (ping_sem) {
sys_sem_wait(&ping_sem);
SYS_ARCH_PROTECT(lev);
sys_sem_free(&ping_sem);
ping_sem = NULL;
SYS_ARCH_UNPROTECT(lev);
}
esp_ping_stop(ping);
esp_ping_delete_session(ping);
}
#endif /* LWIP_IPV4 && LWIP_RAW */

View file

@ -42,7 +42,6 @@ typedef struct _ping_found {
uint32_t total_time;
uint32_t min_time;
uint32_t max_time;
uint32_t ping_seqno;
int8_t ping_err;
} esp_ping_found;
@ -60,7 +59,7 @@ typedef enum {
typedef enum {
PING_RES_TIMEOUT = 0,
PING_RES_OK = 1,
PING_RES_OK = 1,
PING_RES_FINISH = 2,
} ping_res_t;
@ -103,7 +102,7 @@ esp_err_t esp_ping_get_target(ping_target_id_t opt_id, void *opt_val, uint32_t o
* - ESP_OK
* - ESP_ERR_PING_INVALID_PARAMS
*/
esp_err_t esp_ping_result(uint8_t res_val, uint16_t res_len, uint32_t res_time, uint32_t seqno);
esp_err_t esp_ping_result(uint8_t res_val, uint16_t res_len, uint32_t res_time);
#ifdef __cplusplus
}

View file

@ -43,10 +43,10 @@ extern "C" {
#endif
int ping_init(void);
int ping_init(void) __attribute__ ((deprecated));
#ifdef ESP_PING
void ping_deinit(void);
void ping_deinit(void) __attribute__ ((deprecated));
#endif
#if !PING_USE_SOCKETS

View file

@ -100,30 +100,6 @@ Type 'help' to get the list of commands.
Use UP/DOWN arrows to navigate through command history.
Press TAB when typing command name to auto-complete.
[esp32]>
ping <IP address>
Send an ICMP message to an IPv4/IPv6 address
<IPv4/IPv6> Target IP Address
-c, --count=<n> Number of messages
-t, --timeout=<t> Connection timeout, ms
-d, --delay=<t> Delay between messges, ms
-s, --size=<n> Packet data size, bytes
--tos=<n> Type of service
esp32>
esp32> ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 32(60) bytes of data.
60 bytes from 192.168.1.1: icmp_seq=1 time=13 ms
60 bytes from 192.168.1.1: icmp_seq=2 time=11 ms
60 bytes from 192.168.1.1: icmp_seq=3 time=7 ms
60 bytes from 192.168.1.1: icmp_seq=4 time=13 ms
60 bytes from 192.168.1.1: icmp_seq=5 time=25 ms
--- 192.168.1.1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 69ms
rtt min/avg/max = 7/13.80/25 ms
esp32>
```

View file

@ -1,4 +1,3 @@
idf_component_register(SRCS "cmd_wifi.c"
"console_example_main.c"
"cmd_ping.c"
INCLUDE_DIRS ".")

View file

@ -14,7 +14,6 @@ extern "C" {
#include "cmd_system.h"
#include "cmd_wifi.h"
#include "cmd_ping.h"
#include "cmd_nvs.h"
#ifdef __cplusplus

View file

@ -1,194 +0,0 @@
/* Console example — WiFi commands
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <string.h>
#include "esp_log.h"
#include "esp_console.h"
#include "argtable3/argtable3.h"
#include "cmd_decl.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "tcpip_adapter.h"
#include "esp_event.h"
#include "cmd_wifi.h"
#include "cmd_ping.h"
#include "lwip/inet.h"
#include <netinet/in.h>
#include "esp_ping.h"
#include "ping/ping.h"
#define DEFAULT_COUNT (5)
#define DEFAULT_TIMEOUT (1000) // unit = ms
#define DEFAULT_DELAY (500) // unit = ms
#define DEFAULT_DATA_SIZE (32) // bytes
#define FAILURE (-1)
extern volatile bool is_connected;
/** Arguments used by 'send_icmp' function */
static struct {
struct arg_str *ip_address;
struct arg_int *count;
struct arg_int *timeout;
struct arg_int *delay;
struct arg_int *packet_size;
struct arg_int *tos;
struct arg_end *end;
} ping_args;
static bool parse_ip_address(const char *address, ip4_addr_t *ipv4, ip6_addr_t *ipv6)
{
// Determine if the address is IPv4 or IPv6
char *indicator = (char *) malloc(strlen(address));
strcpy(indicator, address);
while(*indicator++)
{
if (*indicator == '.') {
return inet_aton(address, ipv4);
}
else if (*indicator == ':') {
return inet6_aton(address, &ipv6);
}
}
return false;
}
static esp_err_t parse_args(ip4_addr_t *ip4, ip6_addr_t *ip6, uint32_t *count, uint32_t *timeout,
uint32_t *delay, uint32_t *packet_size, uint32_t *tos)
{
if (ping_args.ip_address->count > 0)
{
// Parse IP address (Handle v4 and v6)
bool rc = parse_ip_address(ping_args.ip_address->sval[0], ip4, ip6);
if (!rc) {
ESP_LOGE("ping","Error parsing provided IP address...aborting!\n");
return ESP_FAIL;
}
}
if (ping_args.count->count > 0)
*count= *ping_args.count->ival;
if (ping_args.timeout->count > 0)
*timeout = *ping_args.timeout->ival;
if (ping_args.delay->count > 0)
*delay = *ping_args.delay->ival;
if (ping_args.packet_size->count > 0)
*packet_size = *ping_args.packet_size->ival;
if (ping_args.tos->count > 0)
*tos = *ping_args.tos->ival;
return ESP_OK;
}
esp_err_t ping_results(ping_target_id_t message_type, esp_ping_found *found_val)
{
static int ctr;
ip4_addr_t target_ipv4;
uint32_t ping_count = 0;
esp_ping_get_target(PING_TARGET_IP_ADDRESS, &target_ipv4.addr, sizeof(uint32_t));
esp_ping_get_target(PING_TARGET_IP_ADDRESS_COUNT, &ping_count, sizeof(uint32_t));
if (found_val->ping_err != 2)
{
fprintf(stdout, "%d bytes from %s: icmp_seq=%d time=%d ms\n",
found_val->bytes, inet_ntoa(target_ipv4), found_val->ping_seqno, found_val->resp_time);
} else {
fprintf(stdout, ".");
fflush(stdout);
}
if (++ctr >= ping_count) {
int32_t packet_loss = ( 1-((found_val->recv_count * 1.0) / found_val->send_count)) * 100;
fprintf(stdout, "\n--- %s ping statistics ---\n", inet_ntoa(target_ipv4));
fprintf(stdout, "%d packets transmitted, %d received, %d%% packet loss, time %dms\n",
found_val->send_count, found_val->recv_count, packet_loss, found_val->total_time);
fprintf(stdout, "rtt min/avg/max = %d/%1.2f/%d ms\n", found_val->min_time,
(found_val->total_time * 1.0) / found_val->recv_count, found_val->max_time);
// clean up time
memset(found_val, 0, sizeof(esp_ping_found));
ctr = 0;
}
ping_deinit();
return ESP_OK;
}
static esp_err_t send_icmp(int argc, char **argv)
{
if (!is_connected)
{
ESP_LOGE("ping", "Device is not connected to any AP. Cannot ping host without an IP address\n"
"Please associate to an SSID and then use ping!\n");
return ESP_FAIL;
}
esp_err_t ret;
int counter;
ip4_addr_t target_ipv4;
// initialize optional arguments to default values
uint32_t ping_count = DEFAULT_COUNT;
uint32_t ping_timeout = DEFAULT_TIMEOUT;
uint32_t ping_delay = DEFAULT_DELAY;
uint32_t packet_size = DEFAULT_DATA_SIZE;
uint32_t ping_tos = -1;
// TO DO: IPv6
ip6_addr_t target_ipv6;
int nerrors = arg_parse(argc, argv, (void **) &ping_args);
if (nerrors != 0) {
arg_print_errors(stderr, ping_args.end, argv[0]);
return FAILURE;
}
ret = parse_args(&target_ipv4, &target_ipv6, &ping_count, &ping_timeout, &ping_delay,
&packet_size, &ping_tos);
if (ret == ESP_OK) {
printf("PING %s (%s) %d(%d) bytes of data.\n", inet_ntoa(target_ipv4),
inet_ntoa(target_ipv4), packet_size, (packet_size + 28)); // ICMP header length is 28 bytes
for (counter = 0; counter < ping_count; counter++)
{
vTaskDelay(1000 / portTICK_PERIOD_MS);
esp_ping_set_target(PING_TARGET_IP_ADDRESS_COUNT, &ping_count, sizeof(uint32_t));
esp_ping_set_target(PING_TARGET_RCV_TIMEO, &ping_timeout, sizeof(uint32_t));
esp_ping_set_target(PING_TARGET_DELAY_TIME, &ping_delay, sizeof(uint32_t));
esp_ping_set_target(PING_TARGET_IP_ADDRESS, &target_ipv4.addr, sizeof(uint32_t));
esp_ping_set_target(PING_TARGET_RES_FN, &ping_results, sizeof(ping_results));
esp_ping_set_target(PING_TARGET_DATA_LEN, &packet_size, sizeof(uint32_t));
if (ping_tos != -1)
esp_ping_set_target(PING_TARGET_IP_TOS, &ping_tos, sizeof(uint32_t));
ping_init();
}
} else
return ESP_FAIL;
return ESP_OK;
}
void register_ping(void)
{
ping_args.ip_address = arg_str0(NULL, NULL, "<IPv4/IPv6>", "Target IP Address");
ping_args.timeout = arg_int0("t", "timeout", "<t>", "Connection timeout, ms");
ping_args.count = arg_int0("c", "count", "<n>", "Number of messages");
ping_args.delay= arg_int0("d", "delay", "<t>", "Delay between messges, ms");
ping_args.packet_size = arg_int0("s", "size", "<n>", "Packet data size, bytes");
ping_args.tos = arg_int0(NULL, "tos", "<n>", "Type of service");
ping_args.end = arg_end(1);
const esp_console_cmd_t ping_cmd = {
.command = "ping",
.help = "Send an ICMP message to an IPv4/IPv6 address",
.hint = "<IP address>",
.func = &send_icmp,
.argtable = &ping_args
};
ESP_ERROR_CHECK( esp_console_cmd_register(&ping_cmd) );
}

View file

@ -1,21 +0,0 @@
/* Console example — declarations of command registration functions.
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
// Register Ping functions
void register_ping(void);
#ifdef __cplusplus
}
#endif

View file

@ -24,7 +24,6 @@
static EventGroupHandle_t wifi_event_group;
const int CONNECTED_BIT = BIT0;
volatile bool is_connected = false;
static void event_handler(void* arg, esp_event_base_t event_base,
@ -107,7 +106,6 @@ static int connect(int argc, char **argv)
return 1;
}
ESP_LOGI(__func__, "Connected");
is_connected = true;
return 0;
}

View file

@ -12,7 +12,6 @@
extern "C" {
#endif
extern volatile bool is_connected;
// Register WiFi functions
void register_wifi(void);

View file

@ -130,7 +130,6 @@ void app_main(void)
register_system();
register_wifi();
register_nvs();
register_ping();
/* Prompt to be printed before each line.
* This can be customized, made dynamic, etc.