151 lines
4.3 KiB
C++
151 lines
4.3 KiB
C++
#pragma once
|
|
|
|
#include <mcc_netserver.h>
|
|
#include <mcc_netserver_proto.h>
|
|
|
|
#include "asibfm700_common.h"
|
|
#include "asibfm700_mount.h"
|
|
|
|
namespace asibfm700
|
|
{
|
|
|
|
namespace details
|
|
{
|
|
|
|
template <typename VT, size_t N1, size_t N2>
|
|
static constexpr auto merge_arrays(const std::array<VT, N1>& arr1, const std::array<VT, N2>& arr2)
|
|
{
|
|
constexpr auto N = N1 + N2;
|
|
std::array<VT, N> res;
|
|
|
|
for (size_t i = 0; i < N1; ++i) {
|
|
res[i] = arr1[i];
|
|
}
|
|
|
|
for (size_t i = N1; i < N; ++i) {
|
|
res[i] = arr2[i - N1];
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
} // namespace details
|
|
|
|
constexpr static std::string_view ASIBFM700_COMMPROTO_KEYWORD_METEO_STR{"METEO"};
|
|
|
|
struct Asibfm700NetMessageValidKeywords {
|
|
static constexpr std::array NETMSG_VALID_KEYWORDS =
|
|
details::merge_arrays(mcc::network::MccNetMessageValidKeywords::NETMSG_VALID_KEYWORDS,
|
|
std::array{ASIBFM700_COMMPROTO_KEYWORD_METEO_STR});
|
|
|
|
// hashes of valid keywords
|
|
static constexpr std::array NETMSG_VALID_KEYWORD_HASHES = []<size_t... Is>(std::index_sequence<Is...>) {
|
|
return std::array{mcc::utils::FNV1aHash(NETMSG_VALID_KEYWORDS[Is])...};
|
|
}(std::make_index_sequence<NETMSG_VALID_KEYWORDS.size()>());
|
|
|
|
constexpr static const size_t* isKeywordValid(std::string_view key)
|
|
{
|
|
const auto hash = mcc::utils::FNV1aHash(key);
|
|
|
|
for (auto const& h : NETMSG_VALID_KEYWORD_HASHES) {
|
|
if (h == hash) {
|
|
return &h;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
};
|
|
|
|
template <mcc::traits::mcc_char_range BYTEREPR_T = std::string_view>
|
|
class Asibfm700NetMessage : public mcc::network::MccNetMessage<BYTEREPR_T, Asibfm700NetMessageValidKeywords>
|
|
{
|
|
protected:
|
|
using base_t = mcc::network::MccNetMessage<BYTEREPR_T, Asibfm700NetMessageValidKeywords>;
|
|
|
|
class serializer_t : public base_t::DefaultSerializer
|
|
{
|
|
public:
|
|
template <typename T, mcc::traits::mcc_output_char_range OR>
|
|
void operator()(const T& value, OR& bytes)
|
|
{
|
|
if constexpr (std::same_as<T, Asibfm700CCTE::meteo_t>) {
|
|
// serialize just like a vector
|
|
std::vector<double> meteo{value.temperature, value.humidity, value.pressure};
|
|
base_t::operator()(meteo, bytes);
|
|
} else {
|
|
base_t::operator()(value, bytes);
|
|
}
|
|
}
|
|
} _serializer;
|
|
|
|
|
|
class deserializer_t : public base_t::DefaultDeserializer
|
|
{
|
|
public:
|
|
template <mcc::traits::mcc_input_char_range IR, typename VT>
|
|
std::error_code operator()(IR&& bytes, VT& value)
|
|
{
|
|
if constexpr (std::same_as<VT, Asibfm700CCTE::meteo_t>) {
|
|
// deserialize just like a vector
|
|
|
|
std::vector<double> v;
|
|
auto ec = base_t::operator()(std::forward<IR>(bytes), v);
|
|
if (ec) {
|
|
return ec;
|
|
}
|
|
|
|
if (v.size() < 3) {
|
|
return std::make_error_code(std::errc::invalid_argument);
|
|
}
|
|
|
|
value.temperature = v[0];
|
|
value.humidity = v[1];
|
|
value.pressure = v[2];
|
|
|
|
return {};
|
|
} else {
|
|
return base_t::operator()(std::forward<IR>(bytes), value);
|
|
}
|
|
}
|
|
} _deserializer;
|
|
|
|
|
|
|
|
public:
|
|
using base_t::base_t;
|
|
|
|
template <typename T>
|
|
std::expected<T, std::error_code> paramValue(size_t idx)
|
|
{
|
|
return paramValue<T>(idx, _deserializer);
|
|
}
|
|
|
|
|
|
|
|
template <mcc::traits::mcc_input_char_range KT, typename... PTs>
|
|
std::error_code construct(KT&& key, PTs&&... params)
|
|
requires mcc::traits::mcc_output_char_range<BYTEREPR_T>
|
|
{
|
|
return construct(_serializer, std::forward<KT>(key), std::forward<PTs>(params)...);
|
|
}
|
|
};
|
|
|
|
|
|
|
|
class Asibfm700MountNetServer : public mcc::network::MccGenericMountNetworkServer<Asibfm700Logger>
|
|
{
|
|
using base_t = mcc::network::MccGenericMountNetworkServer<Asibfm700Logger>;
|
|
|
|
public:
|
|
template <mcc::traits::mcc_range_of_input_char_range R = decltype(Asibfm700Logger::LOGGER_DEFAULT_FORMAT)>
|
|
Asibfm700MountNetServer(asio::io_context& ctx, Asibfm700Mount& mount, std::shared_ptr<spdlog::logger> logger);
|
|
|
|
~Asibfm700MountNetServer();
|
|
|
|
private:
|
|
std::vector<char> handleMessage(std::string_view msg);
|
|
};
|
|
|
|
} // namespace asibfm700
|