Change the default for ntpd back to -s, the bug which triggered this
[dragonfly.git] / contrib / ntp / html / Oncore-SHMEM.htm
1 <HTML>
2 <HEAD>
3     <TITLE> ONCORE - SHMEM </TITLE>
4 </HEAD>
5 <BODY>
6 <H3>
7 Motorola ONCORE - The Shared Memory Interface
8 </H3>
9 <HR>
10
11 <H4>
12 Introduction
13 </H4>
14
15 <P>
16 In NMEA mode, the Oncore GPS receiver provides the user with the same information as
17 other GPS receivers.
18 In BINARY mode, it can provide a lot of additional information.
19 <P>
20 In particular, you can ask for satellite positions, satellite health, signal levels,
21 the ephemeris and the almanac, and you can set many operational parameters.
22 In the case of the VP,
23 you can get the pseudorange corrections necessary to act as a DGPS base station, and you can see
24 the raw satellite data messages themselves.
25 <P>
26 When using the Oncore GPS receiver with NTP, this additional information is usually
27 not available since the receiver is only talking to the oncore driver in NTPD.
28 To make this information available for use in other programs,
29 (say graphic displays of satellites positions, plots of SA, etc.), a shared memory interface
30 (SHMEM) has been added to the refclock_oncore driver on those operating systems that support
31 shared memory.
32 <P>
33 To make use of this information you will need an Oncore Reference Manual for the
34 Oncore GPS receiver that you have.  The Manual for the VP only exists as a paper
35 document, the UT manuals are available as a pdf document online.
36 <P>
37 This interface was written by Poul-Henning Kamp (phk@FreeBSD.org), and modified by
38 Reg Clemens (reg@dwf.com).
39 The interface is known to work in FreeBSD, Linux, and Solaris.
40 <H4>
41 Activating the Interface
42 </H4>
43 Although the Shared Memory Interface will be compiled into the Oncore driver
44 on those systems where Shared Memory is supported, to activate this interface you must
45 include a <B>STATUS</B> line in the <tt>/etc/ntp.oncore</tt> data file that looks like
46 <PRE>
47         STATUS < file_name >
48 </PRE>
49 Thus a line like
50 <PRE>
51         STATUS /var/adm/ntpstats/ONCORE
52 </PRE>
53 would be acceptable.
54 This file name will be used to access the Shared Memory.
55 <P>
56 In addition, one the two keywords <B>Posn2D</B> and <B>Posn3D</B> can be added to
57 see @@Ea records containing the 2D or 3D position of the station (see below).
58 Thus to activate the interface, and see 3D positions, something like
59 <PRE>
60         STATUS /var/adm/ntpstats/ONCORE
61         Posn3D
62 </PRE>
63 would be required.
64 <H4>
65 Storage of Messages in Shared Memory
66 </H4>
67 With the shared memory interface, the oncore driver (refclock_oncore) allocates space
68 for all of the messages that it is configured to receive, and then puts each message
69 in the appropriate slot in shared memory as it arrives from the receiver.
70 Since there is no easy way for a client program to know when the shared memory has
71 been updated,
72 a sequence number is associated with each message, and is incremented when a new message
73 arrives.
74 With the sequence number it is easy to check through the shared memory segment for messages that
75 have changed.
76 <P>
77 The Oncore binary messages are kept in their full length, as described in the Reference
78 manual, that is everything from the @@ prefix thru the &lt;checksum&gt;&lt;CR&gt;&lt;LF&gt;.
79 <P>
80 The data starts at location ONE of SHMEM (NOT location ZERO).
81 <P>
82 The messages are stacked in a series of variable length structures, that look like
83 <PRE>
84         struct message {
85                 u_int   length;
86                 u_char  sequence;
87                 u_char  message[length];
88         }
89 </PRE>
90 <P>
91 if something like that were legal.
92 That is, there are two bytes (caution, these may NOT be aligned with word boundaries, so
93 the field needs to be treated as a pair of u_char), that contains the length of the next
94 message.
95 This is followed by a u_char sequence number, that is incremented whenever a new message of
96 this type is received.
97 This is followed by 'length' characters of the actual message.
98 <P>
99 The next structure starts immediately following the last char of the previous message (no alignment).
100 Thus, each structure starts a distance of 'length+3' from the previous structure.
101 <P>
102 Following the last structure, is a u_int containing a zero length to indicate the end
103 of the data.
104 <P>
105 The messages are recognized by reading the headers in the data itself, viz @@Ea or whatever.
106 <P>
107 There are two special cases.
108 <P>
109 (1) The almanac takes a total of 34 submessages all starting with @@Cb.  <br>
110 35 slots are allocated in shared memory.
111 Each @@Cb message is initially placed in the first of these locations,
112 and then  later it is moved to the appropriate location for that submessage.
113 The submessages can be distinguished by the first two characters following the @@Cb header,
114 and new data is received only when the almanac changes.
115 <P>
116 (2) The @@Ea message contains the calculated location of the antenna, and is received
117 once per second.
118 However, when in timekeeping mode, the receiver is normally put in 0D mode, with the
119 position fixed, to get better accuracy.
120 In 0D mode no position is calculated.
121 <P>
122 When the SHMEM option is active,
123 and if one of <B>Posn2D</B> or <B>Posn3D</B> is specified,
124 one @@Ea record is hijacked each 15s, and the receiver
125 is put back in 2D/3D mode so the the current location can be determined (for position determination, or for
126 tracking SA).
127 The timekeeping code is careful NOT to use the time associated with this (less accurate) 2D/3D tick
128 in its timekeeping functions.
129 <P>
130 Following the initial @@Ea message are 3 additional slots for a total of four.
131 As with the almanac, the first gets filled each time a new record becomes available,
132 later in the code, the message is distributed to the appropriate slot.
133 The additional slots are for messages containing 0D, 2D and 3D positions.
134 These messages can be distinguished by different bit patterns in the last data byte of the record.
135 <H4>
136 Opening the Shared Memory File
137 </H4>
138 The shared memory segment is accessed through a file name given on a <B>ACCESS</B> card in the
139 <tt>/etc/ntp.oncore</tt> input file.
140 The following code could be used to open the Shared Memory Segment:
141
142 <PRE>
143         char *Buf, *file;
144         int size, fd;
145         struct stat statbuf;
146
147         file = "/var/adm/ntpstats/ONCORE";  /* the file name on my ACCESS card */
148         if ((fd=open(file, O_RDONLY)) < 0) {
149                 fprintf(stderr, "Cant open %s\n", file);
150                 exit(1);
151         }
152
153         if (stat(file, &statbuf) < 0) {
154                 fprintf(stderr, "Cant stat %s\n", file);
155                 exit(1);
156         }
157
158         size = statbuf.st_size;
159         if ((Buf=mmap(0, size, PROT_READ, MAP_SHARED, fd, (off_t) 0)) < 0) {
160                 fprintf(stderr, "MMAP failed\n");
161                 exit(1);
162         }
163 </PRE>
164
165 <H4>
166 Accessing the data
167 </H4>
168 The following code shows how to get to the individual records.
169
170 <PRE>
171         void    oncore_msg_Ea(), oncore_msg_As(), oncore_msg_Bb();
172
173         struct Msg {
174             char         c[5];
175             unsigned int seq;
176             void         (*go_to)(uchar *);
177         };
178
179         struct Msg Hdr[] = { {"@@Bb", 0, &oncore_msg_Bb},
180                              {"@@Ea", 0, &oncore_msg_Ea},
181                              {"@@As", 0, &oncore_msg_As}};
182
183         void
184         read_data()
185         {
186             int     i, j, k, n, iseq, jseq;
187             uchar   *cp, *cp1;
188
189
190             for(cp=Buf+1; (n = 256*(*cp) + *(cp+1)) != 0;  cp+=(n+3)) {
191                 for (k=0; k < sizeof(Hdr)/sizeof(Hdr[0]);  k++) {
192                     if (!strncmp(cp+3, Hdr[k].c, 4)) {      /* am I interested? */
193                         iseq = *(cp+2);
194                         jseq = Hdr[k].seq;
195                         Hdr[k].seq = iseq;
196                         if (iseq > jseq) {              /* has it changed? */
197                             /* verify checksum */
198                             j = 0;
199                             cp1 = cp+3;             /* points to start of oncore response */
200                             for (i=2; i < n-3; i++)
201                                 j ^= cp1[i];
202                             if (j == cp1[n-3]) {    /* good checksum */
203                                     Hdr[k].go_to(cp1);
204                             } else {
205                                 fprintf(stderr, "Bad Checksum for %s\n", Hdr[k].c);
206                                 break;
207                             }
208                         }
209                     }
210                 }
211                 if (!strncmp(cp+3, "@@Ea", 4))
212                     cp += 3*(n+3);
213                 if (!strncmp(cp+3, "@@Cb", 4))
214                     cp += 34*(n+3);
215             }
216         }
217
218         oncore_msg_Bb(uchar *buf)
219         {
220                 /* process Bb messages */
221         }
222
223         oncore_msg_Ea(uchar *buf)
224         {
225                 /* process Ea messages */
226         }
227
228         oncore_msg_As(uchar *buf)
229         {
230                 /* process As messages */
231         }
232 </PRE>
233
234 The structure Hdr contains the Identifying string for each of the messages that
235 we want to examine, and the name of a program to call when a new message of that
236 type is arrives.
237 The loop can be run every few seconds to check for new data.
238 <H4>
239 Examples
240 </H4>
241 There are two complete examples available.
242 The first plots satellite positions and the station position as affected by SA, and
243 keeps track of the mean station position, so you can run it for periods of days
244 to get a better station position.
245 The second shows the effective horizon by watching satellite tracks.
246 The examples will be found in the GNU-zipped tar file
247 <A HREF=ftp://ftp.udel.edu/pub/ntp/software/OncorePlot.tar.gz>
248 ftp://ftp.udel.edu/pub/ntp/software/OncorePlot.tar.gz</A>.
249 <P>
250 Try the new interface, enjoy.
251 <HR>
252 <ADDRESS>
253 Reg.Clemens (reg@dwf.com),
254 Poul-Henning Kamp (phk@FreeBSD.org)
255 <ADDRESS>
256 </BODY>
257 </HTML>