2 * This file is Copyright (c) 2010 by the GPSD project
3 * BSD terms apply: see the file COPYING in the distribution root for details.
13 #endif /* S_SPLINT_S */
14 #include <sys/types.h>
20 static int verbose = 0;
22 void gpsd_report(int errlevel, const char *fmt, ...)
23 /* assemble command in printf(3) style, use stderr or syslog */
25 if (errlevel <= verbose) {
31 (void)vsnprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), fmt,
35 (void)fputs(buf, stderr);
42 char test[MAX_PACKET_LENGTH + 1];
49 /*@ -initallelements +charint -usedef @*/
50 static struct map singletests[] = {
53 .legend = "NMEA packet with checksum (1)",
54 .test = "$GPVTG,308.74,T,,M,0.00,N,0.0,K*68\r\n",
60 .legend = "NMEA packet with checksum (2)",
61 .test = "$GPGGA,110534.994,4002.1425,N,07531.2585,W,0,00,50.0,172.7,M,-33.8,M,0.0,0000*7A\r\n",
67 .legend = "NMEA packet with checksum and 4 chars of leading garbage",
68 .test = "\xff\xbf\x00\xbf$GPVTG,308.74,T,,M,0.00,N,0.0,K*68\r\n",
74 .legend = "NMEA packet without checksum",
75 .test = "$PSRF105,1\r\n",
81 .legend = "NMEA packet with wrong checksum",
82 .test = "$GPVTG,308.74,T,,M,0.00,N,0.0,K*28\r\n",
89 .legend = "SiRF WAAS version ID",
91 0xA0, 0xA2, 0x00, 0x15,
92 0x06, 0x06, 0x31, 0x2E, 0x32, 0x2E, 0x30, 0x44,
93 0x4B, 0x49, 0x54, 0x31, 0x31, 0x39, 0x20, 0x53,
94 0x4D, 0x00, 0x00, 0x00, 0x00,
95 0x03, 0x82, 0xB0, 0xB3},
101 .legend = "SiRF WAAS version ID with 3 chars of leading garbage",
104 0xA0, 0xA2, 0x00, 0x15,
105 0x06, 0x06, 0x31, 0x2E, 0x32, 0x2E, 0x30, 0x44,
106 0x4B, 0x49, 0x54, 0x31, 0x31, 0x39, 0x20, 0x53,
107 0x4D, 0x00, 0x00, 0x00, 0x00,
108 0x03, 0x82, 0xB0, 0xB3},
114 .legend = "SiRF WAAS version ID with wrong checksum",
116 0xA0, 0xA2, 0x00, 0x15,
117 0x06, 0x06, 0x31, 0x2E, 0x32, 0x2E, 0x30, 0x44,
118 0x4B, 0x49, 0x54, 0x31, 0x31, 0x39, 0x20, 0x53,
119 0x4D, 0x00, 0x00, 0x00, 0x00,
120 0x03, 0x00, 0xB0, 0xB3},
126 .legend = "SiRF WAAS version ID with bad length",
128 0xA0, 0xA2, 0xff, 0x15,
129 0x06, 0x06, 0x31, 0x2E, 0x32, 0x2E, 0x30, 0x44,
130 0x4B, 0x49, 0x54, 0x31, 0x31, 0x39, 0x20, 0x53,
131 0x4D, 0x00, 0x00, 0x00, 0x00,
132 0x03, 0x82, 0xB0, 0xB3},
139 .legend = "Zodiac binary 1000 Geodetic Status Output Message",
141 0xff, 0x81, 0xe8, 0x03, 0x31, 0x00, 0x00, 0x00, 0xe8, 0x79,
142 0x74, 0x0e, 0x00, 0x00, 0x24, 0x00, 0x24, 0x00, 0x04, 0x00,
143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x03, 0x23, 0x00,
144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x06, 0x00,
145 0xcd, 0x07, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x7b, 0x0d,
146 0x00, 0x00, 0x12, 0x6b, 0xa7, 0x04, 0x41, 0x75, 0x32, 0xf8,
147 0x03, 0x1f, 0x00, 0x00, 0xe6, 0xf2, 0x00, 0x00, 0x00, 0x00,
148 0x00, 0x00, 0x11, 0xf6, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40,
149 0xd9, 0x12, 0x90, 0xd0, 0x03, 0x00, 0x00, 0xa3, 0xe1, 0x11,
150 0x10, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa3, 0xe1, 0x11,
151 0x00, 0x00, 0x00, 0x00, 0xe0, 0x93, 0x04, 0x00, 0x04, 0xaa},
154 .type = ZODIAC_PACKET,
158 .legend = "EverMore status packet 0x20",
160 0x10, 0x02, 0x0D, 0x20, 0xE1, 0x00, 0x00, 0x00,
161 0x0A, 0x00, 0x1E, 0x00, 0x32, 0x00, 0x5b, 0x10,
165 .type = EVERMORE_PACKET,
168 .legend = "EverMore packet 0x04 with 0x10 0x10 sequence",
170 0x10, 0x02, 0x0f, 0x04, 0x00, 0x00, 0x10, 0x10,
171 0xa7, 0x13, 0x03, 0x2c, 0x26, 0x24, 0x0a, 0x17,
172 0x00, 0x68, 0x10, 0x03},
175 .type = EVERMORE_PACKET,
178 .legend = "EverMore packet 0x04 with 0x10 0x10 sequence, some noise before packet data",
180 0x10, 0x03, 0xff, 0x10, 0x02, 0x0f, 0x04, 0x00,
181 0x00, 0x10, 0x10, 0xa7, 0x13, 0x03, 0x2c, 0x26,
182 0x24, 0x0a, 0x17, 0x00, 0x68, 0x10, 0x03},
185 .type = EVERMORE_PACKET,
188 .legend = "EverMore packet 0x04, 0x10 and some other data at the beginning",
190 0x10, 0x12, 0x10, 0x03, 0xff, 0x10, 0x02, 0x0f,
191 0x04, 0x00, 0x00, 0x10, 0x10, 0xa7, 0x13, 0x03,
192 0x2c, 0x26, 0x24, 0x0a, 0x17, 0x00, 0x68, 0x10,
196 .type = EVERMORE_PACKET,
199 .legend = "EverMore packet 0x04, 0x10 three times at the beginning",
202 0x10, 0x02, 0x0f, 0x04, 0x00, 0x00, 0x10, 0x10,
203 0xa7, 0x13, 0x03, 0x2c, 0x26, 0x24, 0x0a, 0x17,
204 0x00, 0x68, 0x10, 0x03},
207 .type = EVERMORE_PACKET,
210 .legend = "RTCM104V3 type 1005 packet",
212 * Reference Station Id = 2003
213 * GPS Service supported, but not GLONASS or Galileo
214 * ARP ECEF-X = 1114104.5999 meters
215 * ARP ECEF-Y = -4850729.7108 meters
216 * ARP ECEF-Z = 3975521.4643 meters
219 0xD3, 0x00, 0x13, 0x3E, 0xD7, 0xD3, 0x02, 0x02,
220 0x98, 0x0E, 0xDE, 0xEF, 0x34, 0xB4, 0xBD, 0x62,
221 0xAC, 0x09, 0x41, 0x98, 0x6F, 0x33, 0x36, 0x0B,
226 .type = RTCM3_PACKET,
229 .legend = "RTCM104V3 type 1005 packet with 4th byte garbled",
231 0xD3, 0x00, 0x13, 0x3F, 0xD7, 0xD3, 0x02, 0x02,
232 0x98, 0x0E, 0xDE, 0xEF, 0x34, 0xB4, 0xBD, 0x62,
233 0xAC, 0x09, 0x41, 0x98, 0x6F, 0x33, 0x36, 0x0B,
241 /*@ +initallelements -charint +usedef @*/
245 /*@ -initallelements +charint -usedef @*/
246 static struct map runontests[] = {
249 .legend = "Double NMEA packet with checksum",
250 .test = "$GPVTG,308.74,T,,M,0.00,N,0.0,K*68\r\n$GPGGA,110534.994,4002.1425,N,07531.2585,W,0,00,50.0,172.7,M,-33.8,M,0.0,0000*7A\r\n",
256 /*@ +initallelements -charint +usedef @*/
259 static int packet_test(struct map *mp)
261 struct gps_packet_t packet;
264 packet_init(&packet);
265 /*@i@*/ memcpy(packet.inbufptr = packet.inbuffer, mp->test, mp->testlen);
266 packet.inbuflen = mp->testlen;
267 /*@ -compdef -uniondef -usedef -formatcode @*/
268 packet_parse(&packet);
269 if (packet.type != mp->type)
270 printf("%2zi: %s test FAILED (packet type %d wrong).\n",
271 mp - singletests + 1, mp->legend, packet.type);
273 (mp->test + mp->garbage_offset, packet.outbuffer,
275 printf("%2zi: %s test FAILED (data garbled).\n", mp - singletests + 1,
279 printf("%2zi: %s test succeeded.\n", mp - singletests + 1,
282 for (cp = packet.outbuffer;
283 cp < packet.outbuffer + packet.outbuflen; cp++) {
284 if (lexer->type != NMEA_PACKET)
285 (void)printf(" 0x%02x", *cp);
286 else if (*cp == '\r')
287 (void)fputs("\\r", stdout);
288 else if (*cp == '\n')
289 (void)fputs("\\n", stdout);
290 else if (isprint(*cp))
293 (void)printf("\\x%02x", *cp);
297 /*@ +compdef +uniondef +usedef +formatcode @*/
302 static void runon_test(struct map *mp)
304 struct gps_packet_t packet;
305 int nullfd = open("/dev/null", O_RDONLY);
308 packet_init(&packet);
309 /*@i@*/ memcpy(packet.inbufptr = packet.inbuffer, mp->test, mp->testlen);
310 packet.inbuflen = mp->testlen;
311 /*@ -compdef -uniondef -usedef -formatcode @*/
312 (void)fputs(mp->test, stdout);
314 st = packet_get(nullfd, &packet);
315 printf("packet_parse() returned %zd\n", st);
317 /*@ +compdef +uniondef +usedef +formatcode @*/
320 int main(int argc, char *argv[])
324 int option, singletest = 0;
327 while ((option = getopt(argc, argv, "t:v:")) != -1) {
330 singletest = atoi(optarg);
333 verbose = atoi(optarg);
339 failcount += packet_test(singletests + singletest - 1);
341 (void)fputs("=== Packet identification tests\n ===", stdout);
342 for (mp = singletests;
343 mp < singletests + sizeof(singletests) / sizeof(singletests[0]);
345 failcount += packet_test(mp);
346 (void)fputs("=== EOF with buffer nonempty test ===\n", stdout);
347 runon_test(&runontests[0]);
349 exit(failcount > 0 ? 1 : 0);