aboutsummaryrefslogtreecommitdiff
path: root/src/protocol
diff options
context:
space:
mode:
Diffstat (limited to 'src/protocol')
-rw-r--r--src/protocol/client.cc21
-rw-r--r--src/protocol/client.h23
-rw-r--r--src/protocol/exceptions.h22
-rw-r--r--src/protocol/input.cc118
-rw-r--r--src/protocol/input.h32
-rw-r--r--src/protocol/response.cc19
-rw-r--r--src/protocol/response.h44
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