summaryrefslogtreecommitdiff
path: root/rtcmdecode.c
blob: 972a246721b47a5194adc43339828cd2ed720c69 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdbool.h>
#include <ctype.h>

#include "gpsd.h"

static int verbose = RTCM_ERRLEVEL_BASE;

void gpsd_report(int errlevel, const char *fmt, ... )
/* assemble command in printf(3) style, use stderr or syslog */
{
    if (errlevel <= verbose) {
	char buf[BUFSIZ];
	va_list ap;

	strcpy(buf, "rtcmdecode: ");
	va_start(ap, fmt) ;
	(void)vsnprintf(buf + strlen(buf), sizeof(buf)-strlen(buf), fmt, ap);
	va_end(ap);
	(void)fputs(buf, stdout);
    }
}

static void decode(FILE *fpin, FILE *fpout)
/* RTCM-104 bits on fpin to dump format on fpout */
{
    int             c;
    struct gps_device_t device;
    enum isgpsstat_t res;
    off_t count;
    char buf[BUFSIZ];

    isgps_init(&device);

    count = 0;
    while ((c = fgetc(fpin)) != EOF) {
	res = rtcm_decode(&device, (unsigned int)c);
	if (verbose >= RTCM_ERRLEVEL_BASE + 3) 
	    fprintf(fpout, "%08lu: '%c' [%02x] -> %d\n", 
		   (unsigned long)count++, (isprint(c)?c:'.'), (unsigned)(c & 0xff), res);
	if (res == ISGPS_MESSAGE) {
	    rtcm_dump(&device, buf, sizeof(buf));
	    (void)fputs(buf, fpout);
	}
    }
}

static void passthrough(FILE *fpin, FILE *fpout)
/* dump format on stdin to dump format on stdout (self-inversion test) */
{
    char buf[BUFSIZ];
    struct gps_device_t rtcmdata;

    memset(&rtcmdata, 0, sizeof(rtcmdata));
    while (fgets(buf, sizeof(buf), fpin) != NULL) {
	int status;

	/* pass through comment lines without interpreting */
	if (buf[0] == '#') {
	    (void)fputs(buf, fpout);
	    continue;
	}

	status = rtcm_undump(&rtcmdata.gpsdata.rtcm, buf);

	if (status == 0) {
	    //rtcm_repack(&rtcmdata);
	    //rtcm_unpack(&rtcmdata);
	    (void)rtcm_dump(&rtcmdata, buf, sizeof(buf));
	    (void)fputs(buf, fpout);
	    memset(&rtcmdata, 0, sizeof(rtcmdata));
	} else if (status < 0) {
	    (void) fprintf(stderr, "rtcmdecode: bailing out with status %d\n", status);
	    exit(1);
	}
    }
}

int main(int argc, char **argv)
{
    char buf[BUFSIZ];
    int c;
    bool striphdr = false;
    bool pass = false;

    while ((c = getopt(argc, argv, "hpv:")) != EOF) {
	switch (c) {
	case 'h':	/* not documented, used for debugging */
	    striphdr = true;
	    break;

	case 'p':	/* not documented, used for debugging */
	    pass = true;
	    break;

	case 'v':		/* verbose */
	    verbose = RTCM_ERRLEVEL_BASE + atoi(optarg);
	    break;

	case '?':
	default:
	    (void)fputs("rtcmdecode [-v]\n", stderr);
	    exit(1);
	}
    }
    argc -= optind;
    argv += optind;

    /* strip lines with leading # */
    if (striphdr) {
	while ((c = getchar()) == '#')
	    (void)fgets(buf, (int)sizeof(buf), stdin);
	(void)ungetc(c, stdin);
    }

    if (pass)
	passthrough(stdin, stdout);
    else
	decode(stdin, stdout);
    exit(0);
}

/* rtcmdecode.c ends here */