STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
test_ubx.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#include "ubx.h"
7
8#define CHECK(c) \
9 do { \
10 if (!(c)) { \
11 fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, #c); \
12 exit(1); \
13 } \
14 } while (0)
15
16/* Expected frames from an independent Python encoder (struct.pack + the
17 * Fletcher checksum), keys from the Interface Description UBX-21035062. */
18static const uint8_t kBaud[] = {0xB5, 0x62, 0x06, 0x8A, 0x0C, 0x00, 0x00,
19 0x01, 0x00, 0x00, 0x01, 0x00, 0x52, 0x40,
20 0x00, 0xC2, 0x01, 0x00, 0xF3, 0xA5};
21static const uint8_t kConfig[] = {
22 0xB5, 0x62, 0x06, 0x8A, 0x19, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02,
23 0x00, 0x74, 0x10, 0x00, 0x07, 0x00, 0x91, 0x20, 0x01, 0x01, 0x00,
24 0x21, 0x30, 0x64, 0x00, 0x21, 0x00, 0x11, 0x20, 0x08, 0xF9, 0x01};
25
26/* NAV-PVT: 2026-11-05 14:30:15, 3D fix, 11 SV, lon -122.2585 lat 37.8719,
27 * hMSL 120.5 m, vel N/E/D 1500 / -250 / -98765 mm/s, pDOP 1.35. */
28static const uint8_t kPvt[] = {
29 0xB5, 0x62, 0x01, 0x07, 0x5C, 0x00, 0x15, 0xCD, 0x5B, 0x07, 0xEA, 0x07,
30 0x0B, 0x05, 0x0E, 0x1E, 0x0F, 0x37, 0x19, 0x00, 0x00, 0x00, 0x0C, 0xFE,
31 0xFF, 0xFF, 0x03, 0x01, 0x00, 0x0B, 0x58, 0xD5, 0x20, 0xB7, 0x18, 0xCB,
32 0x92, 0x16, 0xF0, 0x49, 0x02, 0x00, 0xB4, 0xD6, 0x01, 0x00, 0x08, 0x07,
33 0x00, 0x00, 0xC4, 0x09, 0x00, 0x00, 0xDC, 0x05, 0x00, 0x00, 0x06, 0xFF,
34 0xFF, 0xFF, 0x33, 0x7E, 0xFE, 0xFF, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00,
35 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00,
36 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37 0x00, 0x00, 0xB7, 0xE9};
38
39static void test_valset_baud(void) {
40 const ubx_item_t items[] = {{UBX_KEY_UART1_BAUDRATE, 4, 115200}};
41 uint8_t out[64];
42 size_t n = ubx_valset(out, sizeof(out), items, 1);
43 CHECK(n == sizeof(kBaud));
44 CHECK(memcmp(out, kBaud, n) == 0);
45}
46
47static void test_valset_configuration(void) {
48 const ubx_item_t items[] = {
51 {UBX_KEY_RATE_MEAS, 2, 100},
53 };
54 uint8_t out[64];
55 size_t n = ubx_valset(out, sizeof(out), items, 4);
56 CHECK(n == sizeof(kConfig));
57 CHECK(memcmp(out, kConfig, n) == 0);
58 CHECK(ubx_valset(out, 10, items, 4) == 0); /* does not fit */
59 const ubx_item_t bad[] = {{1, 3, 0}}; /* no 3-byte keys */
60 CHECK(ubx_valset(out, sizeof(out), bad, 1) == 0);
61}
62
67 for (size_t i = 0; i < sizeof(kPvt); ++i) {
68 k = gnss_frame_feed(&p, kPvt[i]);
69 CHECK(i == sizeof(kPvt) - 1 || k == GNSS_FRAME_NONE);
70 }
72 CHECK(p.ubx_class == UBX_CLASS_NAV && p.ubx_id == UBX_ID_NAV_PVT);
73 CHECK(p.ubx_len == UBX_NAV_PVT_LEN);
75 CHECK(ubx_parse_nav_pvt(p.ubx_payload, p.ubx_len, &pvt));
76 CHECK(pvt.itow_ms == 123456789U && pvt.year == 2026 && pvt.month == 11);
77 CHECK(pvt.day == 5 && pvt.hour == 14 && pvt.min == 30 && pvt.sec == 15);
78 CHECK(pvt.fix_type == 3 && pvt.flags == 1 && pvt.num_sv == 11);
79 CHECK(pvt.lon_e7 == -1222585000 && pvt.lat_e7 == 378719000);
80 CHECK(pvt.height_mm == 150000 && pvt.hmsl_mm == 120500);
81 CHECK(pvt.hacc_mm == 1800 && pvt.vacc_mm == 2500);
82 CHECK(pvt.vel_n_mms == 1500 && pvt.vel_e_mms == -250);
83 CHECK(pvt.vel_d_mms == -98765 && pvt.sacc_mms == 300);
84 CHECK(pvt.pdop_e2 == 135);
85 CHECK(!ubx_parse_nav_pvt(p.ubx_payload, 91, &pvt)); /* wrong length */
86}
87
89 const uint8_t ack[2] = {UBX_CLASS_CFG, UBX_ID_CFG_VALSET};
90 uint8_t out[16];
91 size_t n =
92 ubx_frame(out, sizeof(out), UBX_CLASS_ACK, UBX_ID_ACK_ACK, ack, 2);
93 CHECK(n == 10);
97 for (size_t i = 0; i < n; ++i)
98 k = gnss_frame_feed(&p, out[i]);
99 CHECK(k == GNSS_FRAME_UBX && p.ubx_class == UBX_CLASS_ACK);
100 CHECK(p.ubx_payload[0] == UBX_CLASS_CFG && p.ubx_payload[1] == 0x8A);
101}
102
103int main(void) {
108 puts("ubx: all tests passed");
109 return 0;
110}
static void pvt(fake_gnss_t *f, uint32_t t)
Definition fake_gnss.c:141
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_NONE
Definition gnss_frame.h:22
@ GNSS_FRAME_UBX
Definition gnss_frame.h:24
*brief user defined string literal for JSON values *sa std::size_t n
Definition json.hpp:24474
int main()
static const uint8_t ack[]
static void test_frame_roundtrip_through_parser(void)
Definition test_ubx.c:88
static const uint8_t kPvt[]
Definition test_ubx.c:28
static void test_nav_pvt_through_the_frame_parser(void)
Definition test_ubx.c:63
#define CHECK(c)
Definition test_ubx.c:8
static const uint8_t kBaud[]
Definition test_ubx.c:18
static void test_valset_baud(void)
Definition test_ubx.c:39
static const uint8_t kConfig[]
Definition test_ubx.c:21
static void test_valset_configuration(void)
Definition test_ubx.c:47
size_t ubx_valset(uint8_t *out, size_t cap, const ubx_item_t *items, size_t count)
Definition ubx.c:30
bool ubx_parse_nav_pvt(const uint8_t *p, uint16_t len, ubx_pvt_t *out)
Definition ubx.c:66
size_t ubx_frame(uint8_t *out, size_t cap, uint8_t cls, uint8_t id, const uint8_t *payload, uint16_t len)
Definition ubx.c:5
#define UBX_CLASS_CFG
Definition ubx.h:33
#define UBX_DYNMODEL_AIR4
Definition ubx.h:48
#define UBX_CLASS_ACK
Definition ubx.h:32
#define UBX_CLASS_NAV
Definition ubx.h:31
#define UBX_KEY_UART1OUTPROT_NMEA
Definition ubx.h:44
#define UBX_ID_CFG_VALSET
Definition ubx.h:40
#define UBX_ID_ACK_ACK
Definition ubx.h:38
#define UBX_KEY_UART1_BAUDRATE
Definition ubx.h:43
#define UBX_KEY_NAVSPG_DYNMODEL
Definition ubx.h:47
#define UBX_NAV_PVT_LEN
Definition ubx.h:41
#define UBX_ID_NAV_PVT
Definition ubx.h:35
#define UBX_KEY_MSGOUT_NAV_PVT_UART1
Definition ubx.h:45
#define UBX_KEY_RATE_MEAS
Definition ubx.h:46