29 return _stream.
onFrame(frame, context);
34 [[nodiscard]]
const GPSNMEAStream& stream()
const {
return _stream; }
41 .
type = GPSType::passive,
42 .logCategory = &PassiveProtocolLog,
44 .create = &gpsCreateProtocol<NMEAProtocol>,
47bool standardSentence(
const GPSFrame& frame)
52bool checkedBlock(
const GPSFrame& frame)
67constexpr std::array INPUTS{
72static_assert(INPUTS.front().family == &NMEA_FAMILY);
75constexpr GPSFrameKinds inputFrames()
78 for (
const auto& input : INPUTS) {
79 frames |= input.frames;
91 static constexpr std::chrono::milliseconds SOURCE_TIMEOUT{3000};
93 PassiveProtocol() { _reset(); }
101 channel.
failControl(QStringLiteral(
"The link cannot run at %1 baud").arg(baud));
115 const auto input = _inputOf(frame);
122 (void) _inputs[*input].runtime->consumeFrame(frame);
129 for (
const auto& input : _inputs) {
130 (void) input.runtime->consume({});
134 bool receiverReady()
const override {
return _ready; }
136 GPSReceiveUpdates receive(
GPSCommandChannel& channel, std::chrono::milliseconds timeout)
override
138 const auto& nmea =
static_cast<const NMEAProtocol&
>(_inputs.front().runtime->protocol()).stream();
139 return nmea.receive(channel, timeout);
145 std::unique_ptr<GPSProtocolRuntime> runtime;
146 uint64_t lastPositionUs = 0;
149 static std::optional<size_t> _inputOf(
const GPSFrame& frame)
151 for (
size_t index = 0; index < INPUTS.size(); ++index) {
152 const auto& input = INPUTS[index];
153 if (input.frames.testFlag(
frame.kind) && (!input.accepts || input.accepts(frame))) {
163 for (
size_t index = 0; index < INPUTS.size(); ++index) {
168 _inputs[index] = {.runtime = std::make_unique<GPSProtocolRuntime>(*INPUTS[index].family, std::move(io),
169 std::move(observer)),
170 .lastPositionUs = 0};
171 _inputs[index].runtime->armNavigationDecode();
178 const uint64_t now =
_context->nowUs();
179 _inputs[index].lastPositionUs = now;
180 if (!_followed || (*_followed != index &&
185 if (_followed != index) {
188 for (
const auto& event : batch.
events) {
194 void _follow(
size_t index)
198 const GPSType family = INPUTS[index].family->type;
199 qCDebug(PassiveProtocolLog) <<
"Passive input decodes" << family;
203 std::array<Input, INPUTS.size()> _inputs;
204 std::optional<size_t> _followed;
214 .
type = GPSType::passive,
215 .logCategory = &PassiveProtocolLog,
216 .stream = {.framers = inputFrames(), .enabled = inputFrames(), .shareSBFSync =
true},
217 .create = &gpsCreateProtocol<PassiveProtocol>,
static std::atomic< jobject > _context
@ SBF
Septentrio "$@" block candidates, up to the first 110 bytes; the decoder checks the CRC.
@ UBX
u-blox 0xB5 0x62 frames with a valid Fletcher checksum.
@ ASCIILine
Printable lines up to CR/LF, without the terminator; the decoder checks checksums.
@ RTCM3
0xD3 frames with a valid CRC-24Q.
#define QGC_LOGGING_CATEGORY(name, categoryStr)
bool setBaudrate(unsigned baudrate)
void failControl(GPSProtocolError failure=GPSProtocolError::Protocol)
GPSStreamDemux & stream()
void publishRTCM(std::span< const uint8_t > frame)
virtual GPSReceiveUpdates onFrame(const GPSFrame &frame, GPSDecodeContext &context)=0
virtual bool configure(GPSCommandChannel &channel, GPSConfig config, unsigned &baud)=0
virtual void flush(GPSDecodeContext &context)
Publishes time-driven output before each decode, such as expired epochs.
constexpr bool fresh(uint64_t timestampUs, uint64_t nowUs, std::chrono::microseconds lifetime)
Whether a receipt is younger than lifetime.
bool isStandardSentence(std::string_view text)
A checked sentence from a standard talker, not a proprietary $P... sentence.
std::optional< Frame > frame(std::string_view text)
const GPSReceiverFamily FAMILY
const GPSReceiverFamily FAMILY
std::optional< BlockHeader > checkedHeader(std::span< const uint8_t > block)
The header of a block candidate whose length fits the candidate and whose CRC matches; nullopt otherw...
const GPSReceiverFamily FAMILY
std::function< uint64_t()> nowUs
The receiver configuration requested for one configure() attempt.
Events decoded from one span of received bytes, in publication order.
GPSReceiveUpdates updates
GPSClock clock
Without a wait, the runtime sleeps in short slices until the duration elapses or cancelToken is cance...
Observers of runtime output, invoked synchronously on the runtime thread.
std::function< void(const GPSEventBatch &)> decoded
Borrowed for the callback; it may decode nested input through GPSProtocolRuntime::consume().