mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-26 22:22:16 +03:00
Модуль Пинг
This commit is contained in:
240
src/modules/virtual/Ping/Ping.cpp
Normal file
240
src/modules/virtual/Ping/Ping.cpp
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
#include "Global.h"
|
||||||
|
#include "classes/IoTItem.h"
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
#ifdef ESP32
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "lwip/inet.h"
|
||||||
|
#include "lwip/netdb.h"
|
||||||
|
#include "lwip/sockets.h"
|
||||||
|
#include "argtable3/argtable3.h"
|
||||||
|
#include "ping/ping_sock.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#ifdef ESP8266
|
||||||
|
#include <ESP8266Ping.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
bool pingState = false;
|
||||||
|
/*
|
||||||
|
static struct
|
||||||
|
{
|
||||||
|
uint32_t timeout;
|
||||||
|
uint32_t interval;
|
||||||
|
uint32_t data_size;
|
||||||
|
uint32_t count;
|
||||||
|
uint32_t tos;
|
||||||
|
uint32_t ttl;
|
||||||
|
//String host;
|
||||||
|
// arg_end *end;
|
||||||
|
} ping_args;
|
||||||
|
*/
|
||||||
|
esp_ping_config_t config = ESP_PING_DEFAULT_CONFIG();
|
||||||
|
|
||||||
|
static void cmd_ping_on_ping_success(esp_ping_handle_t hdl, void *args)
|
||||||
|
{
|
||||||
|
uint8_t ttl;
|
||||||
|
uint16_t seqno;
|
||||||
|
uint32_t elapsed_time, recv_len;
|
||||||
|
ip_addr_t target_addr;
|
||||||
|
esp_ping_get_profile(hdl, ESP_PING_PROF_SEQNO, &seqno, sizeof(seqno));
|
||||||
|
esp_ping_get_profile(hdl, ESP_PING_PROF_TTL, &ttl, sizeof(ttl));
|
||||||
|
esp_ping_get_profile(hdl, ESP_PING_PROF_IPADDR, &target_addr, sizeof(target_addr));
|
||||||
|
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));
|
||||||
|
// Serial.printf("%" PRIu32 " bytes from %s icmp_seq=%" PRIu16 " ttl=%" PRIu16 " time=%" PRIu32 " ms\n",
|
||||||
|
// recv_len, ipaddr_ntoa((ip_addr_t*)&target_addr), seqno, ttl, elapsed_time);
|
||||||
|
SerialPrint("i", "Ping", String(recv_len) + " bytes from " + String(ipaddr_ntoa((ip_addr_t *)&target_addr)) + " icmp_seq=" + String(seqno) + " ttl=" + String(ttl) + " time=" + String(elapsed_time) + " ms");
|
||||||
|
pingState = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cmd_ping_on_ping_timeout(esp_ping_handle_t hdl, void *args)
|
||||||
|
{
|
||||||
|
uint16_t seqno;
|
||||||
|
ip_addr_t target_addr;
|
||||||
|
esp_ping_get_profile(hdl, ESP_PING_PROF_SEQNO, &seqno, sizeof(seqno));
|
||||||
|
esp_ping_get_profile(hdl, ESP_PING_PROF_IPADDR, &target_addr, sizeof(target_addr));
|
||||||
|
// Serial.printf("From %s icmp_seq=%d timeout\n",ipaddr_ntoa((ip_addr_t*)&target_addr), seqno);
|
||||||
|
SerialPrint("i", "Ping", "From " + String(ipaddr_ntoa((ip_addr_t *)&target_addr)) + " icmp_seq=" + String(seqno) + " timeout");
|
||||||
|
pingState = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cmd_ping_on_ping_end(esp_ping_handle_t hdl, void *args)
|
||||||
|
{
|
||||||
|
ip_addr_t target_addr;
|
||||||
|
uint32_t transmitted;
|
||||||
|
uint32_t received;
|
||||||
|
uint32_t total_time_ms;
|
||||||
|
esp_ping_get_profile(hdl, ESP_PING_PROF_REQUEST, &transmitted, sizeof(transmitted));
|
||||||
|
esp_ping_get_profile(hdl, ESP_PING_PROF_REPLY, &received, sizeof(received));
|
||||||
|
esp_ping_get_profile(hdl, ESP_PING_PROF_IPADDR, &target_addr, sizeof(target_addr));
|
||||||
|
esp_ping_get_profile(hdl, ESP_PING_PROF_DURATION, &total_time_ms, sizeof(total_time_ms));
|
||||||
|
uint32_t loss = (uint32_t)((1 - ((float)received) / transmitted) * 100);
|
||||||
|
if (IP_IS_V4(&target_addr))
|
||||||
|
{
|
||||||
|
// Serial.printf("\n--- %s ping statistics ---\n", inet_ntoa(*ip_2_ip4(&target_addr)));
|
||||||
|
SerialPrint("i", "Ping", "\n--- " + String(inet_ntoa(*ip_2_ip4(&target_addr))) + " ping statistics ---");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Serial.printf("\n--- %s ping statistics ---\n", inet6_ntoa(*ip_2_ip6(&target_addr)));
|
||||||
|
SerialPrint("i", "Ping", "\n--- " + String(inet6_ntoa(*ip_2_ip6(&target_addr))) + " ping statistics ---");
|
||||||
|
}
|
||||||
|
// Serial.printf("%" PRIu32 " packets transmitted, %" PRIu32 " received, %" PRIu32 "%% packet loss, time %" PRIu32 "ms\n",
|
||||||
|
// transmitted, received, loss, total_time_ms);
|
||||||
|
SerialPrint("i", "Ping", String(transmitted) + " packets transmitted, " + String(received) + " received, " + String(loss) + "% packet loss, time " + String(total_time_ms) + "ms\n");
|
||||||
|
// delete the ping sessions, so that we clean up all resources and can create a new ping session
|
||||||
|
// we don't have to call delete function in the callback, instead we can call delete function from other tasks
|
||||||
|
esp_ping_delete_session(hdl);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
class PingIoTM : public IoTItem
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
String _ip = "";
|
||||||
|
int timeout = 0;
|
||||||
|
int interval = 0;
|
||||||
|
int data_size = 0;
|
||||||
|
int count = 0;
|
||||||
|
int tos = 0;
|
||||||
|
int ttl = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PingIoTM(String parameters) : IoTItem(parameters)
|
||||||
|
{
|
||||||
|
jsonRead(parameters, "ip", _ip);
|
||||||
|
jsonRead(parameters, "timeout", timeout);
|
||||||
|
jsonRead(parameters, "interval", interval);
|
||||||
|
jsonRead(parameters, "data_size", data_size);
|
||||||
|
jsonRead(parameters, "count", count);
|
||||||
|
jsonRead(parameters, "tos", tos);
|
||||||
|
jsonRead(parameters, "ttl", ttl);
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
/*
|
||||||
|
ping_args.timeout = 10; // arg_dbl0("W", "timeout", "<t>", "Time to wait for a response, in seconds");
|
||||||
|
ping_args.interval = 1; // arg_dbl0("i", "interval", "<t>", "Wait interval seconds between sending each packet");
|
||||||
|
ping_args.data_size = 0; // arg_int0("s", "size", "<n>", "Specify the number of data bytes to be sent");
|
||||||
|
ping_args.count = 0; // arg_int0("c", "count", "<n>", "Stop after sending count packets");
|
||||||
|
ping_args.tos = 0; // arg_int0("Q", "tos", "<n>", "Set Type of Service related bits in IP datagrams");
|
||||||
|
ping_args.ttl = 0; // arg_int0("T", "ttl", "<n>", "Set Time to Live related bits in IP datagrams");
|
||||||
|
// ping_args.end = arg_end(1);
|
||||||
|
*/
|
||||||
|
if (timeout > 0)
|
||||||
|
config.timeout_ms = (uint32_t)(timeout * 1000);
|
||||||
|
if (interval > 0)
|
||||||
|
config.interval_ms = (uint32_t)(interval * 1000);
|
||||||
|
if (data_size > 0)
|
||||||
|
config.data_size = (uint32_t)(data_size);
|
||||||
|
if (count > 0)
|
||||||
|
config.count = (uint32_t)(count);
|
||||||
|
if (tos > 0)
|
||||||
|
config.tos = (uint32_t)(tos);
|
||||||
|
if (ttl > 0)
|
||||||
|
config.ttl = (uint32_t)(ttl);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void doByInterval()
|
||||||
|
{
|
||||||
|
#ifdef ESP8266
|
||||||
|
regEvent((float)Ping.ping(_ip.c_str()), "ping");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Основной цикл программы
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
#ifdef ESP32
|
||||||
|
if (value.valD != (float)pingState)
|
||||||
|
regEvent((float)pingState, "ping");
|
||||||
|
|
||||||
|
#endif
|
||||||
|
IoTItem::loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
IoTValue execute(String command, std::vector<IoTValue> ¶m)
|
||||||
|
{
|
||||||
|
IoTValue val;
|
||||||
|
if (command == "ping")
|
||||||
|
{
|
||||||
|
#ifdef ESP32
|
||||||
|
if (param.size())
|
||||||
|
{
|
||||||
|
// parse IP address
|
||||||
|
struct sockaddr_in6 sock_addr6;
|
||||||
|
ip_addr_t target_addr;
|
||||||
|
memset(&target_addr, 0, sizeof(target_addr));
|
||||||
|
|
||||||
|
if (inet_pton(AF_INET6, _ip.c_str(), &sock_addr6.sin6_addr) == 1)
|
||||||
|
{
|
||||||
|
/* convert ip6 string to ip6 address */
|
||||||
|
ipaddr_aton(_ip.c_str(), &target_addr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct addrinfo hint;
|
||||||
|
struct addrinfo *res = NULL;
|
||||||
|
memset(&hint, 0, sizeof(hint));
|
||||||
|
/* convert ip4 string or hostname to ip4 or ip6 address */
|
||||||
|
if (getaddrinfo(_ip.c_str(), NULL, &hint, &res) != 0)
|
||||||
|
{
|
||||||
|
// Serial.printf("ping: unknown host %s\n", ping_args.host.c_str());
|
||||||
|
SerialPrint("E", "Ping", "ping: unknown host " + _ip);
|
||||||
|
// return 1;
|
||||||
|
}
|
||||||
|
if (res->ai_family == AF_INET)
|
||||||
|
{
|
||||||
|
struct in_addr addr4 = ((struct sockaddr_in *)(res->ai_addr))->sin_addr;
|
||||||
|
inet_addr_to_ip4addr(ip_2_ip4(&target_addr), &addr4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct in6_addr addr6 = ((struct sockaddr_in6 *)(res->ai_addr))->sin6_addr;
|
||||||
|
inet6_addr_to_ip6addr(ip_2_ip6(&target_addr), &addr6);
|
||||||
|
}
|
||||||
|
freeaddrinfo(res);
|
||||||
|
}
|
||||||
|
config.target_addr = target_addr;
|
||||||
|
/* set callback functions */
|
||||||
|
esp_ping_callbacks_t cbs = {
|
||||||
|
.cb_args = NULL,
|
||||||
|
.on_ping_success = cmd_ping_on_ping_success,
|
||||||
|
.on_ping_timeout = cmd_ping_on_ping_timeout,
|
||||||
|
.on_ping_end = cmd_ping_on_ping_end};
|
||||||
|
esp_ping_handle_t ping;
|
||||||
|
|
||||||
|
esp_ping_new_session(&config, &cbs, &ping);
|
||||||
|
esp_ping_start(ping);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef ESP8266
|
||||||
|
if (param.size())
|
||||||
|
{
|
||||||
|
val.valD = Ping.ping(param[0].valS.c_str());
|
||||||
|
if (val.valD)
|
||||||
|
SerialPrint("I", "Ping", "Ping success");
|
||||||
|
else
|
||||||
|
SerialPrint("E", "Ping", "Ping error");
|
||||||
|
regEvent(val, "ping");
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
~PingIoTM(){};
|
||||||
|
};
|
||||||
|
|
||||||
|
void *getAPI_Ping(String subtype, String param)
|
||||||
|
{
|
||||||
|
if (subtype == F("Ping"))
|
||||||
|
{
|
||||||
|
return new PingIoTM(param);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
68
src/modules/virtual/Ping/modinfo.json
Normal file
68
src/modules/virtual/Ping/modinfo.json
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
{
|
||||||
|
"menuSection": "virtual_elments",
|
||||||
|
|
||||||
|
"configItem": [
|
||||||
|
{
|
||||||
|
"global": 0,
|
||||||
|
"name": "Ping",
|
||||||
|
"type": "Reading",
|
||||||
|
"subtype": "Ping",
|
||||||
|
"id": "ping",
|
||||||
|
"needSave": 0,
|
||||||
|
"widget": "nil",
|
||||||
|
"page": "",
|
||||||
|
"descr": "",
|
||||||
|
"ip": "8.8.8.8",
|
||||||
|
"timeout": 5,
|
||||||
|
"interval": 1,
|
||||||
|
"data_size": 0,
|
||||||
|
"count": 0,
|
||||||
|
"tos": 0,
|
||||||
|
"ttl": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
"about": {
|
||||||
|
"authorName": "Mikhail Bubnov",
|
||||||
|
"authorContact": "https://t.me/Mit4bmw",
|
||||||
|
"authorGit": "https://github.com/Mit4el",
|
||||||
|
"specialThanks": "",
|
||||||
|
"moduleName": "Ping",
|
||||||
|
"moduleVersion": "1.0",
|
||||||
|
"usedRam": {
|
||||||
|
"esp32_4mb": 15,
|
||||||
|
"esp8266_4mb": 15
|
||||||
|
},
|
||||||
|
"title": "Пинг",
|
||||||
|
"moduleDesc": "Пинг - проверка доступности сетевого адреса",
|
||||||
|
"propInfo": {
|
||||||
|
"ip": "IP адрес (8.8.8.8) или имя хоста (www.google.com) кого пингуем",
|
||||||
|
"timeout": "Тайм-аут. Только для ESP32. Если 0, то пингует со значением по умолчанию",
|
||||||
|
"interval": "Интервал. Только для ESP32. Если 0, то пингует со значением по умолчанию",
|
||||||
|
"data_size": "Размер пакета. Только для ESP32. Если 0, то пингует со значением по умолчанию",
|
||||||
|
"count": "Количество пакетов. Только для ESP32. Если 0, то пингует со значением по умолчанию",
|
||||||
|
"tos": "Type Of Service. Только для ESP32. Если 0, то пингует со значением по умолчанию",
|
||||||
|
"ttl": "Time To Live. Только для ESP32. Если 0, то пингует со значением по умолчанию"
|
||||||
|
},
|
||||||
|
"funcInfo": [
|
||||||
|
{
|
||||||
|
"name": "ping",
|
||||||
|
"descr": "проверить пинг вручную из сценария",
|
||||||
|
"params": [
|
||||||
|
"IP адрес или имя хоста"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
"defActive": true,
|
||||||
|
|
||||||
|
"usedLibs": {
|
||||||
|
"esp32*": [
|
||||||
|
|
||||||
|
],
|
||||||
|
"esp82*": [
|
||||||
|
"https://github.com/dancol90/ESP8266Ping"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
53
src/modules/virtual/Ping/ping_export.json
Normal file
53
src/modules/virtual/Ping/ping_export.json
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
{
|
||||||
|
"mark": "iotm",
|
||||||
|
"config": [
|
||||||
|
{
|
||||||
|
"global": 0,
|
||||||
|
"type": "Reading",
|
||||||
|
"subtype": "VButton",
|
||||||
|
"id": "vbtn67",
|
||||||
|
"needSave": 0,
|
||||||
|
"widget": "toggle",
|
||||||
|
"page": "Пинг",
|
||||||
|
"descr": "ping",
|
||||||
|
"int": "0",
|
||||||
|
"val": "0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"global": 0,
|
||||||
|
"type": "Reading",
|
||||||
|
"subtype": "Variable",
|
||||||
|
"id": "vout96",
|
||||||
|
"needSave": 0,
|
||||||
|
"widget": "anydataDef",
|
||||||
|
"page": "Пинг",
|
||||||
|
"descr": "Состояние",
|
||||||
|
"int": "0",
|
||||||
|
"val": "...",
|
||||||
|
"map": "1024,1024,1,100",
|
||||||
|
"plus": 0,
|
||||||
|
"multiply": 1,
|
||||||
|
"round": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"global": 0,
|
||||||
|
"type": "Reading",
|
||||||
|
"subtype": "Ping",
|
||||||
|
"id": "ping21",
|
||||||
|
"needSave": 0,
|
||||||
|
"widget": "anydataDef",
|
||||||
|
"page": "Пинг",
|
||||||
|
"descr": "Статус",
|
||||||
|
"ip": "8.8.8.8",
|
||||||
|
"timeout": 5,
|
||||||
|
"interval": 1,
|
||||||
|
"data_size": 0,
|
||||||
|
"count": 0,
|
||||||
|
"tos": 0,
|
||||||
|
"ttl": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
scenario=>if vbtn67==1 then ping21.ping("8.8.8.8")
|
||||||
|
if ping21==0 then vout96 = "нет интернета" else vout96 ="есть интернет"
|
||||||
Reference in New Issue
Block a user