inet_addr_to_ipaddr' не был объявлен в этой области

Я использую ESP32 Ping с этой страницы: https://github.com/pbecchi/ESP32_ping

Он отлично работает на ESP32, ошибок компилятора нет.

Поскольку на моем компьютере что-то не так, я заново установил Windows 10 и Arduino IDE 1.8.8.

После новой установки ESP32 Ping больше не работает.

Ошибка компилятора IDE Arduino в 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;
}

Ардуино IDE 1.8.8. остановка компилятора в этой строке:

inet_addr_from_ipaddr(&to.sin_addr, addr);

Сообщение об ошибке: 'inet_addr_to_ipaddr' не был объявлен в этой области

Согласно этому сообщению, inet_addr нужен библиотека lwip.

Итак... вывод: причиной этой проблемы является неработающая библиотека lwip.

Но когда раньше ESP32 Ping работал нормально, я не устанавливал какую-либо отдельную библиотеку lwip. Возможно, ESP32 Ping использует библиотеку lwip из библиотеки Arduino - #include <Arduino.h>

Но почему после новой установки ESP32 Ping больше не работает?

Установка Arduino IDE автоматически включает библиотеку Arduino. Кроме того, я ничего не менял в Arduino Sketch & Папка библиотеки — C:\Users\Documents\Arduino. Содержимое папки такое же, как и перед новой установкой.

Как это исправить?

Пожалуйста, помогите...

, 👍0

Обсуждение

вы использовали git для установки плат esp32?, @dandavis

установка пакета ESP32 в Board Manager завершилась без ошибок?, @Juraj

@Juraj - установка пакета ESP32 в Board Manager завершилась без каких-либо ошибок, но при компиляции эскиза всегда в этой области не объявлялась ошибка 'inet_addr_to_ipaddr', @wieb

Я искал все файлы, входящие в состав Ping.cpp, в папке C:\Program Files (x86)\Arduino. В этой подпапке найдены ВСЕ включенные файлы, КРОМЕ ip4.h. Файл ip4.h не найден в этой папке, возможно, это причина поломки библиотеки lwip. Как это исправить?, @wieb

Найден ip4.h в C:\Users\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.1\tools\sdk\include\lwip\lwip. Кажется, ESP32 Ping использует две отдельные библиотеки lwip (библиотеки Arduino в C:\Program Files (x86)\Arduino и библиотека ESP32 в C:\Users\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0 .1\tools\sdk\include\lwip\lwip). Но каким-то образом соединение с библиотекой разорвано, и в этой ошибке области видимости не было объявлено _'inet_addr_to_ipaddr'., @wieb

Вместо использования Board Manager для установки пакета ESP32 также попробовал установить его с помощью git, но это тоже не помогло. Тем не менее _'inet_addr_to_ipaddr' не был объявлен в этой ошибке области_, @wieb

Попробовал очень глупое решение, добавив #define inet_addr_from_ipaddr и #define inet_addr_to_ipaddr в файле Ping.cpp. Ошибка компилятора отсутствует, и скетч можно загрузить в ESP32, но ping не работает, поскольку не найдены функции inet_addr_from_ipaddr и inet_addr_to_ipaddr., @wieb

Выполнял поиск в папках: C:\Program Files (x86)\Arduino, C:\Users\AppData\Local\Arduino15\ и C:\Users\Documents\Arduino, НЕ НАЙДЕНО ни одного inet_addr_from_ipaddr и функции inet_addr_to_ipaddr. Возможно, это причина того, что `'inet_addr_to_ipaddr' не был объявлен в этой ошибке. Но как это исправить?, @wieb


1 ответ


Лучший ответ:

0

Выполнено следующее:

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

Затем.... скомпилируйте мой эскиз.

А теперь.... это РАБОТАЕТ.... :) :) :)

Моя предыдущая ошибка заключалась в том, что я не установил ESP32 Core версии 1.0.0.

Я сделал это, установив версию 1.0.1 — версию Boards Manager по умолчанию — которая не сработала.

Похоже, какое-то изменение в ESP32 Core версии 1.0.1 нарушило соединение с библиотекой ESP32 Ping.

,

и почему такой ответ? есть более простой способ переустановить пакет плат, @Juraj