1 /*
2  * This file is Copyright (c) 2010 by the GPSD project
3  * SPDX-License-Identifier: BSD-2-clause
4  */
5 
6 #include "gpsd_config.h"  /* must be before all includes */
7 
8 #include <stdio.h>
9 #include <string.h>     /* for strlcat() */
10 
11 #include "gpsd.h"
12 #include "bits.h"
13 #include "gpsmon.h"
14 
15 #ifdef ITRAX_ENABLE
16 #include "driver_italk.h"
17 
18 extern const struct gps_type_t driver_italk;
19 static WINDOW *satwin, *navfixwin;
20 
21 #define display	(void)mvwprintw
italk_initialize(void)22 static bool italk_initialize(void)
23 {
24     int i;
25 
26     /* "heavily inspired" by monitor_nmea.c */
27     if ((satwin =
28 	 derwin(devicewin, MAX_NR_VISIBLE_PRNS + 3, 27, 0, 0)) == NULL)
29 	return false;
30     (void)wborder(satwin, 0, 0, 0, 0, 0, 0, 0, 0), (void)syncok(satwin, true);
31     (void)wattrset(satwin, A_BOLD);
32     display(satwin, 1, 1, "Ch PRN  Az El S/N Flag U");
33     for (i = 0; i < MAX_NR_VISIBLE_PRNS; i++)
34 	display(satwin, (int)(i + 2), 1, "%2d", i);
35     display(satwin, MAX_NR_VISIBLE_PRNS + 2, 7, " PRN_STATUS ");
36     (void)wattrset(satwin, A_NORMAL);
37 
38     /* "heavily inspired" by monitor_nmea.c */
39     if ((navfixwin = derwin(devicewin, 13, 52, 0, 27)) == NULL)
40 	return false;
41     (void)wborder(navfixwin, 0, 0, 0, 0, 0, 0, 0, 0),
42 	(void)wattrset(navfixwin, A_BOLD);
43     (void)wmove(navfixwin, 1, 1);
44     (void)wprintw(navfixwin, "ECEF Pos:");
45     (void)wmove(navfixwin, 2, 1);
46     (void)wprintw(navfixwin, "ECEF Vel:");
47 
48     (void)wmove(navfixwin, 4, 1);
49     (void)wprintw(navfixwin, "LTP Pos:");
50     (void)wmove(navfixwin, 5, 1);
51     (void)wprintw(navfixwin, "LTP Vel:");
52 
53     (void)wmove(navfixwin, 7, 1);
54     (void)wprintw(navfixwin, "Time UTC:");
55     (void)wmove(navfixwin, 8, 1);
56     (void)wprintw(navfixwin, "Time GPS:                  Day:");
57 
58     (void)wmove(navfixwin, 10, 1);
59     (void)wprintw(navfixwin, "DOP [H]      [V]      [P]      [T]      [G]");
60     (void)wmove(navfixwin, 11, 1);
61     (void)wprintw(navfixwin, "Fix:");
62 
63     display(navfixwin, 12, 20, " NAV_FIX ");
64     (void)wattrset(navfixwin, A_NORMAL);
65     return true;
66 }
67 
display_itk_navfix(unsigned char * buf,size_t len)68 static void display_itk_navfix(unsigned char *buf, size_t len)
69 {
70     unsigned int tow, tod, d, svlist;
71     unsigned short gps_week, nsv;
72     unsigned short year, mon, day, hour, min, sec;
73     double epx, epy, epz, evx, evy, evz;
74     double latitude, longitude;
75     float altitude, speed, track, climb;
76     float hdop, gdop, pdop, vdop, tdop;
77 
78     if (len != 296)
79 	return;
80 
81 #ifdef __UNUSED__
82     flags = (unsigned short) getleu16(buf, 7 + 4);
83     cflags = (unsigned short) getleu16(buf, 7 + 6);
84     pflags = (unsigned short) getleu16(buf, 7 + 8);
85 #endif /* __UNUSED__ */
86 
87 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
88     nsv = (unsigned short) MAX(getleu16(buf, 7 + 12), getleu16(buf, 7 + 14));
89     svlist = (unsigned int) ((unsigned short) getleu32(buf, 7 + 16) | getleu32(buf, 7 + 24));
90 
91     hour = (unsigned short) getleu16(buf, 7 + 66);
92     min = (unsigned short) getleu16(buf, 7 + 68);
93     sec = (unsigned short) getleu16(buf, 7 + 70);
94     //nsec = (unsigned short) getleu32(buf, 7 + 72);
95     year = (unsigned short) getleu16(buf, 7 + 76);
96     mon = (unsigned short) getleu16(buf, 7 + 78);
97     day = (unsigned short) getleu16(buf, 7 + 80);
98     gps_week = (unsigned short) getles16(buf, 7 + 82);
99     tow = (unsigned short) getleu32(buf, 7 + 84);
100 
101     epx = (double)(getles32(buf, 7 + 96) / 100.0);
102     epy = (double)(getles32(buf, 7 + 100) / 100.0);
103     epz = (double)(getles32(buf, 7 + 104) / 100.0);
104     evx = (double)(getles32(buf, 7 + 186) / 1000.0);
105     evy = (double)(getles32(buf, 7 + 190) / 1000.0);
106     evz = (double)(getles32(buf, 7 + 194) / 1000.0);
107 
108     latitude = (double)(getles32(buf, 7 + 144) / 1e7);
109     longitude = (double)(getles32(buf, 7 + 148) / 1e7);
110     altitude = (float)(getles32(buf, 7 + 152) / 1e3);
111     climb = (float)(getles32(buf, 7 + 206) / 1e3);
112     speed = (float)(getleu32(buf, 7 + 210) / 1e3);
113     track = (float)(getleu16(buf, 7 + 214) / 1e2);
114 
115     hdop = (float)(getleu16(buf, 7 + 56) / 100.0);
116     gdop = (float)(getleu16(buf, 7 + 58) / 100.0);
117     pdop = (float)(getleu16(buf, 7 + 60) / 100.0);
118     vdop = (float)(getleu16(buf, 7 + 62) / 100.0);
119     tdop = (float)(getleu16(buf, 7 + 64) / 100.0);
120 
121     (void)wmove(navfixwin, 1, 11);
122     (void)wprintw(navfixwin, "%12.2lf %12.2lf %12.2lfm", epx, epy, epz);
123     (void)wmove(navfixwin, 2, 11);
124     (void)wprintw(navfixwin, "%11.2lf %11.2lf %11.2lfm/s", evx, evy, evz);
125 
126     (void)wmove(navfixwin, 4, 11);
127     (void)wprintw(navfixwin, "%11.8lf   %13.8lf %8.1lfm",
128 		  latitude, longitude, altitude);
129     (void)mvwaddch(navfixwin, 4, 22, ACS_DEGREE);
130     (void)mvwaddch(navfixwin, 4, 38, ACS_DEGREE);
131     (void)wmove(navfixwin, 5, 11);
132     (void)wprintw(navfixwin, "%6.2lfm/s  %5.1lf  %6.2lfm/s climb",
133 		  speed, track, climb);
134     (void)mvwaddch(navfixwin, 5, 27, ACS_DEGREE);
135 
136     (void)wmove(navfixwin, 7, 11);
137     (void)wprintw(navfixwin, "%04u-%02u-%02u %02u:%02u:%02u",
138 		  year, mon, day, hour, min, sec);
139     (void)wmove(navfixwin, 8, 11);
140     (void)wprintw(navfixwin, "%04u+%010.3lf", gps_week, tow / 1000.0);
141     (void)wmove(navfixwin, 8, 33);
142     d = (tow / 1000) / 86400;
143     tod = (tow / 1000) - (d * 86400);
144     sec = (unsigned short)tod % 60;
145     min = (unsigned short)(tod / 60) % 60;
146     hour = (unsigned short)tod / 3600;
147     (void)wprintw(navfixwin, "%1d %02d:%02d:%02d", d, hour, min, sec);
148 
149     (void)wmove(navfixwin, 10, 9);
150     (void)wprintw(navfixwin, "%-5.1f", hdop);
151     (void)wmove(navfixwin, 10, 18);
152     (void)wprintw(navfixwin, "%-5.1f", vdop);
153     (void)wmove(navfixwin, 10, 27);
154     (void)wprintw(navfixwin, "%-5.1f", pdop);
155     (void)wmove(navfixwin, 10, 36);
156     (void)wprintw(navfixwin, "%-5.1f", tdop);
157     (void)wmove(navfixwin, 10, 45);
158     (void)wprintw(navfixwin, "%-5.1f", gdop);
159 
160     (void)wmove(navfixwin, 11, 6);
161     {
162 	char prn[4], satlist[38];
163 	unsigned long i;         // unsigned long just in case ints are 32-bit
164 	satlist[0] = '\0';
165 	for (i = 0; i < 32; i++) {
166 	    if (svlist & (1 << i)) {
167 		(void)snprintf(prn, 4, "%lu ", i + 1);
168 		(void)strlcat(satlist, prn, sizeof(satlist));
169 	    }
170 	}
171 	(void)wprintw(navfixwin, "%02d = %-38s", nsv, satlist);
172     }
173     (void)wnoutrefresh(navfixwin);
174 
175 }
176 
display_itk_prnstatus(unsigned char * buf,size_t len)177 static void display_itk_prnstatus(unsigned char *buf, size_t len)
178 {
179     int i, nchan;
180     if (len < 62)
181 	return;
182 
183     nchan = (int)getleu16(buf, 7 + 50);
184     if (nchan > MAX_NR_VISIBLE_PRNS)
185 	nchan = MAX_NR_VISIBLE_PRNS;
186     for (i = 0; i < nchan; i++) {
187 	int off = 7 + 52 + 10 * i;
188 	unsigned short fl;
189 	unsigned char ss, prn, el, az;
190 
191 	fl = (unsigned short)getleu16(buf, off);
192 	ss = (unsigned char)getleu16(buf, off + 2) & 0xff;
193 	prn = (unsigned char)getleu16(buf, off + 4) & 0xff;
194 	el = (unsigned char)getles16(buf, off + 6) & 0xff;
195 	az = (unsigned char)getles16(buf, off + 8) & 0xff;
196 	(void)wmove(satwin, i + 2, 4);
197 	(void)wprintw(satwin, "%3d %3d %2d  %02d %04x %c",
198 		      prn, az, el, ss, fl,
199 		      (fl & PRN_FLAG_USE_IN_NAV) ? 'Y' : ' ');
200     }
201     for (; i < MAX_NR_VISIBLE_PRNS; i++) {
202 	(void)wmove(satwin, (int)i + 2, 4);
203 	(void)wprintw(satwin, "                      ");
204     }
205     (void)wnoutrefresh(satwin);
206     return;
207 }
208 
italk_update(void)209 static void italk_update(void)
210 {
211     unsigned char *buf;
212     size_t len;
213     unsigned char type;
214 
215     buf = session.lexer.outbuffer;
216     len = session.lexer.outbuflen;
217     type = (unsigned char)getub(buf, 4);
218     switch (type) {
219     case ITALK_NAV_FIX:
220 	display_itk_navfix(buf, len);
221 	break;
222     case ITALK_PRN_STATUS:
223 	display_itk_prnstatus(buf, len);
224 	break;
225     default:
226 	break;
227     }
228 }
229 
italk_command(char line[]UNUSED)230 static int italk_command(char line[]UNUSED)
231 {
232     return COMMAND_UNKNOWN;
233 }
234 
italk_wrap(void)235 static void italk_wrap(void)
236 {
237     (void)delwin(satwin);
238     return;
239 }
240 
241 const struct monitor_object_t italk_mmt = {
242     .initialize = italk_initialize,
243     .update = italk_update,
244     .command = italk_command,
245     .wrap = italk_wrap,
246     .min_y = 23,.min_x = 80,	/* size of the device window */
247     .driver = &driver_italk,
248 };
249 #endif
250