mirror of
https://github.com/arendst/Tasmota.git
synced 2025-04-25 07:17:16 +00:00
- Fix prevent multiple pings to run concurrently
This commit is contained in:
parent
42d82fdc97
commit
3e517ce9b7
@ -27,6 +27,7 @@
|
|||||||
- Add support for an iAQ sensor (#8107)
|
- Add support for an iAQ sensor (#8107)
|
||||||
- Add support for Seven Segment display using HT16K33 (#8116)
|
- Add support for Seven Segment display using HT16K33 (#8116)
|
||||||
- Add support for AS3935 Lightning Sensor by device111 (#8130)
|
- Add support for AS3935 Lightning Sensor by device111 (#8130)
|
||||||
|
- Fix prevent multiple pings to run concurrently
|
||||||
|
|
||||||
### 8.2.0.2 20200328
|
### 8.2.0.2 20200328
|
||||||
|
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
#define XDRV_38 38
|
#define XDRV_38 38
|
||||||
|
|
||||||
#include <ping.h>
|
#include <ping.h>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
const char kPingCommands[] PROGMEM = "|" // no prefix
|
const char kPingCommands[] PROGMEM = "|" // no prefix
|
||||||
D_CMND_PING
|
D_CMND_PING
|
||||||
@ -35,80 +34,77 @@ void (* const PingCommand[])(void) PROGMEM = {
|
|||||||
// inspired by https://github.com/dancol90/ESP8266Ping
|
// inspired by https://github.com/dancol90/ESP8266Ping
|
||||||
|
|
||||||
typedef struct Ping_t {
|
typedef struct Ping_t {
|
||||||
ping_option opt; // extend the ping_option structure with internal values
|
|
||||||
uint16_t total_count; // total count if packets sent
|
uint16_t total_count; // total count if packets sent
|
||||||
uint16_t timeout_count; // time-outs (no responses)
|
uint16_t timeout_count; // time-outs (no responses)
|
||||||
uint32_t min_time; // minimum time in ms for a successful response
|
uint32_t min_time; // minimum time in ms for a successful response
|
||||||
uint32_t max_time; // maximum time in ms for a successful response
|
uint32_t max_time; // maximum time in ms for a successful response
|
||||||
uint32_t sum_time; // cumulated time in ms for all successful responses (used to compute the average)
|
uint32_t sum_time; // cumulated time in ms for all successful responses (used to compute the average)
|
||||||
|
bool busy; // is ping on-going
|
||||||
bool done; // indicates the ping campaign is finished
|
bool done; // indicates the ping campaign is finished
|
||||||
} Ping_t;
|
} Ping_t;
|
||||||
|
|
||||||
std::vector<Ping_t*> pings = {};
|
ping_option ping_opt;
|
||||||
|
Ping_t ping;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
// callbacks for ping
|
// callbacks for ping
|
||||||
|
|
||||||
// called after a ping response is received or time-out
|
// called after a ping response is received or time-out
|
||||||
void ICACHE_RAM_ATTR ping_recv_cb(Ping_t *ping, struct ping_resp *p_resp) {
|
void ICACHE_RAM_ATTR ping_recv_cb(ping_option *popt, struct ping_resp *p_resp) {
|
||||||
// If successful
|
// If successful
|
||||||
if (p_resp->ping_err >= 0) {
|
if (p_resp->ping_err >= 0) {
|
||||||
uint32_t resp_time = p_resp->resp_time;
|
uint32_t resp_time = p_resp->resp_time;
|
||||||
ping->sum_time += resp_time;
|
ping.sum_time += resp_time;
|
||||||
if (resp_time < ping->min_time) { ping->min_time = resp_time; }
|
if (resp_time < ping.min_time) { ping.min_time = resp_time; }
|
||||||
if (resp_time > ping->max_time) { ping->max_time = resp_time; }
|
if (resp_time > ping.max_time) { ping.max_time = resp_time; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// called after the ping campaign is finished
|
// called after the ping campaign is finished
|
||||||
void ICACHE_RAM_ATTR ping_sent_cb(Ping_t *ping, struct ping_resp *p_resp) {
|
void ICACHE_RAM_ATTR ping_sent_cb(ping_option *popt, struct ping_resp *p_resp) {
|
||||||
// copy counters to build the MQTT response
|
// copy counters to build the MQTT response
|
||||||
ping->total_count = p_resp->total_count;
|
ping.total_count = p_resp->total_count;
|
||||||
ping->timeout_count = p_resp->timeout_count;
|
ping.timeout_count = p_resp->timeout_count;
|
||||||
ping->done = true;
|
ping.done = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if any ping requests is completed, and publish the results
|
// Check if any ping requests is completed, and publish the results
|
||||||
void PingResponsePoll(void) {
|
void PingResponsePoll(void) {
|
||||||
for (auto it = pings.begin(); it != pings.end(); it++) {
|
if (ping.done) {
|
||||||
Ping_t *ping = *it;
|
uint32_t success = ping.total_count - ping.timeout_count;
|
||||||
if (ping->done) {
|
uint32_t ip = ping_opt.ip;
|
||||||
uint32_t success = ping->total_count - ping->timeout_count;
|
|
||||||
uint32_t ip = ping->opt.ip;
|
|
||||||
|
|
||||||
// Serial.printf(
|
// Serial.printf(
|
||||||
// "DEBUG ping_sent_cb: ping reply\n"
|
// "DEBUG ping_sent_cb: ping reply\n"
|
||||||
// "\tsuccess_count = %d \n"
|
// "\tsuccess_count = %d \n"
|
||||||
// "\ttimeout_count = %d \n"
|
// "\ttimeout_count = %d \n"
|
||||||
// "\tmin_time = %d \n"
|
// "\tmin_time = %d \n"
|
||||||
// "\tmax_time = %d \n"
|
// "\tmax_time = %d \n"
|
||||||
// "\tavg_time = %d \n",
|
// "\tavg_time = %d \n",
|
||||||
// success, ping->timeout_count,
|
// success, ping.timeout_count,
|
||||||
// ping->min_time, ping->max_time,
|
// ping.min_time, ping.max_time,
|
||||||
// success ? ping->sum_time / success : 0
|
// success ? ping.sum_time / success : 0
|
||||||
// );
|
// );
|
||||||
|
|
||||||
Response_P(PSTR("{\"" D_JSON_PING "\":{\"%d.%d.%d.%d\":{"
|
Response_P(PSTR("{\"" D_JSON_PING "\":{\"%d.%d.%d.%d\":{"
|
||||||
"\"Reachable\":%s"
|
"\"Reachable\":%s"
|
||||||
",\"Success\":%d"
|
",\"Success\":%d"
|
||||||
",\"Timeout\":%d"
|
",\"Timeout\":%d"
|
||||||
",\"MinTime\":%d"
|
",\"MinTime\":%d"
|
||||||
",\"MaxTime\":%d"
|
",\"MaxTime\":%d"
|
||||||
",\"AvgTime\":%d"
|
",\"AvgTime\":%d"
|
||||||
"}}}"),
|
"}}}"),
|
||||||
ip & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, ip >> 24,
|
ip & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, ip >> 24,
|
||||||
success ? "true" : "false",
|
success ? "true" : "false",
|
||||||
success, ping->timeout_count,
|
success, ping.timeout_count,
|
||||||
ping->min_time, ping->max_time,
|
ping.min_time, ping.max_time,
|
||||||
success ? ping->sum_time / success : 0
|
success ? ping.sum_time / success : 0
|
||||||
);
|
);
|
||||||
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_PING));
|
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_PING));
|
||||||
XdrvRulesProcess();
|
XdrvRulesProcess();
|
||||||
|
ping.done = false;
|
||||||
pings.erase(it--); // remove from list
|
ping.busy = false;
|
||||||
delete ping; // free memory allocated
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,28 +113,32 @@ void CmndPing(void) {
|
|||||||
IPAddress ip;
|
IPAddress ip;
|
||||||
|
|
||||||
RemoveSpace(XdrvMailbox.data);
|
RemoveSpace(XdrvMailbox.data);
|
||||||
if (count > 60) { count = 60; }
|
if (count > 8) { count = 8; }
|
||||||
|
|
||||||
|
if (ping.busy) {
|
||||||
|
ResponseCmndChar_P(PSTR("Ping busy"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (WiFi.hostByName(XdrvMailbox.data, ip)) {
|
if (WiFi.hostByName(XdrvMailbox.data, ip)) {
|
||||||
Ping_t *ping = new Ping_t();
|
memset(&ping_opt, 0, sizeof(ping_opt));
|
||||||
memset(ping, 0, sizeof(Ping_t ));
|
memset(&ping, 0, sizeof(ping));
|
||||||
ping->min_time = UINT32_MAX;
|
ping.min_time = UINT32_MAX;
|
||||||
|
|
||||||
ping_option &opt = ping->opt;
|
ping_opt.count = count;
|
||||||
opt.count = count;
|
ping_opt.coarse_time = 1; // wait 1 second between messages
|
||||||
opt.coarse_time = 1; // wait 1 second between messages
|
ping_opt.ip = ip;
|
||||||
opt.ip = ip;
|
|
||||||
|
|
||||||
// callbacks
|
// callbacks
|
||||||
opt.recv_function = (ping_recv_function) ping_recv_cb; // at each response or time-out
|
ping_opt.recv_function = (ping_recv_function) ping_recv_cb; // at each response or time-out
|
||||||
opt.sent_function = (ping_sent_function) ping_sent_cb; // when all packets have been sent and reveived
|
ping_opt.sent_function = (ping_sent_function) ping_sent_cb; // when all packets have been sent and reveived
|
||||||
|
|
||||||
if (ping_start(&opt)) {
|
ping.busy = true;
|
||||||
pings.push_back(ping);
|
if (ping_start(&ping_opt)) {
|
||||||
ResponseCmndDone();
|
ResponseCmndDone();
|
||||||
} else {
|
} else {
|
||||||
ResponseCmndChar_P(PSTR("Unable to send Ping"));
|
ResponseCmndChar_P(PSTR("Unable to send Ping"));
|
||||||
delete ping;
|
ping.busy = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ResponseCmndChar_P(PSTR("Unable to resolve IP address"));
|
ResponseCmndChar_P(PSTR("Unable to resolve IP address"));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user