fix for mqtt base paths - Refactor MQTT subscriptions #173

This commit is contained in:
proddy
2021-11-02 10:42:34 +01:00
parent 54889fec41
commit d78fb53845

View File

@@ -28,40 +28,45 @@ std::vector<Command::CmdFunction> Command::cmdfunctions_;
// takes a path and a json body, parses the data and calls the command // takes a path and a json body, parses the data and calls the command
// the path is leading so if duplicate keys are in the input JSON it will be ignored // the path is leading so if duplicate keys are in the input JSON it will be ignored
// the entry point will be either via the Web API (api/) or MQTT (<base>/)
// returns a return code and json output // returns a return code and json output
uint8_t Command::process(const char * path, const bool authenticated, const JsonObject & input, JsonObject & output) { uint8_t Command::process(const char * path, const bool authenticated, const JsonObject & input, JsonObject & output) {
SUrlParser p; // parse URL for the path names SUrlParser p; // parse URL for the path names
p.parse(path); p.parse(path);
size_t num_paths = p.paths().size();
if (!num_paths) { if (!p.paths().size()) {
output.clear(); output.clear();
output["message"] = "error: invalid path"; output["message"] = "error: invalid path"; // path is empty
return CommandRet::ERROR; return CommandRet::ERROR;
} }
// dump paths, for debugging // check first if it's from API, if so strip the "api/"
// for (auto & folder : p.paths()) { if ((p.paths().front() == "api")) {
// Serial.print(folder.c_str()); p.paths().erase(p.paths().begin());
// }
// must start with either "api" or the hostname
if ((p.paths().front() != "api") && (p.paths().front() != Mqtt::base())) {
output.clear();
output["message"] = "error: invalid path";
return CommandRet::ERRORED;
} else { } else {
p.paths().erase(p.paths().begin()); // remove it // not /api, so must be MQTT path. Check for base and remove it.
num_paths--; if (!strncmp(path, Mqtt::base().c_str(), Mqtt::base().length())) {
char new_path[Mqtt::MQTT_TOPIC_MAX_SIZE];
strncpy(new_path, path, sizeof(new_path));
p.parse(new_path + Mqtt::base().length() + 1); // re-parse the stripped path
} else {
// error
output.clear();
output["message"] = "error: unrecognized path";
return CommandRet::ERRORED;
}
} }
// Serial.println(p.path().c_str()); // dump paths, for debugging
size_t num_paths = p.paths().size(); // re-calculate new path
std::string cmd_s; std::string cmd_s;
int8_t id_n = -1; // default hc int8_t id_n = -1; // default hc
// check for a device // check for a device
// if its not a known device (thermostat, boiler etc) look for any special MQTT subscriptions // if its not a known device (thermostat, boiler etc) look for any special MQTT subscriptions
const char * device_s = nullptr; const char * device_s = nullptr;
if (!p.paths().size()) { if (!num_paths) {
// we must look for the device in the JSON body // we must look for the device in the JSON body
if (input.containsKey("device")) { if (input.containsKey("device")) {
device_s = input["device"]; device_s = input["device"];
@@ -573,5 +578,4 @@ bool SUrlParser::parse(const char * uri) {
return true; return true;
} }
} // namespace emsesp } // namespace emsesp