17c881178SDavid du Colombier #include <u.h>
27c881178SDavid du Colombier #include <libc.h>
37c881178SDavid du Colombier #include "dat.h"
47c881178SDavid du Colombier
57c881178SDavid du Colombier char *serial = "/dev/eia0";
67c881178SDavid du Colombier
77c881178SDavid du Colombier int ttyfd, ctlfd, debug;
87c881178SDavid du Colombier int baud = Baud;
97c881178SDavid du Colombier char *baudstr = "b%dd1r1pns1l8i1w5";
107c881178SDavid du Colombier
117c881178SDavid du Colombier Place where = {-(74.0 + 23.9191/60.0), 40.0 + 41.1346/60.0};
127c881178SDavid du Colombier
137c881178SDavid du Colombier void setline(void);
147c881178SDavid du Colombier void evermore80(Place, int);
157c881178SDavid du Colombier void evermore89(int);
167c881178SDavid du Colombier void evermore8e(void);
177c881178SDavid du Colombier
187c881178SDavid du Colombier void
setline(void)197c881178SDavid du Colombier setline(void){
207c881178SDavid du Colombier char *serialctl;
217c881178SDavid du Colombier
227c881178SDavid du Colombier serialctl = smprint("%sctl", serial);
237c881178SDavid du Colombier if((ttyfd = open(serial, ORDWR)) < 0)
247c881178SDavid du Colombier sysfatal("%s: %r", serial);
257c881178SDavid du Colombier if((ctlfd = open(serialctl, OWRITE)) >= 0){
267c881178SDavid du Colombier if(fprint(ctlfd, baudstr, baud) < 0)
277c881178SDavid du Colombier sysfatal("%s: %r", serialctl);
287c881178SDavid du Colombier }
297c881178SDavid du Colombier free(serialctl);
307c881178SDavid du Colombier }
317c881178SDavid du Colombier
327c881178SDavid du Colombier enum {
337c881178SDavid du Colombier GGAon = 0x01,
347c881178SDavid du Colombier GLLon = 0x02,
357c881178SDavid du Colombier GSAon = 0x04,
367c881178SDavid du Colombier GSVon = 0x08,
377c881178SDavid du Colombier RMCon = 0x10,
387c881178SDavid du Colombier VTGon = 0x20,
397c881178SDavid du Colombier CRCon = 0x40,
407c881178SDavid du Colombier EMTon = 0x80
417c881178SDavid du Colombier };
427c881178SDavid du Colombier
437c881178SDavid du Colombier char*
putbyte(char * s,int v)447c881178SDavid du Colombier putbyte(char *s, int v)
457c881178SDavid du Colombier {
467c881178SDavid du Colombier *s++ = v;
477c881178SDavid du Colombier if((v & 0xff) == 0x10)
487c881178SDavid du Colombier *s++ = v;
497c881178SDavid du Colombier return s;
507c881178SDavid du Colombier }
517c881178SDavid du Colombier
527c881178SDavid du Colombier char*
putshort(char * s,int v)537c881178SDavid du Colombier putshort(char *s, int v)
547c881178SDavid du Colombier {
557c881178SDavid du Colombier s = putbyte(s, v);
567c881178SDavid du Colombier s = putbyte(s, v >> 8);
577c881178SDavid du Colombier return s;
587c881178SDavid du Colombier }
597c881178SDavid du Colombier
607c881178SDavid du Colombier char*
putlong(char * s,long v)617c881178SDavid du Colombier putlong(char *s, long v)
627c881178SDavid du Colombier {
637c881178SDavid du Colombier s = putbyte(s, v);
647c881178SDavid du Colombier s = putbyte(s, v >> 8);
657c881178SDavid du Colombier s = putbyte(s, v >> 16);
667c881178SDavid du Colombier s = putbyte(s, v >> 24);
677c881178SDavid du Colombier return s;
687c881178SDavid du Colombier }
697c881178SDavid du Colombier
707c881178SDavid du Colombier void
evermoresend(char * body,int l)717c881178SDavid du Colombier evermoresend(char *body, int l)
727c881178SDavid du Colombier {
737c881178SDavid du Colombier char buf[8], *s;
747c881178SDavid du Colombier int crc, i;
757c881178SDavid du Colombier
767c881178SDavid du Colombier s = buf;
777c881178SDavid du Colombier *s++ = 0x10; /* DCE */
787c881178SDavid du Colombier *s++ = 0x02; /* STX */
797c881178SDavid du Colombier s = putbyte(s, l); /* length */
807c881178SDavid du Colombier write(ttyfd, buf, s-buf); /* write header */
817c881178SDavid du Colombier
827c881178SDavid du Colombier write(ttyfd, body, l); /* write body */
837c881178SDavid du Colombier
847c881178SDavid du Colombier crc = 0;
857c881178SDavid du Colombier for(i = 0; i < l; i++)
867c881178SDavid du Colombier crc += body[i]; /* calculate crc */
877c881178SDavid du Colombier s = buf;
887c881178SDavid du Colombier s = putbyte(s, crc); /* checksum */
897c881178SDavid du Colombier *s++ = 0x10; /* DCE */
907c881178SDavid du Colombier *s++ = 0x03; /* ETX */
917c881178SDavid du Colombier write(ttyfd, buf, s-buf); /* write trailer */
927c881178SDavid du Colombier }
937c881178SDavid du Colombier
947c881178SDavid du Colombier void
evermore80(Place pl,int baud)957c881178SDavid du Colombier evermore80(Place pl, int baud)
967c881178SDavid du Colombier {
977c881178SDavid du Colombier char buf[32], *s;
987c881178SDavid du Colombier long now, seconds, week;
997c881178SDavid du Colombier
1007c881178SDavid du Colombier fprint(2, "Evermore80");
1017c881178SDavid du Colombier
1027c881178SDavid du Colombier time(&now);
1037c881178SDavid du Colombier seconds = now - 315964800;
1047c881178SDavid du Colombier week = (seconds / (7*24*3600));
1057c881178SDavid du Colombier seconds = seconds % (7*24*3600);
1067c881178SDavid du Colombier s = buf;
1077c881178SDavid du Colombier
1087c881178SDavid du Colombier s = putbyte(s, 0x80); /* message ID */
1097c881178SDavid du Colombier s = putshort(s, week); /* week number */
1107c881178SDavid du Colombier s = putlong(s, seconds*100); /* seconds */
1117c881178SDavid du Colombier s = putshort(s, pl.lat*10.0); /* latitude tenths degree */
1127c881178SDavid du Colombier s = putshort(s, pl.lon*10.0); /* longitude tenths degree */
1137c881178SDavid du Colombier s = putshort(s, 100); /* altitude meters */
1147c881178SDavid du Colombier s = putshort(s, 0); /* datumn ID */
1157c881178SDavid du Colombier s = putbyte(s, 2); /* warm start */
1167c881178SDavid du Colombier s = putbyte(s, GGAon|GSAon|GSVon|RMCon|CRCon);
1177c881178SDavid du Colombier switch(baud){
1187c881178SDavid du Colombier case 4800: s = putbyte(s, 0); break;
1197c881178SDavid du Colombier case 9600: s = putbyte(s, 1); break;
1207c881178SDavid du Colombier case 19200: s = putbyte(s, 2); break;
1217c881178SDavid du Colombier case 38400: s = putbyte(s, 3); break;
1227c881178SDavid du Colombier default:
1237c881178SDavid du Colombier sysfatal("Illegal baud rate");
1247c881178SDavid du Colombier }
1257c881178SDavid du Colombier
1267c881178SDavid du Colombier evermoresend(buf, s - buf);
1277c881178SDavid du Colombier fprint(2, "\n");
1287c881178SDavid du Colombier }
1297c881178SDavid du Colombier
1307c881178SDavid du Colombier void
evermore89(int baud)1317c881178SDavid du Colombier evermore89(int baud)
1327c881178SDavid du Colombier {
1337c881178SDavid du Colombier char buf[32], *s;
1347c881178SDavid du Colombier
1357c881178SDavid du Colombier fprint(2, "Evermore89");
1367c881178SDavid du Colombier s = buf;
1377c881178SDavid du Colombier s = putbyte(s, 0x89); /* message ID */
1387c881178SDavid du Colombier s = putbyte(s, 0x01); /* set main serial port */
1397c881178SDavid du Colombier switch(baud){
1407c881178SDavid du Colombier case 4800: s = putbyte(s, 0x00); break;
1417c881178SDavid du Colombier case 9600: s = putbyte(s, 0x01); break;
1427c881178SDavid du Colombier case 19200: s = putbyte(s, 0x02); break;
1437c881178SDavid du Colombier case 38400: s = putbyte(s, 0x03); break;
1447c881178SDavid du Colombier default:
145*14cc0f53SDavid du Colombier sysfatal("illegal baud rate %d", baud);
1467c881178SDavid du Colombier }
1477c881178SDavid du Colombier
1487c881178SDavid du Colombier evermoresend(buf, s - buf);
1497c881178SDavid du Colombier fprint(2, "\n");
1507c881178SDavid du Colombier }
1517c881178SDavid du Colombier
1527c881178SDavid du Colombier void
evermore8e(void)1537c881178SDavid du Colombier evermore8e(void)
1547c881178SDavid du Colombier {
1557c881178SDavid du Colombier char buf[32], *s;
1567c881178SDavid du Colombier
1577c881178SDavid du Colombier fprint(2, "Evermore8e");
1587c881178SDavid du Colombier s = buf;
1597c881178SDavid du Colombier s = putbyte(s, 0x8e); /* message ID */
1607c881178SDavid du Colombier s = putbyte(s, GGAon|GSAon|GSVon|RMCon); /* all messages except GLL and VTG */
1617c881178SDavid du Colombier s = putbyte(s, 0x01); /* checksum on */
1627c881178SDavid du Colombier s = putbyte(s, 0x01); /* GGA update rate */
1637c881178SDavid du Colombier s = putbyte(s, 0x0b); /* GLL update rate */
1647c881178SDavid du Colombier s = putbyte(s, 0x0a); /* GSA update rate */
1657c881178SDavid du Colombier s = putbyte(s, 0x14); /* GSV update rate */
1667c881178SDavid du Colombier s = putbyte(s, 0x08); /* RMC update rate */
1677c881178SDavid du Colombier s = putbyte(s, 0x0d); /* VTG update rate */
1687c881178SDavid du Colombier
1697c881178SDavid du Colombier evermoresend(buf, s - buf);
1707c881178SDavid du Colombier fprint(2, "\n");
1717c881178SDavid du Colombier }
1727c881178SDavid du Colombier
1737c881178SDavid du Colombier void
main(int argc,char * argv[])1747c881178SDavid du Colombier main(int argc, char*argv[])
1757c881178SDavid du Colombier {
1767c881178SDavid du Colombier char *p;
1777c881178SDavid du Colombier Place pl;
1787c881178SDavid du Colombier int newbaud;
1797c881178SDavid du Colombier
1807c881178SDavid du Colombier newbaud = -1;
1817c881178SDavid du Colombier pl = nowhere;
1827c881178SDavid du Colombier ARGBEGIN {
1837c881178SDavid du Colombier default:
1847c881178SDavid du Colombier fprint(2, "usage: %s [-b baud] [-d device] [-l longitude latitude] [-n newbaud]\n", argv0);
1857c881178SDavid du Colombier exits("usage");
1867c881178SDavid du Colombier case 'D':
1877c881178SDavid du Colombier debug++;
1887c881178SDavid du Colombier break;
1897c881178SDavid du Colombier case 'b':
1907c881178SDavid du Colombier baud = strtol(ARGF(), nil, 0);
1917c881178SDavid du Colombier break;
1927c881178SDavid du Colombier case 'd':
1937c881178SDavid du Colombier serial = ARGF();
1947c881178SDavid du Colombier break;
1957c881178SDavid du Colombier case 'l':
1967c881178SDavid du Colombier p = ARGF();
1977c881178SDavid du Colombier if(strtolatlon(p, &p, &pl) < 0)
1987c881178SDavid du Colombier sysfatal("bad position");
1997c881178SDavid du Colombier while(*p == ' ' || *p == '\t' || *p == '\n')
2007c881178SDavid du Colombier p++;
2017c881178SDavid du Colombier if(*p == '\0')
2027c881178SDavid du Colombier p = ARGF();
2037c881178SDavid du Colombier if (strtolatlon(p, &p, &pl) < 0)
2047c881178SDavid du Colombier sysfatal("bad position");
2057c881178SDavid du Colombier while(*p == ' ' || *p == '\t' || *p == '\n')
2067c881178SDavid du Colombier p++;
2077c881178SDavid du Colombier if(*p != '\0')
2087c881178SDavid du Colombier sysfatal("trailing gunk in position");
2097c881178SDavid du Colombier where = pl;
2107c881178SDavid du Colombier break;
2117c881178SDavid du Colombier case 'n':
2127c881178SDavid du Colombier newbaud = strtol(ARGF(), nil, 0);
2137c881178SDavid du Colombier break;
2147c881178SDavid du Colombier } ARGEND
2157c881178SDavid du Colombier
2167c881178SDavid du Colombier if(newbaud < 0)
2177c881178SDavid du Colombier newbaud = baud;
2187c881178SDavid du Colombier
2197c881178SDavid du Colombier fmtinstall('L', placeconv);
2207c881178SDavid du Colombier print("Initializing GPS to %d baud, at %L, time %s\n",
2217c881178SDavid du Colombier newbaud, where, ctime(time(nil)));
2227c881178SDavid du Colombier setline();
2237c881178SDavid du Colombier evermore80(where, newbaud);
2247c881178SDavid du Colombier }
225