Fix up commands parsing, implement proper json parsing

This commit is contained in:
Lorow
2024-11-09 20:19:37 +01:00
parent 0b0318bc99
commit aaf8fa41cf
8 changed files with 91 additions and 27 deletions

View File

@@ -1,4 +1,4 @@
idf_component_register(SRCS "CommandManager/CommandManager.cpp"
INCLUDE_DIRS "CommandManager"
REQUIRES ProjectConfig
REQUIRES ProjectConfig cJSON
)

View File

@@ -6,16 +6,52 @@ std::unique_ptr<Command> CommandManager::createCommand(CommandType type)
{
case CommandType::PING:
return std::make_unique<PingCommand>();
break;
case CommandType::UPDATE_WIFI:
return std::make_unique<UpdateWifiCommand>(projectConfig);
case CommandType::SET_WIFI:
return std::make_unique<setWiFiCommand>(projectConfig);
default:
return nullptr;
}
}
CommandResult CommandManager::executeFromJson(const std::string *json)
CommandResult CommandManager::executeFromJson(std::string *json)
{
// parse it, get a type of command, grab a command from the map based on type
// parse the payload json, call execute on the command and return the result
cJSON *parsedJson = cJSON_Parse(json->c_str());
if (parsedJson == nullptr)
return CommandResult::getErrorResult("Invalid JSON");
const cJSON *commandData = nullptr;
const cJSON *commands = cJSON_GetObjectItem(parsedJson, "commands");
cJSON_ArrayForEach(commandData, commands)
{
const cJSON *commandTypeString = cJSON_GetObjectItem(commandData, "command");
const cJSON *commandPayload = cJSON_GetObjectItem(commandData, "data");
auto commandType = commandTypeMap.at(std::string(commandTypeString->valuestring));
auto command = createCommand(commandType);
if (command == nullptr)
{
cJSON_Delete(parsedJson);
return CommandResult::getErrorResult("Unknown command");
}
std::string commandPayloadString = std::string(cJSON_Print(commandPayload));
cJSON_Delete(parsedJson);
return command->execute(commandPayloadString);
}
cJSON_Delete(parsedJson);
return CommandResult::getErrorResult("Commands missing");
}
CommandResult CommandManager::executeFromType(CommandType type, std::string *json)
{
auto command = createCommand(type);
if (command == nullptr)
{
return CommandResult::getErrorResult("Unknown command");
}
return command->execute(*json);
}

View File

@@ -1,3 +1,6 @@
#ifndef COMMANDMANAGER_HPP
#define COMMANDMANAGER_HPP
#include <ProjectConfig.hpp>
#include <memory>
#include <string>
@@ -6,8 +9,10 @@
#include "CommandResult.hpp"
#include "CommandSchema.hpp"
#include "Commands.hpp"
#include <cJSON.h>
const enum CommandType {
enum CommandType
{
None,
PING,
SET_WIFI,
@@ -32,5 +37,8 @@ public:
CommandManager(ProjectConfig &projectConfig) : projectConfig(projectConfig) {};
std::unique_ptr<Command> createCommand(CommandType type);
CommandResult executeFromJson(const std::string *json);
};
CommandResult executeFromJson(std::string *json);
CommandResult executeFromType(CommandType type, std::string *json);
};
#endif

View File

@@ -1,3 +1,6 @@
#ifndef COMMAND_RESULT
#define COMMAND_RESULT
class CommandResult
{
private:
@@ -37,3 +40,5 @@ public:
std::string getSuccessMessage() const { return successMessage.value(); };
std::string getErrorMessage() const { return errorMessage.value(); }
};
#endif

View File

@@ -1,3 +1,5 @@
#ifndef COMMAND_SCHEMA_HPP
#define COMMAND_SCHEMA_HPP
class BasePayload
{
};
@@ -23,4 +25,6 @@ class UpdateWifiPayload : public BasePayload
class deleteNetworkPayload : public BasePayload
{
std::optional<std::string> networkName;
};
};
#endif

View File

@@ -1 +1,16 @@
#include "Commands.hpp"
CommandResult PingCommand::execute(std::string &jsonPayload)
{
return CommandResult::getSuccessResult("pong");
}
WifiPayload setConfigCommand::parsePayload(std::string &jsonPayload)
{
return WifiPayload();
}
CommandResult setConfigCommand::execute(std::string &jsonPayload)
{
return CommandResult::getSuccessResult("pong");
}

View File

@@ -1,3 +1,5 @@
#ifndef COMMANDS_HPP
#define COMMANDS_HPP
#include <ProjectConfig.hpp>
#include <memory>
#include <string>
@@ -8,31 +10,25 @@
class Command
{
public:
virtual ~Command() = default;
virtual CommandResult execute(const std::shared_ptr<BasePayload> &payload) = 0;
virtual std::shared_ptr<BasePayload> parsePayload(const std::string *json) = 0;
virtual CommandResult execute(std::string &jsonPayload) = 0;
};
class PingCommand : public Command
{
public:
CommandResult execute(const std::shared_ptr<BasePayload> &payload);
std::shared_ptr<BasePayload> parsePayload(const std::string *json);
CommandResult execute(std::string &jsonPayload) override;
};
class setConfigCommand : public Command
class setWiFiCommand : public Command
{
public:
CommandResult execute(const std::shared_ptr<BasePayload> &payload);
std::shared_ptr<BasePayload> parsePayload(const std::string *json);
};
class UpdateWifiCommand : public Command
{
private:
ProjectConfig &projectConfig;
public:
UpdateWifiCommand(ProjectConfig &projectConfig) : projectConfig(projectConfig) {};
CommandResult execute(const std::shared_ptr<BasePayload> &payload);
setWiFiCommand(ProjectConfig &projectConfig) : projectConfig(projectConfig) {};
CommandResult execute(std::string &jsonPayload) override;
WifiPayload parsePayload(std::string &jsonPayload);
};
#endif

View File

@@ -84,4 +84,4 @@ public:
size_t freeEntries();
};
#endif PREFERENCES_HPP
#endif