0

I am using ESP32 Ping from this page: https://github.com/pbecchi/ESP32_ping

It works fine on ESP32, no compiler error.

Because something wrong on my PC, I did fresh install Windows 10 and Arduino IDE 1.8.8.

After fresh install, ESP32 Ping doesn't work anymore.

Arduino IDE Compiler error in Ping.cpp:

//Ping.cpp

#include <Arduino.h>

#include <math.h>
#include <float.h>
#include <signal.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>

#include "ping.h"

#include "lwip/inet_chksum.h"
#include "lwip/ip.h"
#include "lwip/ip4.h"
#include "lwip/err.h"
#include "lwip/icmp.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include "lwip/netdb.h"
#include "lwip/dns.h"

static uint16_t ping_seq_num;
static uint8_t stopped = 0;

/*
* Statistics
*/
static uint32_t transmitted = 0;
static uint32_t received = 0;
static float min_time = 0;
static float max_time = 0;
static float mean_time = 0;
static float last_mean_time = 0;
static float var_time = 0;

#define PING_ID 0xAFAF

#define PING_DEFAULT_COUNT    10
#define PING_DEFAULT_INTERVAL  1
#define PING_DEFAULT_SIZE     32
#define PING_DEFAULT_TIMEOUT   1

/*
* Helper functions
*
*/
static void ping_prepare_echo(struct icmp_echo_hdr *iecho, uint16_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);

    /* fill the additional data buffer with some data */
    for (i = 0; i < data_len; i++) {
        ((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i;
    }

    iecho->chksum = inet_chksum(iecho, len);
}

static err_t ping_send(int s, ip4_addr_t *addr, int size) {
    struct icmp_echo_hdr *iecho;
    struct sockaddr_in to;
    size_t ping_size = sizeof(struct icmp_echo_hdr) + size;
    int err;

    iecho = (struct icmp_echo_hdr *)mem_malloc((mem_size_t)ping_size);
    if (!iecho) {
        return ERR_MEM;
    }

    ping_prepare_echo(iecho, (uint16_t)ping_size);

    to.sin_len = sizeof(to);
    to.sin_family = AF_INET;
    inet_addr_from_ipaddr(&to.sin_addr, addr);

    if ((err = sendto(s, iecho, ping_size, 0, (struct sockaddr*)&to, sizeof(to)))) {
        transmitted++;
    }
    free(iecho)
    return (err ? ERR_OK : ERR_VAL);
}

static void ping_recv(int s) {
    char buf[64];
    int fromlen, len;
    struct sockaddr_in from;
    struct ip_hdr *iphdr;
    struct icmp_echo_hdr *iecho = NULL;
    char ipa[16];
    struct timeval begin;
    struct timeval end;
    uint64_t micros_begin;
    uint64_t micros_end;
    float elapsed;

    // Register begin time
    gettimeofday(&begin, NULL);

    // Send
    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))) {
            // Register end time
            gettimeofday(&end, NULL);

            /// Get from IP address
            ip4_addr_t fromaddr;
            inet_addr_to_ipaddr(&fromaddr, &from.sin_addr);

            strcpy(ipa, inet_ntoa(fromaddr));

            // Get echo
            iphdr = (struct ip_hdr *)buf;
            iecho = (struct icmp_echo_hdr *)(buf + (IPH_HL(iphdr) * 4));

            // Print ....
            if ((iecho->id == PING_ID) && (iecho->seqno == htons(ping_seq_num))) {
                received++;

                // Get elapsed time in milliseconds
                micros_begin = begin.tv_sec * 1000000;
                micros_begin += begin.tv_usec;

                micros_end = end.tv_sec * 1000000;
                micros_end += end.tv_usec;

                elapsed = (float)(micros_end - micros_begin) / (float)1000.0;

                // Update statistics
                // Mean and variance are computed in an incremental way
                if (elapsed < min_time) {
                    min_time = elapsed;
                }

                if (elapsed > max_time) {
                    max_time = elapsed;
                }

                last_mean_time = mean_time;
                mean_time = (((received - 1) * mean_time) + elapsed) / received;

                if (received > 1) {
                    var_time = var_time + ((elapsed - last_mean_time) * (elapsed - mean_time));
                }

                // Print ...
                log_d("%d bytes from %s: icmp_seq=%d time=%.3f ms\r\n", len, ipa,
                    ntohs(iecho->seqno), elapsed
                );

                return;
            }
            else {
                // TODO
            }
        }
    }

    if (len < 0) {
        log_d("Request timeout for icmp_seq %d\r\n", ping_seq_num);
    }
}
/*
static void stop_action(int i) {
    signal(i, SIG_DFL);
    stopped = 1;
}
+/
/*
* Operation functions
*
*/
void ping(const char *name, int count, int interval, int size, int timeout) {
    // Resolve name
    hostent * target = gethostbyname(name);
    IPAddress adr = *target->h_addr_list[0];
    if (target->h_length == 0) {
        // TODO: error not found target?????
        return;
    }
    ping_start(adr, count, interval, size, timeout);
}
bool ping_start(struct ping_option *ping_o) {


    return ping_start(ping_o->ip,ping_o->count,0,0,0);

}
bool ping_start(IPAddress adr, int count=0, int interval=0, int size=0, int timeout=0) {
//  driver_error_t *error;
    struct sockaddr_in address;
    ip4_addr_t ping_target;
    int s;
    // Get default values if argument are not provided
    if (count == 0) {
        count = PING_DEFAULT_COUNT;
    }

    if (interval == 0) {
        interval = PING_DEFAULT_INTERVAL;
    }

    if (size == 0) {
        size = PING_DEFAULT_SIZE;
    }

    if (timeout == 0) {
        timeout = PING_DEFAULT_TIMEOUT;
    }

    // Create socket
    if ((s = socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0) {
        // TODO: error
        return false;
    }


    address.sin_addr.s_addr = adr; 
    ping_target.addr = address.sin_addr.s_addr; 

    // Setup socket
    struct timeval tout;

    // Timeout
    tout.tv_sec = timeout;
    tout.tv_usec = 0;

    if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tout, sizeof(tout)) < 0) {
        closesocket(s);
        // TODO: error
        return false;
    }

    stopped = 0;
    transmitted = 0;
    received = 0;
    min_time = 1.E+9;// FLT_MAX;
    max_time = 0.0;
    mean_time = 0.0;
    var_time = 0.0;

    // Register signal for stop ping
    //signal(SIGINT, stop_action);

    // Begin ping ...
    char ipa[16];

    strcpy(ipa, inet_ntoa(ping_target));
    log_i("PING %s: %d data bytes\r\n",  ipa, size);

    ping_seq_num = 0;

    while ((ping_seq_num < count) && (!stopped)) {
        if (ping_send(s, &ping_target, size) == ERR_OK) {
            ping_recv(s);
        }
        delay( interval*1000L);
    }

    closesocket(s);

    log_i("%d packets transmitted, %d packets received, %.1f%% packet loss\r\n",
        transmitted,
        received,
        ((((float)transmitted - (float)received) / (float)transmitted) * 100.0)
    );

    if (received) {
        ping_resp pingresp;
        log_i("round-trip min/avg/max/stddev = %.3f/%.3f/%.3f/%.3f ms\r\n", min_time, mean_time, max_time, sqrt(var_time / received));
        pingresp.total_count = 10;
        pingresp.timeout_count = 10;
        pingresp.total_bytes = 1;
        pingresp.total_time = mean_time;
        pingresp.ping_err = 0;
        return true;
    //  ping_o->sent_function(ping_o, (uint8*)&pingresp);
    }
    return false;
}

