On Tue, Jun 21, 2011 at 02:08 UTC, Charles Elliott <[email protected]> wrote: > Hello:
I'm sorry it took me over 5 weeks to notice this message, I was on vacation at the time. Also, the [email protected] mailing list is more appropriate for this discussion. I'm subscribed to both, so feel free to replace questions@ with hackers@ once you're subscribed. > In win32_io.c why is the event char set to CR instead of LF > as the NMEA protocol indicates lines are terminated with CRLF? This might > make a difference as if one read the message string without the LF, leaving > it in the buffer, the next line might be begun with the LF. The relevant > line is #228 dcb.EvtChar = 13; /* CR */ // Should be 10; That's the line in your source, perhaps, but here the "// Should be 10;" seems to be missing ;) Note this code is not specific to the NMEA driver, but is used for all serial-connected refclocks operating on the Windows port of ntpd, including, for example, the ACTS modem refclock. The issue being addressed is that POSIX and Windows serial APIs are fundamentally different, and this code is trying to emulate the POSIX semantics using the Windows API. In particular, many reference clocks open the serial port in a line-oriented mode, where read() calls are not completed until either a CR or LF is seen. That's when the dcb.EvtChar comes into play: ntpd's Windows serial reading code will not try to read until the EvtChar (CR) is reported seen by WaitCommEvent(), at which point it will race to read everything so far buffered. The line so read is passed to add_full_recv_buffer() which queues it to be dispatched to the refclock's receive entrypoint, which for line-oriented refclocks will call a routine which strips any LFs and CRs from the raw buffer before further processing. To further mimic POSIX ntpd behavior, an empty buffer is then passed to add_full_recv_buffer(). This is because on POSIX systems each CRLF-terminated line results in one read terminated by CR, then another immediately terminated by the following LF. After the processing strips CRs and LFs, the result the refclock sees is a line with data, then an empty line. While in theory much the same could be achieved by using LF as the dcb.EvtChar, to mimic POSIX the first read should be completed as soon as CR is received. > Also on win32_io.c, why is the is the Comm Mask set to watch > out for the CD line, in addition to the event flag? If one just waits for > the event char, then he is sure of receiving a whole line. If he waits for > the CD line, then a partial line or, worse, a line plus a partial line might > be read. You need to read ports\winnt\ntpd\ntp_iocompletionport.c as well as win32_io.c to get a complete picture. When the WaitCommEvent indicates the CD line (referred to as RLSD by the Win32 API IIRC) has changed state, the buffered data is not read from the port. That occurs only when WaitCommEvent() indicates the event character CR has been seen. The code is watching for CD state changes to provide a hack, referred to as user-mode PPS support. Note there is real PPSAPI support in the Windows ntpd port, but it requires a separately-distributed modified Windows serial.sys kernel-mode device driver (serialpps.sys) and an associated serialpps-ppsapi-provider.dll which is optionally loaded by ntpd. The hack user-mode PPS support works only for the first complete line of input after each PPS event and replaces the timestamp for that line with the timestamp of the preceding PPS event. This imposes several annoying limitations compared to the real PPSAPI approach: the replacement happens only for one line, meaning for NMEA you need to ensure the first line emitted by the GPS each second is the one ntpd is processing, and the fudge factor that's supposed to be fudging the end-of-line is in fact then fudging the PPS event timestamp instead. Cheers, Dave Hart _______________________________________________ questions mailing list [email protected] http://lists.ntp.org/listinfo/questions
