Public Access
LoRa Scanner: MeshCore by default, and its public channel read
The MeshCore preset is the default for a new device, in the Settings and in the radio before the Scanner is opened. The setting now accepts it: it only took the 7 Meshtastic presets, so MeshCore picked in the App was not saved. Messages on MeshCore's public channel are decrypted with the channel's published key (AES-128, checked with 2 bytes of HMAC-SHA256): the row shows who says they sent it and the start of the text, the details the sender, the time and the whole text. Other channels and private messages stay encrypted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0162FokPdvY2KsS4NBfwyWPk
This commit is contained in:
@@ -2,7 +2,9 @@
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
|
||||
#include "meshcore_channel.h"
|
||||
#include "meshcore_packet.h"
|
||||
#include "meshtastic_header.h"
|
||||
#include "meshtastic_presets.h"
|
||||
@@ -22,14 +24,31 @@ std::string hex(const uint8_t* p, size_t n) {
|
||||
return out;
|
||||
}
|
||||
|
||||
// `room` characters at most: a node's name is cut to fit.
|
||||
// Onto lines of `cols` characters at most, broken at spaces where there are some.
|
||||
void wrapInto(std::vector<std::string>& lines, std::string text, size_t cols) {
|
||||
while (text.size() > cols) {
|
||||
size_t cut = text.rfind(' ', cols);
|
||||
if (cut == std::string::npos || cut == 0) cut = cols;
|
||||
lines.push_back(text.substr(0, cut));
|
||||
text.erase(0, text[cut] == ' ' ? cut + 1 : cut);
|
||||
}
|
||||
if (!text.empty()) lines.push_back(text);
|
||||
}
|
||||
|
||||
// `room` characters at most: a node's name or a message is cut to fit.
|
||||
std::string meshcoreRow(const meshcore::Packet& m, size_t room) {
|
||||
std::string out = meshcore::payloadShort(m.type);
|
||||
std::string hops = m.hops ? " " + std::to_string(m.hops) + "h" : "";
|
||||
meshcore::Advert a;
|
||||
meshcore::Discover d;
|
||||
meshcore::ChannelText t;
|
||||
if (meshcore::parseDiscover(m, d)) {
|
||||
out = d.response ? "here " + hex(d.id, 2) : "who's there?";
|
||||
} else if (meshcore::readChannelText(m, t)) {
|
||||
out = (t.sender.empty() ? "" : t.sender + ": ") + t.text;
|
||||
out = out.substr(0, room > hops.size() ? room - hops.size() : 0);
|
||||
while (!out.empty() && out.back() == ' ') out.pop_back();
|
||||
return out + hops;
|
||||
} else if (meshcore::parseAdvert(m, a)) {
|
||||
size_t used = out.size() + 1 + hops.size();
|
||||
out += " " + (a.name.empty() ? hex(a.key, 2) : a.name.substr(0, room > used ? room - used : 0));
|
||||
@@ -90,6 +109,14 @@ std::vector<std::string> meshcoreLines(const uint8_t* data, size_t len) {
|
||||
} else if (m.addressed() && m.payloadLen >= 4) {
|
||||
std::snprintf(s, sizeof s, "From ..%02x to ..%02x, %u B encrypted", m.payload[1], m.payload[0], static_cast<unsigned>(m.payloadLen - 4));
|
||||
lines.push_back(s);
|
||||
} else if (meshcore::ChannelText t; meshcore::readChannelText(m, t)) {
|
||||
lines.push_back(std::string("On the ") + t.channel + " channel" + (t.sender.empty() ? "" : ", from " + t.sender));
|
||||
std::time_t sent = t.timestamp;
|
||||
std::tm tm{};
|
||||
gmtime_r(&sent, &tm);
|
||||
std::strftime(s, sizeof s, "Sent %Y-%m-%d %H:%M:%S UTC", &tm);
|
||||
lines.push_back(s);
|
||||
wrapInto(lines, t.text, 38);
|
||||
} else if (m.group() && m.payloadLen >= 3) {
|
||||
std::snprintf(s, sizeof s, "Channel 0x%02x%s, %u B encrypted", m.payload[0], m.payload[0] == meshcore::kPublicChannelHash ? " (public?)" : "",
|
||||
static_cast<unsigned>(m.payloadLen - 3));
|
||||
|
||||
Reference in New Issue
Block a user