Version
demo5, patch level b34L (VER_RTKLIB="demo5", PATCH_LEVEL="b34L")
Summary
When using rtkrcv with an ephemeris-only "corr" input stream (broadcast
ephemeris relayed from an NTRIP caster, e.g. BKG's BCEP00BKG0 mountpoint),
the per-stream RTCM3 decoder occasionally gets stuck after long continuous
operation (observed after ~3 days). Once stuck, satellite ephemeris (toe/toc)
stops updating and never recovers, even though:
- The underlying network stream is confirmed healthy (bytes are still
flowing from the source).
- Restarting the process feeding that stream (an independent
str2str
relay in front of it) does NOT recover it.
- Only issuing a full
restart inside rtkrcv (stop + start of the whole
rtk server) recovers it.
This suggests the problem is not in the network/stream layer at all, but in
per-stream decoder state that lives inside the long-running rtkrcv process
and is never reset except on a full server restart.
Root cause (from code inspection)
init_raw() / init_rtcm(), which reset a stream's raw/rtcm decoder state
machine (nbyte, len, sync position, etc.), are only called in
rtksvrstart() in src/rtksvr.c:
for (i=0;i<3;i++) { /* input/log streams */
...
/* initialize receiver raw and rtcm control */
init_raw(svr->raw+i,formats[i]);
init_rtcm(svr->rtcm+i);
...
}
There is no code path to reinitialize the decoder for a single input stream
(rover/base/corr) independently. Reconnecting the underlying stream_t
(automatically via the built-in timeout/reconnect logic, or manually by
restarting whatever process feeds that stream) only replaces the transport
socket — it never touches svr->raw[i] / svr->rtcm[i]. So if that
decoder's internal state gets desynchronized/wedged for any reason (e.g. a
malformed or truncated RTCM3 message straddling a read buffer boundary), it
appears to be unrecoverable short of a full rtksvrstart()/rtksvrstop()
cycle, which also resets the RTK filter state (rtkfree+rtkinit) and
therefore loses float/fixed ambiguity state — much more disruptive than
necessary for what should be an isolated, single-stream issue.
Setup used when this was observed
inpstr1: rover raw observations (NTRIP)
inpstr2: base raw observations (NTRIP)
inpstr3: corr = broadcast ephemeris only, RTCM3, relayed via a local
str2str -in ntrip://.../BCEP00BKG0 -out tcpsvr://:PORT process, consumed
by rtkrcv as inpstr3-type=tcpcli, inpstr3-format=rtcm3
misc-navmsgsel=all
misc-timeout=10000, misc-reconnect=10000 (defaults)
Steps to reproduce
Not reliably reproducible on demand — it appears to be a rare edge case in
the byte stream that only shows up after multiple days of continuous
operation on a live multi-GNSS RTCM3 feed. Happy to capture and share trace
logs (misc-trace>=3) around the next occurrence if that's useful.
Suggested fix / feature request
Expose a way to reset a single input stream's decoder state (raw/rtcm init
- its read buffers) independently of the other streams and without
resetting the RTK filter state — e.g. a rtksvrresetstream(rtksvr_t *svr, int index) that redoes what rtksvrstart() does for svr->raw[index] /
svr->rtcm[index] / svr->buff[index] / svr->pbuf[index] only. This
would let a user-level watchdog recover from a stuck stream decoder
(detected e.g. via stale ephemeris timestamps) without forcing a full
solution restart.
Alternatively, if there's a known failure mode in the RTCM3 byte-stream
parser that can leave it permanently desynchronized without a way to
self-resync, pointers to where to look would be appreciated.
Version
demo5, patch level b34L (
VER_RTKLIB="demo5",PATCH_LEVEL="b34L")Summary
When using
rtkrcvwith an ephemeris-only "corr" input stream (broadcastephemeris relayed from an NTRIP caster, e.g. BKG's BCEP00BKG0 mountpoint),
the per-stream RTCM3 decoder occasionally gets stuck after long continuous
operation (observed after ~3 days). Once stuck, satellite ephemeris (toe/toc)
stops updating and never recovers, even though:
flowing from the source).
str2strrelay in front of it) does NOT recover it.
restartinsidertkrcv(stop + start of the wholertk server) recovers it.
This suggests the problem is not in the network/stream layer at all, but in
per-stream decoder state that lives inside the long-running rtkrcv process
and is never reset except on a full server restart.
Root cause (from code inspection)
init_raw()/init_rtcm(), which reset a stream's raw/rtcm decoder statemachine (
nbyte,len, sync position, etc.), are only called inrtksvrstart()insrc/rtksvr.c:There is no code path to reinitialize the decoder for a single input stream
(rover/base/corr) independently. Reconnecting the underlying
stream_t(automatically via the built-in timeout/reconnect logic, or manually by
restarting whatever process feeds that stream) only replaces the transport
socket — it never touches
svr->raw[i]/svr->rtcm[i]. So if thatdecoder's internal state gets desynchronized/wedged for any reason (e.g. a
malformed or truncated RTCM3 message straddling a read buffer boundary), it
appears to be unrecoverable short of a full
rtksvrstart()/rtksvrstop()cycle, which also resets the RTK filter state (
rtkfree+rtkinit) andtherefore loses float/fixed ambiguity state — much more disruptive than
necessary for what should be an isolated, single-stream issue.
Setup used when this was observed
inpstr1: rover raw observations (NTRIP)inpstr2: base raw observations (NTRIP)inpstr3: corr = broadcast ephemeris only, RTCM3, relayed via a localstr2str -in ntrip://.../BCEP00BKG0 -out tcpsvr://:PORTprocess, consumedby rtkrcv as
inpstr3-type=tcpcli,inpstr3-format=rtcm3misc-navmsgsel=allmisc-timeout=10000,misc-reconnect=10000(defaults)Steps to reproduce
Not reliably reproducible on demand — it appears to be a rare edge case in
the byte stream that only shows up after multiple days of continuous
operation on a live multi-GNSS RTCM3 feed. Happy to capture and share trace
logs (
misc-trace>=3) around the next occurrence if that's useful.Suggested fix / feature request
Expose a way to reset a single input stream's decoder state (raw/rtcm init
resetting the RTK filter state — e.g. a
rtksvrresetstream(rtksvr_t *svr, int index)that redoes whatrtksvrstart()does forsvr->raw[index]/svr->rtcm[index]/svr->buff[index]/svr->pbuf[index]only. Thiswould let a user-level watchdog recover from a stuck stream decoder
(detected e.g. via stale ephemeris timestamps) without forcing a full
solution restart.
Alternatively, if there's a known failure mode in the RTCM3 byte-stream
parser that can leave it permanently desynchronized without a way to
self-resync, pointers to where to look would be appreciated.