|
|
@ -471,18 +471,77 @@ void _terminalLoop() { |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
#if MQTT_SUPPORT && TERMINAL_MQTT_SUPPORT
|
|
|
|
|
|
|
|
void _terminalMqttSetup() { |
|
|
|
|
|
|
|
mqttRegister([](unsigned int type, const char * topic, const char * payload) { |
|
|
|
if (type == MQTT_CONNECT_EVENT) { |
|
|
|
mqttSubscribe(MQTT_TOPIC_CMD); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if (type == MQTT_MESSAGE_EVENT) { |
|
|
|
String t = mqttMagnitude((char *) topic); |
|
|
|
if (!t.startsWith(MQTT_TOPIC_CMD)) return; |
|
|
|
if (!strlen(payload)) return; |
|
|
|
|
|
|
|
String cmd(payload); |
|
|
|
if (!cmd.endsWith("\r\n") && !cmd.endsWith("\n")) { |
|
|
|
cmd += '\n'; |
|
|
|
} |
|
|
|
|
|
|
|
// TODO: unlike http handler, we have only one output stream
|
|
|
|
// and **must** have a fixed-size output buffer
|
|
|
|
// (wishlist: MQTT client does some magic and we don't buffer twice)
|
|
|
|
schedule_function([cmd]() { |
|
|
|
PrintString buffer(TCP_MSS); |
|
|
|
StreamAdapter<const char*> stream(buffer, cmd.c_str(), cmd.c_str() + cmd.length() + 1); |
|
|
|
|
|
|
|
String out; |
|
|
|
terminal::Terminal handler(stream); |
|
|
|
switch (handler.processLine()) { |
|
|
|
case terminal::Terminal::Result::CommandNotFound: |
|
|
|
out += F("Command not found"); |
|
|
|
break; |
|
|
|
case terminal::Terminal::Result::Command: |
|
|
|
out = std::move(buffer); |
|
|
|
default: |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
if (out.length()) { |
|
|
|
mqttSendRaw(mqttTopic(MQTT_TOPIC_CMD, false).c_str(), out.c_str(), false); |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
return; |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
#endif // MQTT_SUPPORT && TERMINAL_MQTT_SUPPORT
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
// Pubic API
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#if TERMINAL_WEB_API_SUPPORT
|
|
|
|
|
|
|
|
void _terminalWebApiSetup() { |
|
|
|
// XXX: new `apiRegister()` depends that `webServer()` is available, meaning we can't call this setup func
|
|
|
|
// before the `webSetup()` is called. ATM, just make sure it is in order.
|
|
|
|
|
|
|
|
void terminalWebApiSetup() { |
|
|
|
#if API_SUPPORT
|
|
|
|
|
|
|
|
apiRegister(getSetting("termWebApiPath", TERMINAL_WEB_API_PATH), |
|
|
|
[](ApiRequest& api) { |
|
|
|
api.handle([](AsyncWebServerRequest* request) { |
|
|
|
AsyncResponseStream *response = request->beginResponseStream("text/plain"); |
|
|
|
for (auto& command : _terminal.commandNames()) { |
|
|
|
response->print(command); |
|
|
|
for (auto* name : _terminal.names()) { |
|
|
|
response->print(name); |
|
|
|
response->print("\r\n"); |
|
|
|
} |
|
|
|
|
|
|
@ -513,9 +572,7 @@ void _terminalWebApiSetup() { |
|
|
|
return true; |
|
|
|
} |
|
|
|
); |
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
webRequestRegister([](AsyncWebServerRequest* request) { |
|
|
|
String path(F(API_BASE_PATH)); |
|
|
|
path += getSetting("termWebApiPath", TERMINAL_WEB_API_PATH); |
|
|
@ -553,72 +610,11 @@ void _terminalWebApiSetup() { |
|
|
|
|
|
|
|
return true; |
|
|
|
}); |
|
|
|
|
|
|
|
#endif // API_SUPPORT
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
#endif // TERMINAL_WEB_API_SUPPORT
|
|
|
|
|
|
|
|
|
|
|
|
#if MQTT_SUPPORT && TERMINAL_MQTT_SUPPORT
|
|
|
|
|
|
|
|
void _terminalMqttSetup() { |
|
|
|
|
|
|
|
mqttRegister([](unsigned int type, const char * topic, const char * payload) { |
|
|
|
if (type == MQTT_CONNECT_EVENT) { |
|
|
|
mqttSubscribe(MQTT_TOPIC_CMD); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if (type == MQTT_MESSAGE_EVENT) { |
|
|
|
String t = mqttMagnitude((char *) topic); |
|
|
|
if (!t.startsWith(MQTT_TOPIC_CMD)) return; |
|
|
|
if (!strlen(payload)) return; |
|
|
|
|
|
|
|
String cmd(payload); |
|
|
|
if (!cmd.endsWith("\r\n") && !cmd.endsWith("\n")) { |
|
|
|
cmd += '\n'; |
|
|
|
} |
|
|
|
|
|
|
|
// TODO: unlike http handler, we have only one output stream
|
|
|
|
// and **must** have a fixed-size output buffer
|
|
|
|
// (wishlist: MQTT client does some magic and we don't buffer twice)
|
|
|
|
schedule_function([cmd]() { |
|
|
|
PrintString buffer(TCP_MSS); |
|
|
|
StreamAdapter<const char*> stream(buffer, cmd.c_str(), cmd.c_str() + cmd.length() + 1); |
|
|
|
|
|
|
|
String out; |
|
|
|
terminal::Terminal handler(stream); |
|
|
|
switch (handler.processLine()) { |
|
|
|
case terminal::Terminal::Result::CommandNotFound: |
|
|
|
out += F("Command not found"); |
|
|
|
break; |
|
|
|
case terminal::Terminal::Result::Command: |
|
|
|
out = std::move(buffer); |
|
|
|
default: |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
if (out.length()) { |
|
|
|
mqttSendRaw(mqttTopic(MQTT_TOPIC_CMD, false).c_str(), out.c_str(), false); |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
return; |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
#endif // MQTT_SUPPORT && TERMINAL_MQTT_SUPPORT
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
// Pubic API
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
Stream & terminalDefaultStream() { |
|
|
|
return (Stream &) _io; |
|
|
|
} |
|
|
@ -671,11 +667,6 @@ void terminalSetup() { |
|
|
|
.onVisible([](JsonObject& root) { root["cmdVisible"] = 1; }); |
|
|
|
#endif
|
|
|
|
|
|
|
|
// Run terminal command and send back the result. Depends on the terminal command using ctx.output
|
|
|
|
#if WEB_SUPPORT && TERMINAL_WEB_API_SUPPORT
|
|
|
|
_terminalWebApiSetup(); |
|
|
|
#endif
|
|
|
|
|
|
|
|
// Similar to the above, but we allow only very small and in-place outputs.
|
|
|
|
#if MQTT_SUPPORT && TERMINAL_MQTT_SUPPORT
|
|
|
|
_terminalMqttSetup(); |
|
|
|