add /raw endpoint

This commit is contained in:
John
2021-11-05 19:51:08 +01:00
parent 7a567e69fb
commit 523df25eb0
5 changed files with 175 additions and 65 deletions
+3 -1
View File
@@ -9,6 +9,8 @@
* fix for message after debian install * fix for message after debian install
* fix for replacing already existing message definitions * fix for replacing already existing message definitions
* fix missing length in CSV dump for some data types * fix missing length in CSV dump for some data types
* fix some missing data type lengths in "grab decode" result
* fix for injecting several messages via command line args
## Features ## Features
* added DTM and BDZ data types * added DTM and BDZ data types
@@ -19,7 +21,7 @@
* added some PIC calibration data to "ebuspicloader" verbose output * added some PIC calibration data to "ebuspicloader" verbose output
* added support for upcoming adapter 3 firmware enhancements * added support for upcoming adapter 3 firmware enhancements
* added config override path * added config override path
* added support for adding message definition via HTTP port * added support for adding message definition, retrieving data types and raw messages to HTTP port
* added "--mqttverbose" option * added "--mqttverbose" option
## Breaking Changes ## Breaking Changes
+55 -10
View File
@@ -145,6 +145,18 @@ paths:
500: 500:
description: General error. description: General error.
content: { } content: { }
/raw:
get:
summary: Retrieve raw data from grabbed and/or decoded messages.
parameters:
- $ref: '#/components/parameters/sinceQuery'
responses:
200:
description: Success
content:
application/json;charset=utf-8:
schema:
$ref: '#/components/schemas/RawMessages'
/{file}: /{file}:
get: get:
summary: Retrieve a particular file. summary: Retrieve a particular file.
@@ -384,19 +396,11 @@ components:
type: string type: string
description: the message comment (only with verbose). description: the message comment (only with verbose).
master: master:
type: array $ref: '#/components/schemas/Symbols'
description: the last seen master data bytes (only with raw and if available). description: the last seen master data bytes (only with raw and if available).
items:
maximum: 255
minimum: 0
type: integer
slave: slave:
type: array $ref: '#/components/schemas/Symbols'
description: the last seen slave data bytes (only with raw and if available). description: the last seen slave data bytes (only with raw and if available).
items:
maximum: 255
minimum: 0
type: integer
fields: fields:
type: object type: object
additionalProperties: additionalProperties:
@@ -411,6 +415,15 @@ components:
def). def).
items: items:
$ref: '#/components/schemas/FieldDef' $ref: '#/components/schemas/FieldDef'
Symbols:
description: master or slave data bytes.
type: array
minItems: 1
maximum: 32
items:
maximum: 255
minimum: 0
type: integer
Field: Field:
type: object type: object
properties: properties:
@@ -531,6 +544,38 @@ components:
$ref: '#/components/schemas/Global' $ref: '#/components/schemas/Global'
additionalProperties: additionalProperties:
$ref: '#/components/schemas/Circuit' $ref: '#/components/schemas/Circuit'
RawMessage:
type: object
description: raw message seen on the bus.
properties:
master:
$ref: '#/components/schemas/Symbols'
description: the last seen master data bytes (only with raw and if available).
slave:
$ref: '#/components/schemas/Symbols'
description: the last seen slave data bytes (only with raw and if available).
lastup:
minimum: 0
type: integer
description: the time in UTC seconds of the last update of the message (0
for never).
count:
type: number
description: number of times the master part was seen.
circuit:
type: string
description: name of the circuit in case of an already associated message definition.
name:
type: string
description: name of the message in case of an already associated message definition.
required:
- master
- count
RawMessages:
type: array
description: raw messages seen on the bus.
items:
$ref: '#/components/schemas/RawMessage'
responses: responses:
BadRequest: BadRequest:
description: Invalid request parameters. description: Invalid request parameters.
+29 -7
View File
@@ -253,16 +253,36 @@ bool decodeType(const DataType* type, const SymbolString& input, size_t length,
return !first; return !first;
} }
bool GrabbedMessage::dump(bool unknown, MessageMap* messages, bool first, bool decode, ostringstream* output, bool GrabbedMessage::dump(bool unknown, MessageMap* messages, bool first, OutputFormat outputFormat,
bool isDirectMode) const { ostringstream* output, bool isDirectMode) const {
Message* message = messages->find(m_lastMaster); Message* message = messages->find(m_lastMaster);
if (unknown && message) { if (unknown && message) {
return false; return false;
} }
if (!first) { if (!first) {
if (outputFormat & OF_JSON) {
*output << ",";
} else {
*output << endl; *output << endl;
} }
}
symbol_t dstAddress = m_lastMaster[1]; symbol_t dstAddress = m_lastMaster[1];
if (outputFormat & OF_JSON) {
*output << "\n{";
if (m_lastMaster.dumpJson(false, output)) {
*output << ", ";
if (dstAddress != BROADCAST && !isMaster(dstAddress) && m_lastSlave.dumpJson(false, output)) {
*output << ", ";
}
}
*output << "\"count\": " << static_cast<unsigned>(m_count);
*output << ", \"lastup\": " << setw(0) << dec << m_lastTime;
if (message) {
*output << ", \"circuit\": \"" << message->getCircuit() << "\""
<< ", \"name\": \"" << message->getName() << "\"";
}
*output << "}";
} else {
*output << m_lastMaster.getStr(); *output << m_lastMaster.getStr();
if (dstAddress != BROADCAST && !isMaster(dstAddress)) { if (dstAddress != BROADCAST && !isMaster(dstAddress)) {
*output << (isDirectMode ? " " : " / ") << m_lastSlave.getStr(); *output << (isDirectMode ? " " : " / ") << m_lastSlave.getStr();
@@ -273,7 +293,10 @@ bool GrabbedMessage::dump(bool unknown, MessageMap* messages, bool first, bool d
*output << ": " << message->getCircuit() << " " << message->getName(); *output << ": " << message->getCircuit() << " " << message->getName();
} }
} }
if (decode) { }
if (!(outputFormat & OF_DEFINITION) || (outputFormat & OF_JSON)) {
return true;
}
DataTypeList *types = DataTypeList::getInstance(); DataTypeList *types = DataTypeList::getInstance();
if (!types) { if (!types) {
return true; return true;
@@ -314,7 +337,6 @@ bool GrabbedMessage::dump(bool unknown, MessageMap* messages, bool first, bool d
} }
} }
} }
}
return true; return true;
} }
@@ -1610,10 +1632,10 @@ bool BusHandler::enableGrab(bool enable) {
return true; return true;
} }
void BusHandler::formatGrabResult(bool unknown, bool decode, ostringstream* output, bool isDirectMode, void BusHandler::formatGrabResult(bool unknown, OutputFormat outputFormat, ostringstream* output, bool isDirectMode,
time_t since, time_t until) const { time_t since, time_t until) const {
if (!m_grabMessages) { if (!m_grabMessages) {
if (!isDirectMode) { if (!isDirectMode && !(outputFormat & OF_JSON)) {
*output << "grab disabled"; *output << "grab disabled";
} }
return; return;
@@ -1624,7 +1646,7 @@ void BusHandler::formatGrabResult(bool unknown, bool decode, ostringstream* outp
|| (until > 0 && it.second.getLastTime() >= until)) { || (until > 0 && it.second.getLastTime() >= until)) {
continue; continue;
} }
if (it.second.dump(unknown, m_messages, first, decode, output, isDirectMode)) { if (it.second.dump(unknown, m_messages, first, outputFormat, output, isDirectMode)) {
first = false; first = false;
} }
} }
+4 -4
View File
@@ -334,12 +334,12 @@ class GrabbedMessage {
* @param unknown whether to dump only if this message is unknown. * @param unknown whether to dump only if this message is unknown.
* @param messages the @a MessageMap instance for resolving known @a Message instances. * @param messages the @a MessageMap instance for resolving known @a Message instances.
* @param first whether this is the first message to be added to the output. * @param first whether this is the first message to be added to the output.
* @param decode whether to add decoding hints. * @param outputFormat the @a OutputFormat options to use.
* @param output the @a ostringstream to format the messages to. * @param output the @a ostringstream to format the messages to.
* @param isDirectMode true for direct mode, false for grab command. * @param isDirectMode true for direct mode, false for grab command.
* @return whether the message was added to the output. * @return whether the message was added to the output.
*/ */
bool dump(bool unknown, MessageMap* messages, bool first, bool decode, ostringstream* output, bool dump(bool unknown, MessageMap* messages, bool first, OutputFormat outputFormat, ostringstream* output,
bool isDirectMode = false) const; bool isDirectMode = false) const;
@@ -538,13 +538,13 @@ class BusHandler : public WaitThread {
/** /**
* Format the grabbed messages to the @a ostringstream. * Format the grabbed messages to the @a ostringstream.
* @param unknown whether to dump only unknown messages. * @param unknown whether to dump only unknown messages.
* @param decode whether to add decoding hints. * @param outputFormat the @a OutputFormat options to use.
* @param output the @a ostringstream to format the messages to. * @param output the @a ostringstream to format the messages to.
* @param isDirectMode true for direct mode, false for grab command. * @param isDirectMode true for direct mode, false for grab command.
* @param since the start time from which to add received messages (inclusive), or 0 for all. * @param since the start time from which to add received messages (inclusive), or 0 for all.
* @param until the end time to which to add received messages (exclusive), or 0 for all. * @param until the end time to which to add received messages (exclusive), or 0 for all.
*/ */
void formatGrabResult(bool unknown, bool decode, ostringstream* output, bool isDirectMode = false, void formatGrabResult(bool unknown, OutputFormat outputFormat, ostringstream* output, bool isDirectMode = false,
time_t since = 0, time_t until = 0) const; time_t since = 0, time_t until = 0) const;
/** /**
+44 -3
View File
@@ -434,14 +434,14 @@ void MainLoop::run() {
} }
if (settings.listenWithUnknown || settings.listenOnlyUnknown) { if (settings.listenWithUnknown || settings.listenOnlyUnknown) {
if (m_busHandler->isGrabEnabled()) { if (m_busHandler->isGrabEnabled()) {
m_busHandler->formatGrabResult(true, false, &ostream, true, since, now); m_busHandler->formatGrabResult(true, OF_NONE, &ostream, true, since, now);
} else { } else {
m_busHandler->enableGrab(true); // needed for listening to all messages m_busHandler->enableGrab(true); // needed for listening to all messages
} }
} }
} else if (settings.mode == cm_direct) { } else if (settings.mode == cm_direct) {
if (m_busHandler->isGrabEnabled()) { if (m_busHandler->isGrabEnabled()) {
m_busHandler->formatGrabResult(false, false, &ostream, true, since, now); m_busHandler->formatGrabResult(false, OF_NONE, &ostream, true, since, now);
} }
} }
// send result to client // send result to client
@@ -1639,7 +1639,7 @@ result_t MainLoop::executeGrab(const vector<string>& args, ostringstream* ostrea
} }
} }
if (!invalid) { if (!invalid) {
m_busHandler->formatGrabResult(onlyUnknown, decode, ostream); m_busHandler->formatGrabResult(onlyUnknown, decode ? OF_DEFINITION : OF_NONE, ostream);
return RESULT_OK; return RESULT_OK;
} }
} }
@@ -2218,6 +2218,47 @@ result_t MainLoop::executeGet(const vector<string>& args, bool* connected, ostri
return formatHttpResult(ret, type, ostream); return formatHttpResult(ret, type, ostream);
} }
if (uri == "/raw") {
time_t since = 0, until = 0;
bool onlyUnknown = false;
if (args.size() > argPos) {
string query = args[argPos];
istringstream stream(query);
string token;
while (getline(stream, token, '&')) {
size_t pos = token.find('=');
string qname, value;
if (pos != string::npos) {
qname = token.substr(0, pos);
value = token.substr(pos + 1);
} else {
qname = token;
}
if (qname == "since") {
since = parseInt(value.c_str(), 10, 0, 0xffffffff, &ret);
} else if (qname == "unknown") {
onlyUnknown = parseBoolQuery(value);
}
if (ret != RESULT_OK) {
break;
}
}
}
if (ret == RESULT_OK) {
*ostream << "[";
if (since > 0) {
time_t now;
time(&now);
until = now-1;
}
m_busHandler->formatGrabResult(onlyUnknown, OF_JSON, ostream, false, since, until);
*ostream << "\n]";
type = 6;
}
*connected = false;
return formatHttpResult(ret, type, ostream);
}
if (uri.length() < 1 || uri[0] != '/' || uri.find("//") != string::npos || uri.find("..") != string::npos) { if (uri.length() < 1 || uri[0] != '/' || uri.find("//") != string::npos || uri.find("..") != string::npos) {
ret = RESULT_ERR_INVALID_ARG; ret = RESULT_ERR_INVALID_ARG;
} else { } else {