This commit is contained in:
2025-10-29 15:07:53 +03:00
parent 78e4bb182c
commit bc300bb3de
6 changed files with 508 additions and 166 deletions

View File

@@ -899,154 +899,317 @@ public:
MccGenericMountNetworkServer(asio::io_context& ctx, MountT& mount, LoggerCtorArgsTs&&... log_args)
: base_t(ctx, {}, std::forward<LoggerCtorArgsTs>(log_args)...)
{
base_t::_handleMessageFunc = [mount = std::move(mount), this](std::string_view command) {
using mount_error_t = decltype(mount)::error_t;
// to avoid possible compiler optimization (one needs to catch 'mount' strictly by reference)
auto* mount_ptr = &mount;
base_t::_handleMessageFunc = [mount_ptr, this](std::string_view command) {
using mount_error_t = typename MountT::error_t;
mount_error_t m_err;
MccNetMessage input_msg;
MccNetMessage<handle_message_func_result_t> output_msg;
std::error_code err{};
if (auto ec = parseMessage(command, input_msg)) {
auto ec = parseMessage(command, input_msg);
if (ec) {
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ERROR_STR, ec);
} else {
if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR)) { // strange!
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, command);
} else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_SERVER_ERROR_STR)) { // ??!!!
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, command);
} else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_RESTART_SERVER_STR)) {
this->restart();
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, command);
} else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_INIT_STR)) {
m_err = mount.initMount();
if (m_err) {
err = mcc_deduce_error_code(m_err, MccGenericMountNetworkServerErrorCode::ERROR_MOUNT_INIT);
}
} else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_STOP_STR)) {
m_err = mount.stopMount();
if (m_err) {
err = mcc_deduce_error_code(m_err, MccGenericMountNetworkServerErrorCode::ERROR_MOUNT_STOP);
}
} else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_SLEW_STR)) {
m_err = mount.slewToTarget(false);
if (m_err) {
err = mcc_deduce_error_code(m_err, MccGenericMountNetworkServerErrorCode::ERROR_MOUNT_SLEW);
}
} else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_MOVE_STR)) {
m_err = mount.slewToTarget(true);
if (m_err) {
err = mcc_deduce_error_code(m_err, MccGenericMountNetworkServerErrorCode::ERROR_MOUNT_MOVE);
}
} else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_TRACK_STR)) {
m_err = mount.trackTarget();
if (m_err) {
err = mcc_deduce_error_code(m_err, MccGenericMountNetworkServerErrorCode::ERROR_MOUNT_TRACK);
}
} else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_COORDFMT_STR)) {
auto v = input_msg.paramValue<MccCoordinateSerializer::SerializedCoordFormat>(0);
if (v) {
_coordFormat = v.value();
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, command);
} else {
err = v.error();
}
} else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_COORDPREC_STR)) {
auto v = input_msg.paramValue<MccCoordinateSerializer::SexagesimalCoordPrec>(0);
if (v) {
_coordPrec = v.value();
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, command);
} else {
err = v.error();
}
} else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_TARGET_STR)) {
// by default return ICRS coordinates
MccCelestialPoint cp{.pair_kind = MccCoordPairKind::COORDS_KIND_RADEC_ICRS};
auto sz = input_msg.paramSize();
if (sz) { // set or get operation
auto vc = input_msg.paramValue<MccCelestialPoint>(0); // is it set operation?
if (vc) { // coordinates are given - set operation
auto m_err = mount.setPointingTarget(vc.value());
if (m_err) {
if (m_err) {
err = mcc_deduce_error_code(
m_err, MccGenericMountNetworkServerErrorCode::ERROR_MOUNT_SET_TARGET);
}
} else {
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, command);
}
} else {
auto vp = input_msg.paramValue<MccCoordPairKind>(0);
if (vp) { // coordinate pair kind is given
cp.pair_kind = vp.value();
err = coordsFromTelemetryData(mount, true, cp);
if (!err) {
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR,
MCC_COMMPROTO_KEYWORD_TARGET_STR, cp);
}
} else { // invalid command!!!
err = vp.error();
}
}
} else { // get operation
err = coordsFromTelemetryData(mount, true, cp);
if (!err) {
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, MCC_COMMPROTO_KEYWORD_TARGET_STR,
_coordFormat, _coordPrec, cp);
}
}
} else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_MOUNT_STR)) {
// by default return ICRS coordinates
MccCelestialPoint cp{.pair_kind = MccCoordPairKind::COORDS_KIND_RADEC_ICRS};
if (input_msg.paramSize()) { // ccordinate pair kind is given
auto vp = input_msg.paramValue<MccCoordPairKind>(0);
if (vp) { // coordinate pair kind is given
cp.pair_kind = vp.value();
err = coordsFromTelemetryData(mount, false, cp);
if (!err) {
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR,
MCC_COMMPROTO_KEYWORD_MOUNT_STR, cp);
}
} else { // invalid command!!!
err = vp.error();
}
} else {
err = coordsFromTelemetryData(mount, false, cp);
if (!err) {
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, MCC_COMMPROTO_KEYWORD_MOUNT_STR,
_coordFormat, _coordPrec, cp);
}
}
} else {
err = std::make_error_code(std::errc::invalid_argument);
}
if (err) { // send error description
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ERROR_STR, err);
}
// else { // send ACK with copy of the input message
// output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, command);
// }
output_msg = handleMessage<decltype(output_msg)>(input_msg, mount_ptr);
}
return output_msg.byteRepr();
// std::error_code err{};
// if (auto ec = parseMessage(command, input_msg)) {
// output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ERROR_STR, ec);
// } else {
// if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR)) { // strange!
// output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, command);
// } else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_SERVER_ERROR_STR)) { // ??!!!
// output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, command);
// } else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_RESTART_SERVER_STR)) {
// this->restart();
// output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, command);
// } else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_INIT_STR)) {
// m_err = mount_ptr->initMount();
// if (m_err) {
// err = mcc_deduce_error_code(m_err, MccGenericMountNetworkServerErrorCode::ERROR_MOUNT_INIT);
// }
// } else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_STOP_STR)) {
// m_err = mount_ptr->stopMount();
// if (m_err) {
// err = mcc_deduce_error_code(m_err, MccGenericMountNetworkServerErrorCode::ERROR_MOUNT_STOP);
// }
// } else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_SLEW_STR)) {
// m_err = mount_ptr->slewToTarget(false);
// if (m_err) {
// err = mcc_deduce_error_code(m_err, MccGenericMountNetworkServerErrorCode::ERROR_MOUNT_SLEW);
// }
// } else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_MOVE_STR)) {
// m_err = mount_ptr->slewToTarget(true);
// if (m_err) {
// err = mcc_deduce_error_code(m_err, MccGenericMountNetworkServerErrorCode::ERROR_MOUNT_MOVE);
// }
// } else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_TRACK_STR)) {
// m_err = mount_ptr->trackTarget();
// if (m_err) {
// err = mcc_deduce_error_code(m_err, MccGenericMountNetworkServerErrorCode::ERROR_MOUNT_TRACK);
// }
// } else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_COORDFMT_STR)) {
// auto v = input_msg.paramValue<MccCoordinateSerializer::SerializedCoordFormat>(0);
// if (v) {
// _coordFormat = v.value();
// output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, command);
// } else {
// err = v.error();
// }
// } else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_COORDPREC_STR)) {
// auto v = input_msg.paramValue<MccCoordinateSerializer::SexagesimalCoordPrec>(0);
// if (v) {
// _coordPrec = v.value();
// output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, command);
// } else {
// err = v.error();
// }
// } else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_TARGET_STR)) {
// // by default return ICRS coordinates
// MccCelestialPoint cp{.pair_kind = MccCoordPairKind::COORDS_KIND_RADEC_ICRS};
// auto sz = input_msg.paramSize();
// if (sz) { // set or get operation
// auto vc = input_msg.paramValue<MccCelestialPoint>(0); // is it set operation?
// if (vc) { // coordinates are given - set
// operation
// auto m_err = mount_ptr->setPointingTarget(vc.value());
// if (m_err) {
// if (m_err) {
// err = mcc_deduce_error_code(
// m_err, MccGenericMountNetworkServerErrorCode::ERROR_MOUNT_SET_TARGET);
// }
// } else {
// output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, command);
// }
// } else {
// auto vp = input_msg.paramValue<MccCoordPairKind>(0);
// if (vp) { // coordinate pair kind is given
// cp.pair_kind = vp.value();
// err = coordsFromTelemetryData(*mount_ptr, true, cp);
// if (!err) {
// output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR,
// MCC_COMMPROTO_KEYWORD_TARGET_STR, cp);
// }
// } else { // invalid command!!!
// err = vp.error();
// }
// }
// } else { // get operation
// err = coordsFromTelemetryData(*mount_ptr, true, cp);
// if (!err) {
// output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR,
// MCC_COMMPROTO_KEYWORD_TARGET_STR,
// _coordFormat, _coordPrec, cp);
// }
// }
// } else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_MOUNT_STR)) {
// // by default return ICRS coordinates
// MccCelestialPoint cp{.pair_kind = MccCoordPairKind::COORDS_KIND_RADEC_ICRS};
// if (input_msg.paramSize()) { // ccordinate pair kind is given
// auto vp = input_msg.paramValue<MccCoordPairKind>(0);
// if (vp) { // coordinate pair kind is given
// cp.pair_kind = vp.value();
// err = coordsFromTelemetryData(*mount_ptr, false, cp);
// if (!err) {
// output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR,
// MCC_COMMPROTO_KEYWORD_MOUNT_STR, cp);
// }
// } else { // invalid command!!!
// err = vp.error();
// }
// } else {
// err = coordsFromTelemetryData(*mount_ptr, false, cp);
// if (!err) {
// output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR,
// MCC_COMMPROTO_KEYWORD_MOUNT_STR,
// _coordFormat, _coordPrec, cp);
// }
// }
// } else {
// err = std::make_error_code(std::errc::invalid_argument);
// }
// if (err) { // send error description
// output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ERROR_STR, err);
// }
// // else { // send ACK with copy of the input message
// // output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, command);
// // }
// }
// return output_msg.byteRepr();
};
}
virtual ~MccGenericMountNetworkServer() {}
protected:
// MccNetMessageCoordFormat _coordFormat{MccNetMessageCoordFormat::CFMT_SGM}; // ouput coordinates format
// MccNetMessageCoordPrec _coordPrec{2, 1};
MccCoordinateSerializer::SerializedCoordFormat _coordFormat{
MccCoordinateSerializer::SerializedCoordFormat::CFMT_SGM};
MccCoordinateSerializer::SexagesimalCoordPrec _coordPrec{2, 1};
template <typename RESULT_MSG_T, typename INPUT_MSG_T, mcc_generic_mount_c MountT>
RESULT_MSG_T handleMessage(const INPUT_MSG_T& input_msg, MountT* mount_ptr)
requires(
std::derived_from<RESULT_MSG_T,
MccNetMessage<typename RESULT_MSG_T::byte_repr_t, typename RESULT_MSG_T::valid_keys_t>> &&
std::derived_from<INPUT_MSG_T,
MccNetMessage<typename INPUT_MSG_T::byte_repr_t, typename INPUT_MSG_T::valid_keys_t>>)
{
using mount_error_t = typename MountT::error_t;
mount_error_t m_err;
RESULT_MSG_T output_msg;
std::error_code err{};
if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR)) { // strange!
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, input_msg.byteRepr());
} else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_SERVER_ERROR_STR)) { // ??!!!
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, input_msg.byteRepr());
} else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_RESTART_SERVER_STR)) {
this->restart();
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, input_msg.byteRepr());
} else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_STATUS_STR)) {
auto st = mount_ptr->status(); // according to mcc_generic_mount_c 'st' is formattable
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, MCC_COMMPROTO_KEYWORD_STATUS_STR, st);
} else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_INIT_STR)) {
m_err = mount_ptr->initMount();
if (m_err) {
err = mcc_deduce_error_code(m_err, MccGenericMountNetworkServerErrorCode::ERROR_MOUNT_INIT);
} else {
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, MCC_COMMPROTO_KEYWORD_INIT_STR);
}
} else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_STOP_STR)) {
m_err = mount_ptr->stopMount();
if (m_err) {
err = mcc_deduce_error_code(m_err, MccGenericMountNetworkServerErrorCode::ERROR_MOUNT_STOP);
} else {
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, MCC_COMMPROTO_KEYWORD_STOP_STR);
}
} else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_SLEW_STR)) {
m_err = mount_ptr->slewToTarget(false);
if (m_err) {
err = mcc_deduce_error_code(m_err, MccGenericMountNetworkServerErrorCode::ERROR_MOUNT_SLEW);
} else {
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, MCC_COMMPROTO_KEYWORD_SLEW_STR);
}
} else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_MOVE_STR)) {
m_err = mount_ptr->slewToTarget(true);
if (m_err) {
err = mcc_deduce_error_code(m_err, MccGenericMountNetworkServerErrorCode::ERROR_MOUNT_MOVE);
} else {
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, MCC_COMMPROTO_KEYWORD_MOVE_STR);
}
} else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_TRACK_STR)) {
m_err = mount_ptr->trackTarget();
if (m_err) {
err = mcc_deduce_error_code(m_err, MccGenericMountNetworkServerErrorCode::ERROR_MOUNT_TRACK);
} else {
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, MCC_COMMPROTO_KEYWORD_TRACK_STR);
}
} else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_COORDFMT_STR)) {
auto v = input_msg.template paramValue<MccCoordinateSerializer::SerializedCoordFormat>(0);
if (v) {
_coordFormat = v.value();
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, input_msg.byteRepr());
} else {
err = v.error();
}
} else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_COORDPREC_STR)) {
auto v = input_msg.template paramValue<MccCoordinateSerializer::SexagesimalCoordPrec>(0);
if (v) {
_coordPrec = v.value();
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, input_msg.byteRepr());
} else {
err = v.error();
}
} else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_TARGET_STR)) {
// by default return ICRS coordinates
MccCelestialPoint cp{.pair_kind = MccCoordPairKind::COORDS_KIND_RADEC_ICRS};
auto sz = input_msg.paramSize();
if (sz) { // set or get operation
auto vc = input_msg.template paramValue<MccCelestialPoint>(0); // is it set operation?
if (vc) { // coordinates are given - set operation
auto m_err = mount_ptr->setPointingTarget(vc.value());
if (m_err) {
if (m_err) {
err = mcc_deduce_error_code(m_err,
MccGenericMountNetworkServerErrorCode::ERROR_MOUNT_SET_TARGET);
}
} else {
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, input_msg.byteRepr());
}
} else {
auto vp = input_msg.template paramValue<MccCoordPairKind>(0);
if (vp) { // coordinate pair kind is given
cp.pair_kind = vp.value();
err = coordsFromTelemetryData(*mount_ptr, true, cp);
if (!err) {
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, MCC_COMMPROTO_KEYWORD_TARGET_STR,
cp);
}
} else { // invalid command!!!
err = vp.error();
}
}
} else { // get operation
err = coordsFromTelemetryData(*mount_ptr, true, cp);
if (!err) {
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, MCC_COMMPROTO_KEYWORD_TARGET_STR,
_coordFormat, _coordPrec, cp);
}
}
} else if (input_msg.withKey(MCC_COMMPROTO_KEYWORD_MOUNT_STR)) {
// by default return ICRS coordinates
MccCelestialPoint cp{.pair_kind = MccCoordPairKind::COORDS_KIND_RADEC_ICRS};
if (input_msg.paramSize()) { // ccordinate pair kind is given
auto vp = input_msg.template paramValue<MccCoordPairKind>(0);
if (vp) { // coordinate pair kind is given
cp.pair_kind = vp.value();
err = coordsFromTelemetryData(*mount_ptr, false, cp);
if (!err) {
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, MCC_COMMPROTO_KEYWORD_MOUNT_STR, cp);
}
} else { // invalid command!!!
err = vp.error();
}
} else {
err = coordsFromTelemetryData(*mount_ptr, false, cp);
if (!err) {
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ACK_STR, MCC_COMMPROTO_KEYWORD_MOUNT_STR,
_coordFormat, _coordPrec, cp);
}
}
} else {
err = std::make_error_code(std::errc::invalid_argument);
}
if (err) { // send error description
output_msg.construct(MCC_COMMPROTO_KEYWORD_SERVER_ERROR_STR, err);
}
return output_msg;
}
template <typename MSG_T>
std::error_code parseMessage(std::string_view msg_bytes, MSG_T& msg)
{