48 int main(
int argc,
char *argv[]) {
52 char *outFileName = NULL;
54 bool clobberOutput =
false;
57 "Usage: %1$s [-v] [-q] [-f] [-Z] [-o outfile] DATFILE\n"
58 "\t-v\tIncrease verbosity\n"
59 "\t-q\tDecrease verbosity\n"
60 "\t-f\tOverwrite existing output files\n"
61 "\t-Z\tDisable gzipped output\n"
62 "\t-o\tWrite output to named file\n"
64 "Output file name will be generated based on input file name and compression flags, unless set by -o option\n";
69 while ((go = getopt(argc, argv,
"vqfZo:")) != -1) {
87 "Only a single output file name can be provided");
90 outFileName = strdup(optarg);
94 log_error(&state,
"Unknown option `-%c'", optopt);
100 if (argc - optind != 1) {
106 fprintf(stderr, usage, argv[0]);
112 char *inFileName = strdup(argv[optind]);
113 FILE *inFile = fopen(inFileName,
"rb");
114 if (inFile == NULL) {
115 log_error(&state,
"Unable to open input file");
122 if (outFileName == NULL) {
126 char *inF1 = strdup(inFileName);
127 char *inF2 = strdup(inFileName);
128 char *dn = dirname(inF1);
129 char *bn = basename(inF2);
132 char *ep = strrchr(bn,
'.');
142 char *nbn = calloc(bnl + 1,
sizeof(
char));
143 strncpy(nbn, bn, bnl);
145 if (asprintf(&outFileName,
"%s/%s.satinfo.csv.gz", dn, nbn) <= 0) {
156 if (asprintf(&outFileName,
"%s/%s.satinfo.csv", dn, nbn) <= 0) {
173 char fmode[5] = {
'w',
'b', 0, 0};
197 gzFile outFile = gzopen(outFileName, fmode);
198 if (outFile == NULL) {
199 log_error(&state,
"Unable to open output file");
200 log_error(&state,
"%s ", strerror(errno));
207 log_info(&state, 1,
"Writing %s output to %s", doGZ ?
"compressed" :
"uncompressed",
214 struct stat inStat = {0};
215 if (fstat(fileno(inFile), &inStat) != 0) {
216 log_error(&state,
"Unable to get input file status: %s", strerror(errno));
223 long inSize = inStat.st_size;
227 log_info(&state, 1,
"Reading %.2fGB of data from %s", inSize / 1.0E9, inFileName);
228 }
else if (inSize >= 1E6) {
229 log_info(&state, 1,
"Reading %.2fMB of data from %s", inSize / 1.0E6, inFileName);
230 }
else if (inSize >= 1E3) {
231 log_info(&state, 1,
"Reading %.2fkB of data from %s", inSize / 1.0E3, inFileName);
233 log_info(&state, 1,
"Reading %ld bytes of data from %s", inSize, inFileName);
238 char *GNSS[] = {
"GPS",
"SBAS",
"Galileo",
"BeiDou",
"IMES",
"QZSS",
"GLONASS"};
240 "TOW,Source,GNSS,SatID,SNR,Elevation,Azimuth,Residual,Quality,SatUsed\n");
241 while (!(feof(inFile))) {
247 "Error reading messages from file (Code: 0x%52x)\n",
252 log_info(&state, 1,
"End of file reached");
260 if (tmp.
type == 0x03 && (data[0] == 0xb5 && data[1] == 0x62 &&
261 data[2] == 0x01 && data[3] == 0x35)) {
262 const uint32_t tow = data[6] + (data[7] << 8) + (data[8] << 16) +
264 const uint8_t numSats = data[11];
266 for (
int i = 0; i < numSats; i++) {
267 const uint8_t gnssID = data[14 + 12 * i];
268 const uint8_t satID = data[15 + 12 * i];
269 const uint8_t SNR = data[16 + 12 * i];
270 const int8_t elev = data[17 + 12 * i];
272 data[18 + 12 * i] + (data[19 + 12 * i] << 8);
274 (data[20 + 12 * i] + (data[21 + 12 * i] << 8)) /
276 const uint8_t qual = data[22 + 12 * i] & 0x07;
277 const uint8_t inUse = (data[22 + 12 * i] & 0x08) / 0x08;
278 gzprintf(outFile,
"%u,%02X,%s,%u,%u,%d,%d,%d,%u,%u\n", tow,
279 tmp.
source, GNSS[gnssID], satID, SNR, elev, azi,
286 inPos = ftell(inFile);
287 if (((((1.0 * inPos) / inSize) * 100) - progress) >= 5) {
288 progress = (((1.0 * inPos) / inSize) * 100);
289 log_info(&state, 2,
"Progress: %d%% (%ld / %ld)", progress, inPos, inSize);
void msg_destroy(msg_t *msg)
Destroy a message.
bool mp_readMessage(int handle, msg_t *out)
Static wrapper around mp_readMessage_buf.
#define SLSOURCE_GPS
GPS (or other satellite navigation) sources.
void destroy_program_state(program_state *s)
Cleanly destroy program state.
void log_info(const program_state *s, const int level, const char *format,...)
Output formatted information message at a given level.
void log_error(const program_state *s, const char *format,...)
Output formatted error message.
msg_data_t data
Embedded data.
uint8_t type
Message type. Common types to be documented.
uint8_t source
Maps to a specific sensor unit or data source.
Program state and logging information.
int verbose
Current log verbosity (console output)
bool started
Indicates startup completed.
float value
Generic numerical data.
uint8_t * bytes
Our "raw" binary type.
#define GIT_VERSION_STRING
Git version description.