STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
test_gnss_frame.c
Go to the documentation of this file.
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include "gnss_frame.h"
6
7#define CHECK(condition) \
8 do { \
9 if (!(condition)) { \
10 fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, #condition); \
11 exit(1); \
12 } \
13 } while (0)
14
15/* Feed bytes; return how many valid frames of each kind completed. */
16typedef struct {
17 unsigned nmea, ubx;
18} counts_t;
19
20static counts_t feed(gnss_frame_parser_t* p, const uint8_t* bytes, size_t n) {
21 counts_t c = {0, 0};
22 for (size_t i = 0; i < n; ++i) {
23 gnss_frame_kind_t k = gnss_frame_feed(p, bytes[i]);
24 if (k == GNSS_FRAME_NMEA)
25 c.nmea++;
26 if (k == GNSS_FRAME_UBX)
27 c.ubx++;
28 }
29 return c;
30}
31
32static counts_t feed_str(gnss_frame_parser_t* p, const char* s) {
33 return feed(p, (const uint8_t*)s, strlen(s));
34}
35
36/* Vectors computed outside this code: the GGA example's published checksum is
37 * 47; TXT and UBX checksums were computed independently in Python. */
38static const char gga[] =
39 "$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47\r\n";
40static const char txt[] = "$GNTXT,01,01,02,u-blox AG - www.u-blox.com*4E\r\n";
41static const uint8_t ack[] = {0xB5, 0x62, 0x05, 0x01, 0x02,
42 0x00, 0x06, 0x8A, 0x98, 0xC1};
43
44static void test_valid_frames(void) {
47 counts_t c = feed_str(&p, gga);
48 CHECK(c.nmea == 1 && c.ubx == 0);
49 c = feed_str(&p, txt);
50 CHECK(c.nmea == 1);
51 c = feed(&p, ack, sizeof(ack));
52 CHECK(c.ubx == 1 && c.nmea == 0);
53 CHECK(p.rejected == 0);
54}
55
56static void test_lowercase_checksum(void) {
59 CHECK(feed_str(&p, "$GNTXT,01,01,02,u-blox AG - www.u-blox.com*4e").nmea ==
60 1);
61}
62
63static void test_wrong_nmea_checksum(void) {
66 char bad[sizeof(gga)];
67 memcpy(bad, gga, sizeof(gga));
68 bad[strlen(bad) - 3] = '8'; /* *47 -> *48 */
69 CHECK(feed_str(&p, bad).nmea == 0);
70 CHECK(p.rejected == 1);
71 /* one flipped body byte also fails */
72 memcpy(bad, gga, sizeof(gga));
73 bad[10] = '6';
74 CHECK(feed_str(&p, bad).nmea == 0);
75}
76
77static void test_corrupt_ubx(void) {
78 for (size_t i = 2; i < sizeof(ack); ++i) {
81 uint8_t bad[sizeof(ack)];
82 memcpy(bad, ack, sizeof(ack));
83 bad[i] ^= 0x01;
84 counts_t c = feed(&p, bad, sizeof(bad));
85 CHECK(c.ubx == 0);
86 }
87}
88
89static void test_noise_then_frame(void) {
92 /* line noise (incl. NUL), a stray UBX sync byte and a half sentence */
93 static const uint8_t noise[] = {0xFF, 0x00, 'g', 'a', 'r', 0xB5, 'z',
94 '$', 'G', 'P', 'G', 'G', 'A', ','};
95 CHECK(feed(&p, noise, sizeof(noise)).nmea == 0);
96 CHECK(feed_str(&p, gga).nmea == 1); /* '$' restarts the cut sentence */
97 CHECK(p.rejected == 1);
98}
99
103 char longline[200] = "$";
104 memset(longline + 1, 'A', 150);
105 strcat(longline, "*00");
106 CHECK(feed_str(&p, longline).nmea == 0);
107 /* *57 is the right XOR including the 0x01, so only the "printable
108 * characters only" rule can reject it. */
109 CHECK(feed_str(&p, "$GP\x01GGA*57").nmea == 0);
110 CHECK(feed_str(&p, "$GPGGA*56").nmea == 1); /* same frame, no 0x01 */
111}
112
113static void test_ubx_length_limit(void) {
116 /* declared payload 0xFFFF is refused right after the length bytes */
117 const uint8_t big[] = {0xB5, 0x62, 0x01, 0x07, 0xFF, 0xFF};
118 CHECK(feed(&p, big, sizeof(big)).ubx == 0);
119 CHECK(p.rejected == 1);
120 CHECK(feed(&p, ack, sizeof(ack)).ubx == 1);
121}
122
123int main(void) {
131 puts("gnss_frame: all tests passed");
132 return 0;
133}
int32_t p
Definition flight_e2e.c:78
gnss_frame_kind_t gnss_frame_feed(gnss_frame_parser_t *p, uint8_t byte)
Definition gnss_frame.c:57
void gnss_frame_init(gnss_frame_parser_t *parser)
Definition gnss_frame.c:35
gnss_frame_kind_t
Definition gnss_frame.h:21
@ GNSS_FRAME_UBX
Definition gnss_frame.h:24
@ GNSS_FRAME_NMEA
Definition gnss_frame.h:23
*brief user defined string literal for JSON values *sa std::size_t n
Definition json.hpp:24474
unsigned ubx
unsigned nmea
int main()
static void test_overlong_and_binary_nmea(void)
static counts_t feed_str(gnss_frame_parser_t *p, const char *s)
static void test_wrong_nmea_checksum(void)
#define CHECK(condition)
static void test_valid_frames(void)
static const uint8_t ack[]
static void test_lowercase_checksum(void)
static const char gga[]
static const char txt[]
static void test_corrupt_ubx(void)
static void test_ubx_length_limit(void)
static counts_t feed(gnss_frame_parser_t *p, const uint8_t *bytes, size_t n)
static void test_noise_then_frame(void)