Plan 9 from Bell Labs’s /sys/src/games/gps/gps55.c

Copyright © 2021 Plan 9 Foundation
Distributed under the MIT License.
Download the Plan 9 distribution.


#include	<u.h>
#include	<libc.h>
#include	<bio.h>

char	eiafile[] = "/dev/eia0";
char	gpslog[] = "/tmp/gpslog";
char	record[150];
char	databuf[150];
int	deltaalt;

long	gethhmmss(char*);
long	getddmmyy(char*);
long	getnumb(char*);

void
main(int argc, char *argv[])
{
	int c, fi, fl;
	int latns, lngew, magew;
	Biobuf gpb;
	char *p;
	long t0, t1, alt, lat, lng, speed, magvar, dir;

	ARGBEGIN {
	case 'A':
		deltaalt = atol(ARGF());
		break;
	} ARGEND
	p = eiafile;
	if(argc > 0)
		p = argv[0];
	sprint(record, "%sctl", p);
	fi = open(record, OWRITE);
	if(fi >= 0) {
		write(fi, "b4800", 5);
		close(fi);
	}
	fi = open(p, OREAD);
	if(fi < 0) {
		fprint(2, "cannot open %s\n", p);
		goto out;
	}
	Binit(&gpb, fi, OREAD);

	fl = open(gpslog, OWRITE);
	if(fl < 0) {
		fl = create(gpslog, OWRITE, 0666);
		if(fl < 0) {
			fprint(2, "cant create %s\n", gpslog);
			exits("create");
		}
	}
	seek(fl, 0, 2);

loop:
	p = record;
	for(;;) {
		c = Bgetc(&gpb);
		if(c < 0)
			goto out;
		c &= 0x7f;
		if(p >= record+sizeof(record))
			p = record;
		*p++ = c;
		if(c == '\n')
			break;
	}
	if(memcmp(record, "$GPRMC", 6))
		goto loop;
	p[-2] = 0;

	/* hhmmss 232310 */
	p = strchr(record, ',');
	if(p == 0)
		goto loop;
	p++;
	t1 = gethhmmss(p);
	if(t1 < 0)
		goto loop;

	/* alt A */
	p = strchr(p, ',');
	if(p == 0)
		goto loop;
	p++;
	alt = getnumb(p);
	if(alt < 0)
		alt = 0;
	else
		alt = alt/100 + deltaalt;

	/* lat 4042.11 */
	p = strchr(p, ',');
	if(p == 0)
		goto loop;
	p++;
	lat = getnumb(p);
	if(lat < 0)
		goto loop;

	/* NS N */
	p = strchr(p, ',');
	if(p == 0)
		goto loop;
	p++;
	latns = *p;
	if(latns != 'N' && latns != 'S')
		goto loop;

	/* lng 07424.28 */
	p = strchr(p, ',');
	if(p == 0)
		goto loop;
	p++;
	lng = getnumb(p);
	if(lng < 0)
		goto loop;

	/* EW W */
	p = strchr(p, ',');
	if(p == 0)
		goto loop;
	p++;
	lngew = *p;
	if(lngew != 'E' && lngew != 'W')
		goto loop;

	/* speed 032.2 */
	p = strchr(p, ',');
	if(p == 0)
		goto loop;
	p++;
	speed = getnumb(p);

	/* dir 315.6 */
	p = strchr(p, ',');
	if(p == 0)
		goto loop;
	p++;
	dir = getnumb(p);

	/* ddmmyy 081292 */
	p = strchr(p, ',');
	if(p == 0)
		goto loop;
	p++;
	t0 = getddmmyy(p);
	if(t0 < 0)
		goto loop;

	/* magvar 012.9 */
	p = strchr(p, ',');
	if(p == 0)
		goto loop;
	p++;
	magvar = getnumb(p);

	/* EW W*72 */
	p = strchr(p, ',');
	if(p == 0)
		goto loop;
	p++;
	magew = *p;
	if(magew != 'E' && magew != 'W')
		goto loop;

	sprint(databuf,
	"%11ld %3ld°%.2ld.%.2ld'%c %3ld°%.2ld.%.2ld'%c %5ld %3ld %3ld %c%2ld.%ld\n",
		t0+t1,
		lat/10000, lat%10000/100, lat%100, latns,
		lng/10000, lng%10000/100, lng%100, lngew,
		alt/100, speed/100, dir/100,
		magew, magvar/100, magvar%100/10);

	c = strlen(databuf);
	if(c != 58)
		print("len = %d\n", c);
	if(fl >= 0)
		write(fl, databuf, c);
	goto loop;

out:
	exits("error");
}

long
getddmmyy(char *p)
{
	static lastd, lastm, lasty, lastt;
	int d, m, y, c;
	long t;
	Tm *tm;

	c = p[0] - '0';
	if(c < 0 || c > 9)
		goto bad;
	d = c*10;
	c = p[1] - '0';
	if(c < 0 || c > 9)
		goto bad;
	d += c;

	c = p[2] - '0';
	if(c < 0 || c > 9)
		goto bad;
	m = c*10;
	c = p[3] - '0';
	if(c < 0 || c > 9)
		goto bad;
	m += c;
	m--;

	c = p[4] - '0';
	if(c < 0 || c > 9)
		goto bad;
	y = c*10;
	c = p[5] - '0';
	if(c < 0 || c > 9)
		goto bad;
	y += c;
	if(d == lastd && m == lastm && y == lasty)
		return lastt;

	t = 0;
	for(c=1000000; c; t+=c) {
		tm = gmtime(t);
		if(tm->year < y)
			continue;
		if(tm->year > y)
			goto dec;
		if(tm->mon < m)
			continue;
		if(tm->mon > m)
			goto dec;
		if(tm->mday < d)
			continue;
		if(tm->mday > d)
			goto dec;
		if(tm->hour || tm->min || tm->sec)
			goto dec;
		break;
	dec:
		t -= c;
		c /= 10;
	}
	lastd = d;
	lastm = m;
	lasty = y;
	lastt = t;
	return t;

bad:
	return -1;
}

long
gethhmmss(char *p)
{
	int c;
	long t;

	c = p[0] - '0';
	if(c < 0 || c > 9)
		goto bad;
	t = c*36000;
	c = p[1] - '0';
	if(c < 0 || c > 9)
		goto bad;
	t += c*3600;
	c = p[2] - '0';
	if(c < 0 || c > 9)
		goto bad;
	t += c*600;
	c = p[3] - '0';
	if(c < 0 || c > 9)
		goto bad;
	t += c*60;
	c = p[4] - '0';
	if(c < 0 || c > 9)
		goto bad;
	t += c*10;
	c = p[5] - '0';
	if(c < 0 || c > 9)
		goto bad;
	t += c*1;
	return t;

bad:
	return -1;
}

long
getnumb(char *p)
{
	int c;
	long t;

	for(t=0;;) {
		c = *p++;
		if(c == '.' || c == ',')
			break;
		if(c < '0' || c > '9')
			goto bad;
		t = t*10 + (c-'0');
	}
	t = t*100;
	if(c == '.') {
		c = *p++;
		if(c != ',') {
			if(c < '0' || c > '9')
				goto bad;
			t = t + (c-'0')*10;

			c = *p;
			if(c != ',') {
				if(c < '0' || c > '9')
					goto bad;
				t = t + (c-'0');
			}
		}
	}
	return t;

bad:
	return -1;
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@plan9.bell-labs.com.