diff options
Diffstat (limited to 'src/protocol')
-rw-r--r-- | src/protocol/client.cc | 21 | ||||
-rw-r--r-- | src/protocol/client.h | 23 | ||||
-rw-r--r-- | src/protocol/exceptions.h | 22 | ||||
-rw-r--r-- | src/protocol/input.cc | 118 | ||||
-rw-r--r-- | src/protocol/input.h | 32 | ||||
-rw-r--r-- | src/protocol/response.cc | 19 | ||||
-rw-r--r-- | src/protocol/response.h | 44 |
7 files changed, 279 insertions, 0 deletions
diff --git a/src/protocol/client.cc b/src/protocol/client.cc new file mode 100644 index 0000000..40ffa36 --- /dev/null +++ b/src/protocol/client.cc @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: BSD-3-Clause + +#include "client.h" + +namespace protocol { + +void BaseClient::setDevice(std::shared_ptr<voltronic::Device> device) { + device_ = std::move(device); +} + +std::pair<std::shared_ptr<char>, size_t> BaseClient::runOnDevice(std::string& raw) { + size_t bufSize = 256; + std::shared_ptr<char> buf(new char[bufSize]); + size_t responseSize = device_->run( + (const u8*)raw.c_str(), raw.size(), + (u8*)buf.get(), bufSize); + + return std::pair<std::shared_ptr<char>, size_t>(buf, responseSize); +} + +}
\ No newline at end of file diff --git a/src/protocol/client.h b/src/protocol/client.h new file mode 100644 index 0000000..8ed49aa --- /dev/null +++ b/src/protocol/client.h @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: BSD-3-Clause + +#ifndef INVERTER_TOOLS_PROTOCOL_CLIENT_H +#define INVERTER_TOOLS_PROTOCOL_CLIENT_H + +#include "../voltronic/device.h" +#include "response.h" + +namespace protocol { + +class BaseClient { +private: + std::shared_ptr<voltronic::Device> device_; + +public: + void setDevice(std::shared_ptr<voltronic::Device> device); + virtual std::shared_ptr<BaseResponse> execute(int commandType, std::vector<std::string>& arguments) = 0; + std::pair<std::shared_ptr<char>, size_t> runOnDevice(std::string& raw); +}; + +} + +#endif //INVERTER_TOOLS_PROTOCOL_CLIENT_H diff --git a/src/protocol/exceptions.h b/src/protocol/exceptions.h new file mode 100644 index 0000000..4febe28 --- /dev/null +++ b/src/protocol/exceptions.h @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: BSD-3-Clause + +#ifndef INVERTER_TOOLS_PROTOCOL_EXCEPTIONS_H +#define INVERTER_TOOLS_PROTOCOL_EXCEPTIONS_H + +#include <stdexcept> + +namespace protocol { + +class InvalidResponseError : public std::runtime_error { +public: + using std::runtime_error::runtime_error; +}; + +class ParseError : public InvalidResponseError { +public: + using InvalidResponseError::InvalidResponseError; +}; + +} + +#endif //INVERTER_TOOLS_PROTOCOL_EXCEPTIONS_H diff --git a/src/protocol/input.cc b/src/protocol/input.cc new file mode 100644 index 0000000..a44ee3e --- /dev/null +++ b/src/protocol/input.cc @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: BSD-3-Clause + +#include <stdexcept> +#include <sstream> +#include <vector> +#include <string> + +#ifdef INVERTERCTL +#include <getopt.h> +#endif + +#include "../util.h" +#include "input.h" + +namespace protocol { + +#ifdef INVERTERCTL +void get_args(CommandInput* input, std::vector<std::string>& arguments, size_t count) { + for (size_t i = 0; i < count; i++) { + if (optind < input->argc && *input->argv[optind] != '-') + arguments.emplace_back(input->argv[optind++]); + else { + std::ostringstream error; + error << "this command requires " << count << " argument"; + if (count > 1) + error << "s"; + throw std::invalid_argument(error.str()); + } + } +} +#endif + +#ifdef INVERTERD +void get_args(CommandInput* input, std::vector<std::string>& arguments, size_t count) { + if (input->argv->size() < count) { + std::ostringstream error; + error << "this command requires " << count << " argument"; + if (count > 1) + error << "s"; + throw std::invalid_argument(error.str()); + } + + for (size_t i = 0; i < count; i++) + arguments.emplace_back((*input->argv)[i]); +} +#endif + +void validate_date_args(const std::string* ys, const std::string* ms, const std::string* ds) { + static const std::string err_year = "invalid year"; + static const std::string err_month = "invalid month"; + static const std::string err_day = "invalid day"; + + int y, m = 0, d = 0; + + // validate year + if (!is_numeric(*ys) || ys->size() != 4) + throw std::invalid_argument(err_year); + + y = std::stoi(*ys); + if (y < 2000 || y > 2099) + throw std::invalid_argument(err_year); + + // validate month + if (ms != nullptr) { + if (!is_numeric(*ms) || ms->size() > 2) + throw std::invalid_argument(err_month); + + m = std::stoi(*ms); + if (m < 1 || m > 12) + throw std::invalid_argument(err_month); + } + + // validate day + if (ds != nullptr) { + if (!is_numeric(*ds) || ds->size() > 2) + throw std::invalid_argument(err_day); + + d = std::stoi(*ds); + if (d < 1 || d > 31) + throw std::invalid_argument(err_day); + } + + if (y != 0 && m != 0 && d != 0) { + if (!is_date_valid(y, m, d)) + throw std::invalid_argument("invalid date"); + } +} + +void validate_time_args(const std::string* hs, const std::string* ms, const std::string* ss) { + static const std::string err_hour = "invalid hour"; + static const std::string err_minute = "invalid minute"; + static const std::string err_second = "invalid second"; + + unsigned h, m, s; + + if (!is_numeric(*hs) || hs->size() > 2) + throw std::invalid_argument(err_hour); + + h = static_cast<unsigned>(std::stoul(*hs)); + if (h > 23) + throw std::invalid_argument(err_hour); + + if (!is_numeric(*ms) || ms->size() > 2) + throw std::invalid_argument(err_minute); + + m = static_cast<unsigned>(std::stoul(*ms)); + if (m > 59) + throw std::invalid_argument(err_minute); + + if (!is_numeric(*ss) || ss->size() > 2) + throw std::invalid_argument(err_second); + + s = static_cast<unsigned>(std::stoul(*ss)); + if (s > 59) + throw std::invalid_argument(err_second); +} + +}
\ No newline at end of file diff --git a/src/protocol/input.h b/src/protocol/input.h new file mode 100644 index 0000000..1791f9a --- /dev/null +++ b/src/protocol/input.h @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: BSD-3-Clause + +#ifndef INVERTER_TOOLS_PROTOCOL_COMMON_COMMANDS_H +#define INVERTER_TOOLS_PROTOCOL_COMMON_COMMANDS_H + +#include <string> +#include <vector> + +#define GET_ARGS(__len__) protocol::get_args((protocol::CommandInput*)input, arguments, (__len__)) + +namespace protocol { + +#ifdef INVERTERCTL +struct CommandInput { + int argc; + char **argv; +}; +#endif + +#ifdef INVERTERD +struct CommandInput { + std::vector<std::string>* argv; +}; +#endif + +void get_args(CommandInput* input, std::vector<std::string>& arguments, size_t count); +void validate_date_args(const std::string* ys, const std::string* ms, const std::string* ds); +void validate_time_args(const std::string* hs, const std::string* ms, const std::string* ss); + +} + +#endif //INVERTER_TOOLS_PROTOCOL_COMMON_COMMANDS_H diff --git a/src/protocol/response.cc b/src/protocol/response.cc new file mode 100644 index 0000000..0d6eeab --- /dev/null +++ b/src/protocol/response.cc @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: BSD-3-Clause + +#include "response.h" + +namespace protocol { + +BaseResponse::BaseResponse(std::shared_ptr<char> raw, size_t rawSize) + : raw_(std::move(raw)), rawSize_(rawSize) +{} + + +formattable_ptr ErrorResponse::format(formatter::Format format) +{ + return std::shared_ptr<formatter::Status>( + new formatter::Status(format, false, error_) + ); +} + +} diff --git a/src/protocol/response.h b/src/protocol/response.h new file mode 100644 index 0000000..e6e258d --- /dev/null +++ b/src/protocol/response.h @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: BSD-3-Clause + +#ifndef INVERTER_TOOLS_PROTOCOL_RESPONSE_H +#define INVERTER_TOOLS_PROTOCOL_RESPONSE_H + +#include <memory> +#include "../formatter/formatter.h" + +namespace protocol { + +typedef std::shared_ptr<formatter::Formattable> formattable_ptr; + +class BaseResponse { +protected: + std::shared_ptr<char> raw_; + size_t rawSize_; + +public: + BaseResponse(std::shared_ptr<char> raw, size_t rawSize); + virtual ~BaseResponse() = default; + virtual bool validate() = 0; + virtual void unpack() = 0; + virtual formattable_ptr format(formatter::Format format) = 0; +}; + + +class ErrorResponse : public BaseResponse { +private: + std::string error_; + +public: + explicit ErrorResponse(std::string error) + : BaseResponse(nullptr, 0), error_(std::move(error)) {} + + bool validate() override { + return true; + } + void unpack() override {} + formattable_ptr format(formatter::Format format) override; +}; + +} + +#endif //INVERTER_TOOLS_PROTOCOL_RESPONSE_H |