From 496fe37d44e20ab2a66cc5f4443cfff683c39ff2 Mon Sep 17 00:00:00 2001 From: Julian Oes Date: Tue, 4 Jun 2024 14:54:40 +1200 Subject: [PATCH] rtk: encode RTCM data in base64 This makes it possible to use this in language wrappers such as Python. --- proto | 2 +- .../plugins/rtk/include/plugins/rtk/rtk.h | 2 +- src/mavsdk/plugins/rtk/rtk.cpp | 4 +- src/mavsdk/plugins/rtk/rtk_impl.cpp | 12 +-- src/mavsdk_server/src/generated/rtk/rtk.pb.cc | 76 +++++++++--------- src/mavsdk_server/src/generated/rtk/rtk.pb.h | 78 +++++++++---------- .../src/plugins/rtk/rtk_service_impl.h | 4 +- 7 files changed, 90 insertions(+), 88 deletions(-) diff --git a/proto b/proto index 4fb7d97e72..1cd12e9212 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit 4fb7d97e72ea6cbfb10a570f53e208b1fc286c10 +Subproject commit 1cd12e9212ab1a7405e5f6d8dc432ad47d9977ef diff --git a/src/mavsdk/plugins/rtk/include/plugins/rtk/rtk.h b/src/mavsdk/plugins/rtk/include/plugins/rtk/rtk.h index 9bd2751703..d21175f3e7 100644 --- a/src/mavsdk/plugins/rtk/include/plugins/rtk/rtk.h +++ b/src/mavsdk/plugins/rtk/include/plugins/rtk/rtk.h @@ -62,7 +62,7 @@ class Rtk : public PluginBase { * @brief RTCM data type */ struct RtcmData { - std::string data{}; /**< @brief The data encoded as a string */ + std::string data_base64{}; /**< @brief The data encoded as a base64 string */ }; /** diff --git a/src/mavsdk/plugins/rtk/rtk.cpp b/src/mavsdk/plugins/rtk/rtk.cpp index e98100c0aa..176f3e2d45 100644 --- a/src/mavsdk/plugins/rtk/rtk.cpp +++ b/src/mavsdk/plugins/rtk/rtk.cpp @@ -24,14 +24,14 @@ Rtk::Result Rtk::send_rtcm_data(RtcmData rtcm_data) const bool operator==(const Rtk::RtcmData& lhs, const Rtk::RtcmData& rhs) { - return (rhs.data == lhs.data); + return (rhs.data_base64 == lhs.data_base64); } std::ostream& operator<<(std::ostream& str, Rtk::RtcmData const& rtcm_data) { str << std::setprecision(15); str << "rtcm_data:" << '\n' << "{\n"; - str << " data: " << rtcm_data.data << '\n'; + str << " data_base64: " << rtcm_data.data_base64 << '\n'; str << '}'; return str; } diff --git a/src/mavsdk/plugins/rtk/rtk_impl.cpp b/src/mavsdk/plugins/rtk/rtk_impl.cpp index 8c76e510cd..25e1cca0a4 100644 --- a/src/mavsdk/plugins/rtk/rtk_impl.cpp +++ b/src/mavsdk/plugins/rtk/rtk_impl.cpp @@ -1,5 +1,5 @@ #include "rtk_impl.h" -#include "unused.h" +#include "base64.h" namespace mavsdk { @@ -30,8 +30,10 @@ Rtk::Result RtkImpl::send_rtcm_data(Rtk::RtcmData rtcm_data) { constexpr size_t field_len = MAVLINK_MSG_GPS_RTCM_DATA_FIELD_DATA_LEN; + std::vector decoded = base64_decode(rtcm_data.data_base64); + const size_t num_packets_required = - rtcm_data.data.size() / field_len + (rtcm_data.data.size() % field_len == 0 ? 0 : 1); + decoded.size() / field_len + (decoded.size() % field_len == 0 ? 0 : 1); // The maximum is 4 times the 180 bytes because we only have two bits to // denote the fragment ID. @@ -40,11 +42,11 @@ Rtk::Result RtkImpl::send_rtcm_data(Rtk::RtcmData rtcm_data) } // Copy length before we change it. - size_t bytes_to_send = rtcm_data.data.size(); + size_t bytes_to_send = decoded.size(); // The mavlink helpers memcpy, so we need to make sure we're not // copying from where we shouldn't. - rtcm_data.data.resize(num_packets_required * field_len); + decoded.resize(num_packets_required * field_len); for (size_t i = 0; i < num_packets_required; ++i) { const uint8_t flags = @@ -59,7 +61,7 @@ Rtk::Result RtkImpl::send_rtcm_data(Rtk::RtcmData rtcm_data) &message, flags, static_cast(std::min(field_len, bytes_to_send)), - reinterpret_cast(rtcm_data.data.c_str() + (i * field_len))); + (decoded.data() + (i * field_len))); return message; })) { ++_sequence; diff --git a/src/mavsdk_server/src/generated/rtk/rtk.pb.cc b/src/mavsdk_server/src/generated/rtk/rtk.pb.cc index 2cff847a1a..09c1efbe3c 100644 --- a/src/mavsdk_server/src/generated/rtk/rtk.pb.cc +++ b/src/mavsdk_server/src/generated/rtk/rtk.pb.cc @@ -48,7 +48,7 @@ PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT inline constexpr RtcmData::Impl_::Impl_( ::_pbi::ConstantInitialized) noexcept - : data_( + : data_base64_( &::google::protobuf::internal::fixed_address_empty_string, ::_pbi::ConstantInitialized()), _cached_size_{0} {} @@ -121,7 +121,7 @@ const ::uint32_t TableStruct_rtk_2frtk_2eproto::offsets[] PROTOBUF_SECTION_VARIA ~0u, // no _inlined_string_donated_ ~0u, // no _split_ ~0u, // no sizeof(Split) - PROTOBUF_FIELD_OFFSET(::mavsdk::rpc::rtk::RtcmData, _impl_.data_), + PROTOBUF_FIELD_OFFSET(::mavsdk::rpc::rtk::RtcmData, _impl_.data_base64_), PROTOBUF_FIELD_OFFSET(::mavsdk::rpc::rtk::SendRtcmDataRequest, _impl_._has_bits_), PROTOBUF_FIELD_OFFSET(::mavsdk::rpc::rtk::SendRtcmDataRequest, _internal_metadata_), ~0u, // no _extensions_ @@ -170,20 +170,20 @@ static const ::_pb::Message* const file_default_instances[] = { }; const char descriptor_table_protodef_rtk_2frtk_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { "\n\rrtk/rtk.proto\022\016mavsdk.rpc.rtk\032\024mavsdk_" - "options.proto\"\030\n\010RtcmData\022\014\n\004data\030\001 \001(\t\"" - "B\n\023SendRtcmDataRequest\022+\n\trtcm_data\030\001 \001(" - "\0132\030.mavsdk.rpc.rtk.RtcmData\"E\n\024SendRtcmD" - "ataResponse\022-\n\nrtk_result\030\001 \001(\0132\031.mavsdk" - ".rpc.rtk.RtkResult\"\313\001\n\tRtkResult\0220\n\006resu" - "lt\030\001 \001(\0162 .mavsdk.rpc.rtk.RtkResult.Resu" - "lt\022\022\n\nresult_str\030\002 \001(\t\"x\n\006Result\022\022\n\016RESU" - "LT_UNKNOWN\020\000\022\022\n\016RESULT_SUCCESS\020\001\022\023\n\017RESU" - "LT_TOO_LONG\020\002\022\024\n\020RESULT_NO_SYSTEM\020\005\022\033\n\027R" - "ESULT_CONNECTION_ERROR\020\0062m\n\nRtkService\022_" - "\n\014SendRtcmData\022#.mavsdk.rpc.rtk.SendRtcm" - "DataRequest\032$.mavsdk.rpc.rtk.SendRtcmDat" - "aResponse\"\004\200\265\030\001B\031\n\rio.mavsdk.rtkB\010RtkPro" - "tob\006proto3" + "options.proto\"\037\n\010RtcmData\022\023\n\013data_base64" + "\030\001 \001(\t\"B\n\023SendRtcmDataRequest\022+\n\trtcm_da" + "ta\030\001 \001(\0132\030.mavsdk.rpc.rtk.RtcmData\"E\n\024Se" + "ndRtcmDataResponse\022-\n\nrtk_result\030\001 \001(\0132\031" + ".mavsdk.rpc.rtk.RtkResult\"\313\001\n\tRtkResult\022" + "0\n\006result\030\001 \001(\0162 .mavsdk.rpc.rtk.RtkResu" + "lt.Result\022\022\n\nresult_str\030\002 \001(\t\"x\n\006Result\022" + "\022\n\016RESULT_UNKNOWN\020\000\022\022\n\016RESULT_SUCCESS\020\001\022" + "\023\n\017RESULT_TOO_LONG\020\002\022\024\n\020RESULT_NO_SYSTEM" + "\020\005\022\033\n\027RESULT_CONNECTION_ERROR\020\0062m\n\nRtkSe" + "rvice\022_\n\014SendRtcmData\022#.mavsdk.rpc.rtk.S" + "endRtcmDataRequest\032$.mavsdk.rpc.rtk.Send" + "RtcmDataResponse\"\004\200\265\030\001B\031\n\rio.mavsdk.rtkB" + "\010RtkProtob\006proto3" }; static const ::_pbi::DescriptorTable* const descriptor_table_rtk_2frtk_2eproto_deps[1] = { @@ -193,7 +193,7 @@ static ::absl::once_flag descriptor_table_rtk_2frtk_2eproto_once; const ::_pbi::DescriptorTable descriptor_table_rtk_2frtk_2eproto = { false, false, - 570, + 577, descriptor_table_protodef_rtk_2frtk_2eproto, "rtk/rtk.proto", &descriptor_table_rtk_2frtk_2eproto_once, @@ -265,7 +265,7 @@ RtcmData::RtcmData(::google::protobuf::Arena* arena) inline PROTOBUF_NDEBUG_INLINE RtcmData::Impl_::Impl_( ::google::protobuf::internal::InternalVisibility visibility, ::google::protobuf::Arena* arena, const Impl_& from) - : data_(arena, from.data_), + : data_base64_(arena, from.data_base64_), _cached_size_{0} {} RtcmData::RtcmData( @@ -283,7 +283,7 @@ RtcmData::RtcmData( inline PROTOBUF_NDEBUG_INLINE RtcmData::Impl_::Impl_( ::google::protobuf::internal::InternalVisibility visibility, ::google::protobuf::Arena* arena) - : data_(arena), + : data_base64_(arena), _cached_size_{0} {} inline void RtcmData::SharedCtor(::_pb::Arena* arena) { @@ -296,7 +296,7 @@ RtcmData::~RtcmData() { } inline void RtcmData::SharedDtor() { ABSL_DCHECK(GetArena() == nullptr); - _impl_.data_.Destroy(); + _impl_.data_base64_.Destroy(); _impl_.~Impl_(); } @@ -307,7 +307,7 @@ PROTOBUF_NOINLINE void RtcmData::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - _impl_.data_.ClearToEmpty(); + _impl_.data_base64_.ClearToEmpty(); _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } @@ -319,7 +319,7 @@ const char* RtcmData::_InternalParse( PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 -const ::_pbi::TcParseTable<0, 1, 0, 36, 2> RtcmData::_table_ = { +const ::_pbi::TcParseTable<0, 1, 0, 43, 2> RtcmData::_table_ = { { 0, // no _has_bits_ 0, // no _extensions_ @@ -333,21 +333,21 @@ const ::_pbi::TcParseTable<0, 1, 0, 36, 2> RtcmData::_table_ = { &_RtcmData_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback }, {{ - // string data = 1; + // string data_base64 = 1; {::_pbi::TcParser::FastUS1, - {10, 63, 0, PROTOBUF_FIELD_OFFSET(RtcmData, _impl_.data_)}}, + {10, 63, 0, PROTOBUF_FIELD_OFFSET(RtcmData, _impl_.data_base64_)}}, }}, {{ 65535, 65535 }}, {{ - // string data = 1; - {PROTOBUF_FIELD_OFFSET(RtcmData, _impl_.data_), 0, 0, + // string data_base64 = 1; + {PROTOBUF_FIELD_OFFSET(RtcmData, _impl_.data_base64_), 0, 0, (0 | ::_fl::kFcSingular | ::_fl::kUtf8String | ::_fl::kRepAString)}, }}, // no aux_entries {{ - "\27\4\0\0\0\0\0\0" + "\27\13\0\0\0\0\0\0" "mavsdk.rpc.rtk.RtcmData" - "data" + "data_base64" }}, }; @@ -358,11 +358,11 @@ ::uint8_t* RtcmData::_InternalSerialize( ::uint32_t cached_has_bits = 0; (void)cached_has_bits; - // string data = 1; - if (!this->_internal_data().empty()) { - const std::string& _s = this->_internal_data(); + // string data_base64 = 1; + if (!this->_internal_data_base64().empty()) { + const std::string& _s = this->_internal_data_base64(); ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( - _s.data(), static_cast(_s.length()), ::google::protobuf::internal::WireFormatLite::SERIALIZE, "mavsdk.rpc.rtk.RtcmData.data"); + _s.data(), static_cast(_s.length()), ::google::protobuf::internal::WireFormatLite::SERIALIZE, "mavsdk.rpc.rtk.RtcmData.data_base64"); target = stream->WriteStringMaybeAliased(1, _s, target); } @@ -383,10 +383,10 @@ ::size_t RtcmData::ByteSizeLong() const { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - // string data = 1; - if (!this->_internal_data().empty()) { + // string data_base64 = 1; + if (!this->_internal_data_base64().empty()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize( - this->_internal_data()); + this->_internal_data_base64()); } return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); @@ -408,8 +408,8 @@ void RtcmData::MergeImpl(::google::protobuf::Message& to_msg, const ::google::pr ::uint32_t cached_has_bits = 0; (void) cached_has_bits; - if (!from._internal_data().empty()) { - _this->_internal_set_data(from._internal_data()); + if (!from._internal_data_base64().empty()) { + _this->_internal_set_data_base64(from._internal_data_base64()); } _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -433,7 +433,7 @@ void RtcmData::InternalSwap(RtcmData* PROTOBUF_RESTRICT other) { auto* arena = GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); _internal_metadata_.InternalSwap(&other->_internal_metadata_); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.data_, &other->_impl_.data_, arena); + ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.data_base64_, &other->_impl_.data_base64_, arena); } ::google::protobuf::Metadata RtcmData::GetMetadata() const { diff --git a/src/mavsdk_server/src/generated/rtk/rtk.pb.h b/src/mavsdk_server/src/generated/rtk/rtk.pb.h index 32d11b7aaa..bee296a28d 100644 --- a/src/mavsdk_server/src/generated/rtk/rtk.pb.h +++ b/src/mavsdk_server/src/generated/rtk/rtk.pb.h @@ -473,22 +473,22 @@ class RtcmData final : // accessors ------------------------------------------------------- enum : int { - kDataFieldNumber = 1, + kDataBase64FieldNumber = 1, }; - // string data = 1; - void clear_data() ; - const std::string& data() const; + // string data_base64 = 1; + void clear_data_base64() ; + const std::string& data_base64() const; template - void set_data(Arg_&& arg, Args_... args); - std::string* mutable_data(); - PROTOBUF_NODISCARD std::string* release_data(); - void set_allocated_data(std::string* value); + void set_data_base64(Arg_&& arg, Args_... args); + std::string* mutable_data_base64(); + PROTOBUF_NODISCARD std::string* release_data_base64(); + void set_allocated_data_base64(std::string* value); private: - const std::string& _internal_data() const; - inline PROTOBUF_ALWAYS_INLINE void _internal_set_data( + const std::string& _internal_data_base64() const; + inline PROTOBUF_ALWAYS_INLINE void _internal_set_data_base64( const std::string& value); - std::string* _internal_mutable_data(); + std::string* _internal_mutable_data_base64(); public: // @@protoc_insertion_point(class_scope:mavsdk.rpc.rtk.RtcmData) @@ -498,7 +498,7 @@ class RtcmData final : friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 0, 1, 0, - 36, 2> + 43, 2> _table_; friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -514,7 +514,7 @@ class RtcmData final : ::google::protobuf::Arena* arena); inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, ::google::protobuf::Arena* arena, const Impl_& from); - ::google::protobuf::internal::ArenaStringPtr data_; + ::google::protobuf::internal::ArenaStringPtr data_base64_; mutable ::google::protobuf::internal::CachedSize _cached_size_; PROTOBUF_TSAN_DECLARE_MEMBER }; @@ -900,57 +900,57 @@ class SendRtcmDataRequest final : // RtcmData -// string data = 1; -inline void RtcmData::clear_data() { +// string data_base64 = 1; +inline void RtcmData::clear_data_base64() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_.data_.ClearToEmpty(); + _impl_.data_base64_.ClearToEmpty(); } -inline const std::string& RtcmData::data() const +inline const std::string& RtcmData::data_base64() const ABSL_ATTRIBUTE_LIFETIME_BOUND { - // @@protoc_insertion_point(field_get:mavsdk.rpc.rtk.RtcmData.data) - return _internal_data(); + // @@protoc_insertion_point(field_get:mavsdk.rpc.rtk.RtcmData.data_base64) + return _internal_data_base64(); } template -inline PROTOBUF_ALWAYS_INLINE void RtcmData::set_data(Arg_&& arg, +inline PROTOBUF_ALWAYS_INLINE void RtcmData::set_data_base64(Arg_&& arg, Args_... args) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); ; - _impl_.data_.Set(static_cast(arg), args..., GetArena()); - // @@protoc_insertion_point(field_set:mavsdk.rpc.rtk.RtcmData.data) + _impl_.data_base64_.Set(static_cast(arg), args..., GetArena()); + // @@protoc_insertion_point(field_set:mavsdk.rpc.rtk.RtcmData.data_base64) } -inline std::string* RtcmData::mutable_data() ABSL_ATTRIBUTE_LIFETIME_BOUND { - std::string* _s = _internal_mutable_data(); - // @@protoc_insertion_point(field_mutable:mavsdk.rpc.rtk.RtcmData.data) +inline std::string* RtcmData::mutable_data_base64() ABSL_ATTRIBUTE_LIFETIME_BOUND { + std::string* _s = _internal_mutable_data_base64(); + // @@protoc_insertion_point(field_mutable:mavsdk.rpc.rtk.RtcmData.data_base64) return _s; } -inline const std::string& RtcmData::_internal_data() const { +inline const std::string& RtcmData::_internal_data_base64() const { PROTOBUF_TSAN_READ(&_impl_._tsan_detect_race); - return _impl_.data_.Get(); + return _impl_.data_base64_.Get(); } -inline void RtcmData::_internal_set_data(const std::string& value) { +inline void RtcmData::_internal_set_data_base64(const std::string& value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); ; - _impl_.data_.Set(value, GetArena()); + _impl_.data_base64_.Set(value, GetArena()); } -inline std::string* RtcmData::_internal_mutable_data() { +inline std::string* RtcmData::_internal_mutable_data_base64() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); ; - return _impl_.data_.Mutable( GetArena()); + return _impl_.data_base64_.Mutable( GetArena()); } -inline std::string* RtcmData::release_data() { +inline std::string* RtcmData::release_data_base64() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - // @@protoc_insertion_point(field_release:mavsdk.rpc.rtk.RtcmData.data) - return _impl_.data_.Release(); + // @@protoc_insertion_point(field_release:mavsdk.rpc.rtk.RtcmData.data_base64) + return _impl_.data_base64_.Release(); } -inline void RtcmData::set_allocated_data(std::string* value) { +inline void RtcmData::set_allocated_data_base64(std::string* value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_.data_.SetAllocated(value, GetArena()); + _impl_.data_base64_.SetAllocated(value, GetArena()); #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING - if (_impl_.data_.IsDefault()) { - _impl_.data_.Set("", GetArena()); + if (_impl_.data_base64_.IsDefault()) { + _impl_.data_base64_.Set("", GetArena()); } #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING - // @@protoc_insertion_point(field_set_allocated:mavsdk.rpc.rtk.RtcmData.data) + // @@protoc_insertion_point(field_set_allocated:mavsdk.rpc.rtk.RtcmData.data_base64) } // ------------------------------------------------------------------- diff --git a/src/mavsdk_server/src/plugins/rtk/rtk_service_impl.h b/src/mavsdk_server/src/plugins/rtk/rtk_service_impl.h index bce0229392..24c999866c 100644 --- a/src/mavsdk_server/src/plugins/rtk/rtk_service_impl.h +++ b/src/mavsdk_server/src/plugins/rtk/rtk_service_impl.h @@ -47,7 +47,7 @@ class RtkServiceImpl final : public rpc::rtk::RtkService::Service { { auto rpc_obj = std::make_unique(); - rpc_obj->set_data(rtcm_data.data); + rpc_obj->set_data_base64(rtcm_data.data_base64); return rpc_obj; } @@ -56,7 +56,7 @@ class RtkServiceImpl final : public rpc::rtk::RtkService::Service { { mavsdk::Rtk::RtcmData obj; - obj.data = rtcm_data.data(); + obj.data_base64 = rtcm_data.data_base64(); return obj; }