diff --git a/docs/solo/tools.md b/docs/solo/tools.md index 254d8586..0af838f0 100644 --- a/docs/solo/tools.md +++ b/docs/solo/tools.md @@ -48,7 +48,7 @@ channel and one room, each switched on separately: | ------- | ----- | | `!ping` | `pong` | | `!batt`, `!temp`, `!time`, `!loc` | battery, temperature, time, position | - | `!hops` | how many hops the command took | + | `!hops` | how many hops the command took (`known route` as for `!path`) | | `!path` | which way it came: the hop hashes, oldest first (`3f:a1:c8`; 2-byte mode `3fa1:c802`), `direct`, or `known route` when it came over a saved path (whose hops aren't carried) | | `!snr` | how its last hop was heard here: SNR and RSSI | | `!dist` | how far away and which way the sender is (both need a position) | diff --git a/examples/companion_radio/MsgExpand.h b/examples/companion_radio/MsgExpand.h index ca03360a..9a12b078 100644 --- a/examples/companion_radio/MsgExpand.h +++ b/examples/companion_radio/MsgExpand.h @@ -20,7 +20,7 @@ // {dist} — distance m (requires sm) // {co2} — CO2 concentration ppm (requires sm) // {name} — sender's name (bot replies only; requires sender_name, else left literal) -// {hops} — hop count: "direct" or "N hops" (bot replies only; requires hops>=0, else left literal) +// {hops} — hop count: "direct" or "N hops", "known route" when it came over a saved path (bot replies only; requires hops>=0, else left literal) // {path} — inbound route as hop hashes, oldest first: "3f:a1:c8" (bot replies only; requires `in`, else left literal) // {snr} — the message's last hop's SNR, "6.5dB" (bot replies only) // {rssi} — and its RSSI, "-92dBm" (bot replies only) @@ -28,6 +28,7 @@ struct BotInbound { const char* path; // "direct" or the hop hashes float snr, rssi; // the last hop's + bool routed; // came over a saved path, whose hops aren't carried: no hop count }; inline void expandMsg(const char* tmpl, char* out, int out_len, @@ -143,8 +144,9 @@ inline void expandMsg(const char* tmpl, char* out, int out_len, p += 6; } else if (strncmp(p, "{hops}", 6) == 0) { if (hops >= 0) { - char b[10]; - if (hops == 0) strcpy(b, "direct"); + char b[12]; + if (in && in->routed) strcpy(b, "known route"); + else if (hops == 0) strcpy(b, "direct"); else snprintf(b, sizeof(b), "%u hops", (unsigned)hops); APPEND(b, strlen(b)); } else { APPEND("{hops}", 6); } diff --git a/examples/companion_radio/MyMeshBot.h b/examples/companion_radio/MyMeshBot.h index 5e81ed49..1a2f1e9e 100644 --- a/examples/companion_radio/MyMeshBot.h +++ b/examples/companion_radio/MyMeshBot.h @@ -134,7 +134,7 @@ bool MyMesh::botInQuietHours() const { // "3fa1:c802"); "direct" if heard directly. The sender's position: its // contact's, when it has one (on a channel, the contact of that name). static char s_bot_path[MAX_PATH_SIZE * 3 + 8]; -static BotInbound s_bot_in = { s_bot_path, 0, 0 }; +static BotInbound s_bot_in = { s_bot_path, 0, 0, false }; static const ContactInfo* s_bot_sender = nullptr; // the asker's contact, if known (Actions by) static bool s_bot_from_pos = false; static int32_t s_bot_from_lat = 0, s_bot_from_lon = 0; @@ -148,7 +148,8 @@ void MyMesh::setBotInbound(const mesh::Packet* pkt, const ContactInfo* sender) { if (s_bot_from_pos) { s_bot_from_lat = sender->gps_lat; s_bot_from_lon = sender->gps_lon; } // A direct-routed packet's path is used up on the way (each repeater takes // its own hash off), so it says nothing about the hops it went through. - if (pkt && pkt->isRouteDirect()) { strcpy(s_bot_path, "known route"); return; } + s_bot_in.routed = pkt && pkt->isRouteDirect(); + if (s_bot_in.routed) { strcpy(s_bot_path, "known route"); return; } if (n == 0) { strcpy(s_bot_path, "direct"); return; } char* o = s_bot_path; for (uint8_t h = 0; h < n; h++) { @@ -322,8 +323,9 @@ bool MyMesh::botCommandReply(const char* cmd, const char* arg, const char* arg2, return true; } if (!strcmp(cmd, "hops")) { - if (hops == 0) strncpy(out, "direct", out_len); // heard directly (0 repeaters) - else snprintf(out, out_len, "%u hops", (unsigned)hops); + if (s_bot_in.routed) strncpy(out, "known route", out_len); // a saved path's hops aren't carried (see !path) + else if (hops == 0) strncpy(out, "direct", out_len); // heard directly (0 repeaters) + else snprintf(out, out_len, "%u hops", (unsigned)hops); out[out_len - 1] = '\0'; return true; } diff --git a/examples/companion_radio/ui-core/BotConfig.h b/examples/companion_radio/ui-core/BotConfig.h index 74cc8fce..b36f49f1 100644 --- a/examples/companion_radio/ui-core/BotConfig.h +++ b/examples/companion_radio/ui-core/BotConfig.h @@ -130,7 +130,7 @@ static void logLine(const BotLogEntry& e, int8_t tz, char* out, size_t n) { e.who[0] ? e.who : "?", e.req, e.reply); } -static const char* const REPLY_PLACEHOLDERS[] = { "{name}", "{hops}", "{path}", "{snr}", "{loc}", "{time}", "{batt}" }; +static const char* const REPLY_PLACEHOLDERS[] = { "{name}", "{hops}", "{path}", "{snr}", "{loc}", "{time}", "{batt}", "{rssi}" }; static const int REPLY_PLACEHOLDER_COUNT = sizeof(REPLY_PLACEHOLDERS) / sizeof(REPLY_PLACEHOLDERS[0]); // Shown value of a text row ("(none)", "(any msg)" for the "*" trigger). diff --git a/examples/companion_radio/ui-core/HopRoute.h b/examples/companion_radio/ui-core/HopRoute.h index 5b719a6e..3a6e1dc3 100644 --- a/examples/companion_radio/ui-core/HopRoute.h +++ b/examples/companion_radio/ui-core/HopRoute.h @@ -47,7 +47,7 @@ public: for (int i = 0; i < gw; i++) if (!isdigit((unsigned char)q[i])) decimal = false; k++; q += gw; - if (*q != ':') break; + if (*q != ':' || !isxdigit((unsigned char)q[1])) break; // "3f:a1: 2 hops": that ':' is the sentence's q++; } if (!ok || k < 2) continue;