#pragma once #include #include #include "asibfm700_common.h" #include "asibfm700_mount.h" namespace asibfm700 { namespace details { template static constexpr auto merge_arrays(const std::array& arr1, const std::array& arr2) { constexpr auto N = N1 + N2; std::array 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 = [](std::index_sequence) { return std::array{mcc::utils::FNV1aHash(NETMSG_VALID_KEYWORDS[Is])...}; }(std::make_index_sequence()); 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 class Asibfm700NetMessage : public mcc::network::MccNetMessage { protected: using base_t = mcc::network::MccNetMessage; class serializer_t : public base_t::DefaultSerializer { public: template void operator()(const T& value, OR& bytes) { if constexpr (std::same_as) { // serialize just like a vector std::vector 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 std::error_code operator()(IR&& bytes, VT& value) { if constexpr (std::same_as) { // deserialize just like a vector std::vector v; auto ec = base_t::operator()(std::forward(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(bytes), value); } } } _deserializer; public: using base_t::base_t; template std::expected paramValue(size_t idx) { return paramValue(idx, _deserializer); } template std::error_code construct(KT&& key, PTs&&... params) requires mcc::traits::mcc_output_char_range { return construct(_serializer, std::forward(key), std::forward(params)...); } }; class Asibfm700MountNetServer : public mcc::network::MccGenericMountNetworkServer { using base_t = mcc::network::MccGenericMountNetworkServer; public: Asibfm700MountNetServer(asio::io_context& ctx, Asibfm700Mount& mount, std::shared_ptr logger); ~Asibfm700MountNetServer(); private: std::vector handleMessage(std::string_view msg); }; } // namespace asibfm700