7#include <net/settings.h>
8#include <protocol/protocol.h>
9#include <protocol/protocol_oob.h>
10#include <protocol/registry.h>
11#include <run/run_manager.h>
12#include <utils/StringPrint.h>
13#include <utils/logging.h>
14#include <utils/serial_lines.h>
19#include <utils/streaming_json.h>
21FLASHMEM
void trim(
char *str) {
22 unsigned int start = 0, end = strlen(str) - 1;
25 while (isspace(str[start])) {
30 while (end > start && isspace(str[end])) {
35 if (start > 0 || end < (strlen(str) - 1)) {
36 memmove(str, str + start, end - start + 1);
37 str[end - start + 1] =
'\0';
41FLASHMEM
void msg::JsonLinesProtocol::init(
size_t envelope_size) {
42 envelope_in =
new DynamicJsonDocument(envelope_size);
43 envelope_out =
new DynamicJsonDocument(envelope_size);
46FLASHMEM
void msg::JsonLinesProtocol::handleMessage(net::auth::AuthentificationContext &user_context,
48 auto envelope_out = this->envelope_out->to<JsonObject>();
49 auto envelope_in = this->envelope_in->as<JsonObjectConst>();
52 std::string msg_id = envelope_in[
"id"];
53 std::string msg_type = envelope_in[
"type"];
54 bool perf_trace = envelope_in[
"perf_trace"] |
false;
55 elapsedMicros handle_message_time_us;
59 envelope_out[
"id"] = msg_id;
60 envelope_out[
"type"] = msg_type;
61 auto msg_out = envelope_out.createNestedObject(
"msg");
64 auto msg_handler = msg::handlers::Registry::get().lookup(msg_type);
65 auto requiredClearance = msg::handlers::Registry::get().requiredClearance(msg_type);
69 msg_out[
"error"] =
"Unknown message type. Try this message: {'type':'help'}.";
70 }
else if (!user_context.can_do(requiredClearance)) {
72 msg_out[
"error"] =
"User is not authorized for action";
74 auto msg_in = envelope_in[
"msg"].as<JsonObjectConst>();
75 return_code = msg_handler->handle(msg_in, msg_out);
76 if (return_code == msg::handlers::MessageHandler::not_implemented) {
77 return_code = msg_handler->handle(msg_in, msg_out, user_context);
78 if (return_code == msg::handlers::MessageHandler::not_implemented) {
80 auto envelope_and_msg_out = utils::StreamingJson(output);
81 envelope_and_msg_out.begin_dict();
82 envelope_and_msg_out.kv(
"id", msg_id);
83 envelope_and_msg_out.kv(
"type", msg_type);
84 envelope_and_msg_out.key(
"msg");
87 return_code = msg_handler->handle(msg_in, envelope_and_msg_out);
91 if (return_code == msg::handlers::MessageHandler::not_implemented) {
93 envelope_and_msg_out.begin_dict();
94 envelope_and_msg_out.end_dict();
96 if (return_code != 0) {
97 LOG_ALWAYS(
"Error while handling streaming message.")
99 envelope_and_msg_out.kv(
"code", return_code);
101 envelope_and_msg_out.kv(
"perf_handle_message_time_us", handle_message_time_us);
102 envelope_and_msg_out.end_dict();
108 if (return_code != 0) {
110 envelope_out[
"error"] = msg_out[
"error"];
111 envelope_out.remove(
"msg");
112 LOG_ALWAYS(
"Error while handling message.");
115 envelope_out[
"code"] = return_code;
117 envelope_out[
"perf_handle_message_time_us"] = (
unsigned long)handle_message_time_us;
119 serializeJson(envelope_out, output);
125FLASHMEM
void msg::JsonLinesProtocol::process_serial_input(net::auth::AuthentificationContext &user_context) {
130 auto error = deserializeJson(*envelope_in, line);
131 if (error == DeserializationError::Code::EmptyInput) {
135 LOG4(
"Malformed serial line input. Expecting JSON-Lines. Error: ", error.c_str(),
". Input was: ", line);
137 handleMessage(user_context, Serial);
142FLASHMEM
bool msg::JsonLinesProtocol::process_tcp_input(net::EthernetClient &connection,
143 net::auth::AuthentificationContext &user_context) {
144 auto error = deserializeJson(*envelope_in, connection);
145 if (error == DeserializationError::Code::EmptyInput) {
148 LOG2(
"Malformed TCP/IP input. Expecting JSON Lines. Error: ", error.c_str());
150 handleMessage(user_context, connection);
153 if (!connection.writeFully(
"\n"))
159FLASHMEM
void msg::JsonLinesProtocol::process_string_input(
const std::string &envelope_in_str,
160 std::string &envelope_out_str,
161 net::auth::AuthentificationContext &user_context) {
162 auto error = deserializeJson(*envelope_in, envelope_in_str);
163 if (error == DeserializationError::Code::EmptyInput) {
166 envelope_out_str =
"{'error':'Error while parsing JSON, error message: ";
167 envelope_out_str += error.c_str();
168 envelope_out_str +=
"'}\n";
170 utils::StringPrint s;
171 handleMessage(user_context, s);
172 envelope_out_str = s.str();
178FLASHMEM
void msg::JsonLinesProtocol::process_out_of_band_handlers(carrier::Carrier &
carrier_) {
179 if (!run::RunManager::get().queue.empty()) {
181 client::RunStateChangeNotificationHandler run_state_change_handler{broadcast, *envelope_out};
182 client::RunDataNotificationHandler run_data_handler{
carrier_, broadcast};
183 client::StreamingRunDataNotificationHandler alternative_run_data_handler{
carrier_, broadcast};
188 run::RunManager::get().run_next(
carrier_, &run_state_change_handler, &run_data_handler,
189 &alternative_run_data_handler);
FLASHMEM void trim(char *str)
utils::SerialLineReader serial_line_reader