bool ping_regist_recv(struct ping_option *ping_opt, ping_recv_function ping_recv)
{
    if (ping_opt == NULL)
        return false;

    ping_opt->recv_function = ping_recv;
    return true;
}

bool ping_regist_sent(struct ping_option *ping_opt, ping_sent_function ping_sent)
{
    if (ping_opt == NULL)
        return false;

    ping_opt->sent_function = ping_sent;
    return true;
}

Arduino IDE 1.8.8. compiler stop in this line:

inet_addr_from_ipaddr(&to.sin_addr, addr);

The error message: 'inet_addr_to_ipaddr' was not declared in this scope

According to this post, inet_addr need lwip library.

So... the conclusion: cause of this issue is broken lwip library.

But when ESP32 Ping working fine previously, I didn't install any separate lwip library. Maybe ESP32 Ping use lwip library from Arduino library - #include <Arduino.h>

But why after fresh install, ESP32 Ping doesn't work anymore?

Arduino IDE installation automatically included Arduino library. Also, I didn't change anything on Arduino Sketch & Library folder - C:\Users\Documents\Arduino. The folder content as the same as before fresh install.

How to fix this?

Please help...

  • did you use git to install the esp32 boards? – dandavis Jan 17 at 13:59
  • did the install of ESP32 package in Board Manager finish without errors? – Juraj Jan 17 at 14:11
  • @Juraj - ESP32 package installation in Board Manager finished without any errors but when compile the sketch always error 'inet_addr_to_ipaddr' was not declared in this scope – wieb Jan 17 at 15:12
  • I did search all Ping.cpp included files in C:\Program Files (x86)\Arduino folder. ALL included files has been found in that sub folder EXCEPT ip4.h. The ip4.h file doesn't found in that folder, maybe this is the cause of broken lwip library. How to fix this? – wieb Jan 17 at 15:48
  • Found ip4.h in C:\Users\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.1\tools\sdk\include\lwip\lwip. It seems ESP32 Ping use 2 separate lwip libraries (Arduino libraries in C:\Program Files (x86)\Arduino and ESP32 library in C:\Users\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.1\tools\sdk\include\lwip\lwip). But somehow the library connection is broken and cause 'inet_addr_to_ipaddr' was not declared in this scope error – wieb Jan 17 at 17:36
0

Done this steps:

1. Uninstall Arduino IDE 1.8.8
2. Delete C:\Users\AppData\Local\
3. Rename C:\Users\Documents\Arduino into C:\Users\Documents\Arduino_OLD
4. Restart the PC
5. Install Arduino IDE 1.8.8
6. Install ESP32 Core version 1.0.0 using Boards Manager

Then.... compile my sketch.

And now.... it WORKS.... :) :) :)

My previous mistake is not installing ESP32 Core version 1.0.0.

I did it by installing version 1.0.1 - the Boards Manager default version - which didn't work.

It seems some change in ESP32 Core version 1.0.1 broke ESP32 Ping library connection.

  • and why this answer? there is a simpler way to reinstall a boards package – Juraj Jan 20 at 6:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.