Enable the shared terminal on WiFi-only Companions
This commit is contained in:
1 parent
c946adadfe
commit
373c2daebe
7 files changed
+65
-29
No files matched your search
@@ -2,6 +2,15 @@
|
||||
#include <helpers/CompanionJohnConfig.h>
|
||||
#include <helpers/ota/OtaMemoryPolicy.h>
|
||||
|
||||
// The role terminal is also used by WebConfig on WiFi-only Companions. Its
|
||||
// parser and reply tracking do not require a physical USB transport.
|
||||
#if defined(ENABLE_USB_INTERFACE) \
|
||||
|| (defined(ESP32_PLATFORM) && defined(WIFI_SSID) && !defined(WEBCONFIG_DISABLED))
|
||||
#define COMPANION_FEATURE_TEXT_TERMINAL 1
|
||||
#else
|
||||
#define COMPANION_FEATURE_TEXT_TERMINAL 0
|
||||
#endif
|
||||
|
||||
// Features are selected independently so adding a transport or changing an
|
||||
// image-size profile cannot accidentally remove unrelated Companion behavior.
|
||||
// Keep the legacy umbrella as a compatibility input for existing target files;
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
#endif
|
||||
|
||||
#include <helpers/CLICommandUtils.h>
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
#include <helpers/TracePathHelpers.h>
|
||||
#endif
|
||||
|
||||
@@ -224,7 +224,7 @@ static bool save_filter(const ContactInfo& c);
|
||||
// First 16 bytes of SHA-256("#testing"), encoded as base64.
|
||||
#define TESTING_GROUP_PSK "zeXoLPUVZH3LVHp5pPBl0Q=="
|
||||
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
static const char* terminalContactTypeName(uint8_t type) {
|
||||
if (type == ADV_TYPE_CHAT) return "Chat";
|
||||
if (type == ADV_TYPE_REPEATER) return "Repeater";
|
||||
@@ -708,7 +708,7 @@ void MyMesh::onDiscoveredContact(ContactInfo &contact, bool is_new, uint8_t path
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
if (hasTerminalOutput() && _terminal_display.shouldShowAdvert()) {
|
||||
Stream& output = terminalOutput();
|
||||
output.printf("\r\nADVERT from -> %s\r\n", contact.name);
|
||||
@@ -759,7 +759,7 @@ int MyMesh::getRecentlyHeard(AdvertPath dest[], int max_num) {
|
||||
return max_num;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
void MyMesh::onContactVisit(const ContactInfo& contact) {
|
||||
if (contact.type == ADV_TYPE_NONE) return;
|
||||
|
||||
@@ -779,7 +779,7 @@ void MyMesh::onContactPathUpdated(const ContactInfo &contact) {
|
||||
|
||||
scheduleContactWrite(contact);
|
||||
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
if (hasTerminalOutput()) {
|
||||
terminalOutput().printf("\r\nPATH updated -> %s\r\n> ", contact.name);
|
||||
}
|
||||
@@ -815,7 +815,7 @@ void MyMesh::expireExpectedAcks() {
|
||||
|
||||
if (entry.expires_at == now || millisHasNowPassed(entry.expires_at)) {
|
||||
if (!hasActiveRetries(entry.retry_key)) {
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
if (entry.terminal_origin && hasTerminalOutput()) {
|
||||
terminalOutput().print("\r\n ERROR: timed out, no ACK.\r\n> ");
|
||||
}
|
||||
@@ -872,7 +872,7 @@ ContactInfo* MyMesh::processAck(const uint8_t *data) {
|
||||
out_frame, 9);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
if (expected_ack_table[i].terminal_origin && hasTerminalOutput()) {
|
||||
terminalOutput().printf("\r\n Got ACK! (round trip: %lu ms)\r\n> ",
|
||||
(unsigned long)trip_time);
|
||||
@@ -927,7 +927,7 @@ void MyMesh::queueMessage(const ContactInfo &from, uint8_t txt_type, mesh::Packe
|
||||
_serial->writeFrame(frame, 1);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
if (hasTerminalOutput()) {
|
||||
Stream& output = terminalOutput();
|
||||
const char* kind = txt_type == TXT_TYPE_CLI_DATA ? "CLI" : "MSG";
|
||||
@@ -1058,7 +1058,7 @@ void MyMesh::onCommandDataRecv(const ContactInfo &from, mesh::Packet *pkt, uint3
|
||||
markConnectionActive(from); // in case this is from a server, and we have a connection
|
||||
bool terminal_command_reply = false;
|
||||
uint32_t terminal_command_elapsed_millis = 0;
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
terminal_command_reply = _terminal_command.takeReply(
|
||||
from.id.pub_key, _ms->getMillis(), terminal_command_elapsed_millis);
|
||||
if (terminal_command_reply) _terminal_command_target[0] = 0;
|
||||
@@ -1127,7 +1127,7 @@ void MyMesh::onChannelMessageRecv(const mesh::GroupChannel &channel, mesh::Packe
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
if (hasTerminalOutput()
|
||||
&& _terminal_display.shouldShowChannel(is_emergency_channel)) {
|
||||
ChannelDetails details;
|
||||
@@ -1269,18 +1269,18 @@ void MyMesh::onContactResponse(const ContactInfo &contact, const uint8_t *data,
|
||||
|
||||
if (pending_login && memcmp(&pending_login, contact.id.pub_key, 4) == 0) { // check for login response
|
||||
// yes, is response to pending sendLogin()
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
const bool terminal_login_response = _terminal_login_pending
|
||||
&& memcmp(_terminal_login_key, contact.id.pub_key,
|
||||
sizeof(_terminal_login_key)) == 0;
|
||||
#endif
|
||||
int i = 0;
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
bool login_success = false;
|
||||
bool modern_login = false;
|
||||
#endif
|
||||
if (len >= 6 && memcmp(&data[4], "OK", 2) == 0) { // legacy Repeater login OK response
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
login_success = true;
|
||||
#endif
|
||||
out_frame[i++] = PUSH_CODE_LOGIN_SUCCESS;
|
||||
@@ -1288,7 +1288,7 @@ void MyMesh::onContactResponse(const ContactInfo &contact, const uint8_t *data,
|
||||
memcpy(&out_frame[i], contact.id.pub_key, 6);
|
||||
i += 6; // pub_key_prefix
|
||||
} else if (len >= 13 && data[4] == RESP_SERVER_LOGIN_OK) { // new login response
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
login_success = true;
|
||||
modern_login = true;
|
||||
#endif
|
||||
@@ -1314,7 +1314,7 @@ void MyMesh::onContactResponse(const ContactInfo &contact, const uint8_t *data,
|
||||
// no Binary route. Binary logins retain their exact requester even if a
|
||||
// different transport has issued a command in the meantime.
|
||||
writePendingSerialFrame(out_frame, i);
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
if (terminal_login_response) {
|
||||
if (hasTerminalOutput()) {
|
||||
Stream& output = terminalOutput();
|
||||
@@ -1474,7 +1474,7 @@ void MyMesh::onTraceRecv(mesh::Packet *packet, uint32_t tag, uint32_t auth_code,
|
||||
i += path_len >> path_sz;
|
||||
out_frame[i++] = (int8_t)(packet->getSNR() * 4); // extra/final SNR (to this node)
|
||||
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
if (hasTerminalOutput() && _terminal_trace_pending
|
||||
&& tag == _terminal_trace_tag && auth_code == _terminal_trace_auth) {
|
||||
Stream& output = terminalOutput();
|
||||
@@ -1539,7 +1539,7 @@ MyMesh::MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMe
|
||||
_iter_total_count = 0;
|
||||
_iter_table_revision = 0;
|
||||
_cli_rescue = false;
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
_terminal_mode = false;
|
||||
_terminal_output = NULL;
|
||||
_terminal_recipient_set = false;
|
||||
@@ -6776,7 +6776,7 @@ void MyMesh::appendRxPowerSavingAdjustmentNote(char* reply, size_t reply_size,
|
||||
(unsigned)_prefs.rx_ps_level);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
Stream& MyMesh::terminalOutput() {
|
||||
return _terminal_output != NULL ? *_terminal_output : Serial;
|
||||
}
|
||||
@@ -8468,7 +8468,7 @@ void MyMesh::loop() {
|
||||
#ifdef COMPANION_MESH_CLOCK_SYNC
|
||||
_clock_sync.loop();
|
||||
#endif
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
serviceTerminalLogin();
|
||||
serviceTerminalCommand();
|
||||
serviceTerminalTrace();
|
||||
|
||||
@@ -122,7 +122,7 @@ struct AdvertPath {
|
||||
};
|
||||
|
||||
class MyMesh : public BaseChatMesh, public DataStoreHost, public UIShutdownGuard
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
, public ContactVisitor
|
||||
#endif
|
||||
#ifdef WITH_WEBCONFIG
|
||||
@@ -187,7 +187,7 @@ public:
|
||||
void execCommand(char* cmd, char* reply) override;
|
||||
bool supportsCliTerminal() const override { return true; }
|
||||
void execAdminCommand(char* cmd, char* reply) override;
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
bool supportsStreamTerminal() const override { return true; }
|
||||
bool beginStreamTerminal(Stream& output) override;
|
||||
bool ownsStreamTerminal(const Stream& output) const override {
|
||||
@@ -207,7 +207,7 @@ public:
|
||||
bool advert();
|
||||
void enterCLIRescue();
|
||||
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
void enterTerminalMode();
|
||||
void exitTerminalMode();
|
||||
// Clear state owned by the current text-terminal host without changing the
|
||||
@@ -281,7 +281,7 @@ protected:
|
||||
bool onContactPathRecv(ContactInfo& from, uint8_t* in_path, uint8_t in_path_len, uint8_t* out_path, uint8_t out_path_len, uint8_t extra_type, uint8_t* extra, uint8_t extra_len) override;
|
||||
void onDiscoveredContact(ContactInfo &contact, bool is_new, uint8_t path_len, const uint8_t* path) override;
|
||||
void onContactPathUpdated(const ContactInfo &contact) override;
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
void onContactVisit(const ContactInfo& contact) override;
|
||||
#endif
|
||||
ContactInfo* processAck(const uint8_t *data) override;
|
||||
@@ -403,7 +403,7 @@ private:
|
||||
void formatWiFiPowerSaving(char* reply, size_t reply_size) const;
|
||||
void syncWiFiPowerSaving();
|
||||
#endif
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
Stream& terminalOutput();
|
||||
bool hasTerminalOutput() const { return _terminal_output != NULL; }
|
||||
void printTerminalBanner(bool show_binary_stop);
|
||||
@@ -515,7 +515,7 @@ private:
|
||||
bool _iter_start_pending;
|
||||
bool _iter_contact_pending;
|
||||
bool _cli_rescue;
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
bool _terminal_mode;
|
||||
Stream* _terminal_output;
|
||||
mesh::TerminalDisplayFilter _terminal_display;
|
||||
@@ -620,7 +620,7 @@ private:
|
||||
uint8_t text_fingerprint[MAX_HASH_SIZE];
|
||||
uint8_t retry_key[MAX_HASH_SIZE];
|
||||
BaseSerialInterface* reply_route;
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
bool terminal_origin;
|
||||
#endif
|
||||
};
|
||||
@@ -635,7 +635,7 @@ private:
|
||||
void expireExpectedAcks();
|
||||
AckTableEntry* findPendingTextMessage(
|
||||
const uint8_t text_fingerprint[MAX_HASH_SIZE], uint32_t message_timestamp);
|
||||
#ifdef ENABLE_USB_INTERFACE
|
||||
#if COMPANION_FEATURE_TEXT_TERMINAL
|
||||
void rememberTerminalAck(ContactInfo& recipient, const char* text,
|
||||
uint32_t message_timestamp, uint32_t expected_ack,
|
||||
uint32_t est_timeout,
|
||||
|
||||
@@ -1086,6 +1086,14 @@ void MyMesh::endStreamTerminal(Stream& output) {
|
||||
enterUsbTerminalMode();
|
||||
}
|
||||
}
|
||||
#elif defined(WITH_WEBCONFIG)
|
||||
bool MyMesh::beginStreamTerminal(Stream& output) {
|
||||
return enterNetworkTerminalMode(output);
|
||||
}
|
||||
|
||||
void MyMesh::endStreamTerminal(Stream& output) {
|
||||
exitNetworkTerminalMode(output);
|
||||
}
|
||||
#endif
|
||||
|
||||
void halt() {
|
||||
|
||||
Reference in new issue
Block a user