static void bedumpall(void) { (void)printf("getsb: %016" PRIx64 " %016" PRIx64 " %016" PRIx64 " %016" PRIx64 "\n", (uint64_t) sb1, (uint64_t) sb2, (uint64_t) getsb(buf, 0), (uint64_t) getsb(buf, 8)); (void)printf("getub: %016" PRIx64 " %016" PRIx64 " %016" PRIx64 " %016" PRIx64 "\n", (uint64_t) ub1, (uint64_t) ub2, (uint64_t) getub(buf, 0), (uint64_t) getub(buf, 8)); (void)printf("getbes16: %016" PRIx64 " %016" PRIx64 " %016" PRIx64 " %016" PRIx64 "\n", (uint64_t) sw1, (uint64_t) sw2, (uint64_t) getbes16(buf, 0), (uint64_t) getbes16(buf, 8)); (void)printf("getbeu16: %016" PRIx64 " %016" PRIx64 " %016" PRIx64 " %016" PRIx64 "\n", (uint64_t) uw1, (uint64_t) uw2, (uint64_t) getbeu16(buf, 0), (uint64_t) getbeu16(buf, 8)); (void)printf("getbes32: %016" PRIx64 " %016" PRIx64 " %016" PRIx64 " %016" PRIx64 "\n", (uint64_t) sl1, (uint64_t) sl2, (uint64_t) getbes32(buf, 0), (uint64_t) getbes32(buf, 8)); (void)printf("getbeu32: %016" PRIx64 " %016" PRIx64 " %016" PRIx64 " %016" PRIx64 "\n", (uint64_t) ul1, (uint64_t) ul2, (uint64_t) getbeu32(buf, 0), (uint64_t) getbeu32(buf, 8)); (void)printf("getbes64: %016" PRIx64 " %016" PRIx64 " %016" PRIx64 " %016" PRIx64 "\n", (uint64_t) sL1, (uint64_t) sL2, (uint64_t) getbes64(buf, 0), (uint64_t) getbes64(buf, 8)); (void)printf("getbeu64: %016" PRIx64 " %016" PRIx64 " %016" PRIx64 " %016" PRIx64 "\n", (uint64_t) uL1, (uint64_t) uL2, (uint64_t) getbeu64(buf, 0), (uint64_t) getbeu64(buf, 8)); (void)printf("getbef32: %f %f\n", f1, getbef32((const char *)buf, 24)); (void)printf("getbed64: %.16f %.16f\n", d1, getbed64((const char *)buf, 16)); }
/* * decode MID 0xDC, Measurement Time * * 10 bytes */ static gps_mask_t sky_msg_DC(struct gps_device_t *session, unsigned char *buf, size_t len) { unsigned int iod; /* Issue of data 0 - 255 */ unsigned int wn; /* week number 0 - 65535 */ unsigned int tow; /* receiver tow 0 - 604799999 in mS */ unsigned int mp; /* measurement period 1 - 1000 ms */ /* calculated */ double f_tow; /* tow in seconds */ unsigned int msec; /* mSec part of tow */ if ( 10 != len) return 0; iod = (unsigned int)getub(buf, 1); wn = getbeu16(buf, 2); tow = getbeu32(buf, 4); f_tow = (double)(tow / 1000); msec = tow % 1000; mp = getbeu16(buf, 8); /* should this be newdata.skyview_time? */ session->gpsdata.skyview_time = gpsd_gpstime_resolve(session, wn, f_tow ); gpsd_log(&session->context->errout, LOG_DATA, "Skytraq: MID 0xDC: iod=%u, wn=%u, tow=%u, mp=%u, t=%lld.%03u\n", iod, wn, tow, mp, (long long)session->gpsdata.skyview_time, msec); return 0; }
/*@ -duplicatequals +ignorequals @*/ int main(int argc, char *argv[]) { bool failures = false; bool quiet = (argc > 1) && (strcmp(argv[1], "--quiet") == 0); /*@ -observertrans -usereleased @*/ struct unsigned_test *up, unsigned_tests[] = { /* tests using the big buffer */ {buf, 0, 1, 0, false, "first bit of first byte"}, {buf, 0, 8, 0x01, false, "first 8 bits"}, {buf, 32, 7, 0x02, false, "first seven bits of fifth byte (0x05)"}, {buf, 56, 12, 0x8f, false, "12 bits crossing 7th to 8th bytes (0x08ff)"}, {buf, 78, 4, 0xb, false, "4 bits crossing 8th to 9th byte (0xfefd)"}, {buf, 0, 1, 0, true, "first bit of first byte"}, {buf, 0, 8, 0x80, true, "first 8 bits"}, {buf, 32, 7, 0x20, true, "first seven bits of fifth byte (0x05)"}, {buf, 56, 12, 0xf10,true, "12 bits crossing 7th to 8th bytes (0x08ff)"}, {buf, 78, 4, 0xd, true, "4 bits crossing 8th to 9th byte (0xfefd)"}, /* sporadic tests based on found bugs */ {(unsigned char *)"\x19\x23\f6", 7, 2, 2, false, "2 bits crossing 1st to 2nd byte (0x1923)"}, }; unsigned char *sp; memcpy(buf, "\x01\x02\x03\x04\x05\x06\x07\x08", 8); memcpy(buf + 8, "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8", 8); memcpy(buf + 16, "\x40\x09\x21\xfb\x54\x44\x2d\x18", 8); memcpy(buf + 24, "\x40\x49\x0f\xdb", 4); /*@ +observertrans +usereleased @*/ /*@-type@*/ sb1 = getsb(buf, 0); sb2 = getsb(buf, 8); ub1 = getub(buf, 0); ub2 = getub(buf, 8); sw1 = getbes16(buf, 0); sw2 = getbes16(buf, 8); uw1 = getbeu16(buf, 0); uw2 = getbeu16(buf, 8); sl1 = getbes32(buf, 0); sl2 = getbes32(buf, 8); ul1 = getbeu32(buf, 0); ul2 = getbeu32(buf, 8); sL1 = getbes64(buf, 0); sL2 = getbes64(buf, 8); uL1 = getbeu64(buf, 0); uL2 = getbeu64(buf, 8); f1 = getbef32((const char *)buf, 24); d1 = getbed64((const char *)buf, 16); sb1 = getsb(buf, 0); sb2 = getsb(buf, 8); ub1 = getub(buf, 0); ub2 = getub(buf, 8); sw1 = getles16(buf, 0); sw2 = getles16(buf, 8); uw1 = getleu16(buf, 0); uw2 = getleu16(buf, 8); sl1 = getles32(buf, 0); sl2 = getles32(buf, 8); ul1 = getleu32(buf, 0); ul2 = getleu32(buf, 8); sL1 = getles64(buf, 0); sL2 = getles64(buf, 8); uL1 = getleu64(buf, 0); uL2 = getleu64(buf, 8); f1 = getlef32((const char *)buf, 24); d1 = getled64((const char *)buf, 16); /*@+type@*/ if (!quiet) { (void)fputs("Test data:", stdout); for (sp = buf; sp < buf + 28; sp++) (void)printf(" %02x", *sp); (void)putc('\n', stdout); /* big-endian test */ printf("Big-endian:\n"); bedumpall(); /* little-endian test */ printf("Little-endian:\n"); ledumpall(); } if (sb1 != 1) printf("getsb(buf, 0) FAILED\n"); if (sb2 != -1) printf("getsb(buf, 8) FAILED\n"); if (ub1 != 1) printf("getub(buf, 0) FAILED\n"); if (ub2 != 0xff) printf("getub(buf, 8) FAILED\n"); (void)printf("Testing bitfield extraction\n"); for (up = unsigned_tests; up < unsigned_tests + sizeof(unsigned_tests) / sizeof(unsigned_tests[0]); up++) { uint64_t res = ubits((unsigned char *)buf, up->start, up->width, up->le); bool success = (res == up->expected); if (!success) failures = true; if (!success || !quiet) (void)printf("ubits(%s, %d, %d, %s) %s should be %" PRIx64 ", is %" PRIx64 ": %s\n", hexdump(buf, strlen((char *)buf)), up->start, up->width, up->le ? "true" : "false", up->description, up->expected, res, success ? "succeeded" : "FAILED"); } exit(failures ? EXIT_FAILURE : EXIT_SUCCESS); }
static void sirf_update(void) { int i, j, ch, sv; unsigned char *buf; size_t len; uint8_t dgps; char tbuf[JSON_DATE_MAX+1]; buf = session.lexer.outbuffer + 4; len = session.lexer.outbuflen - 8; switch (buf[0]) { case 0x02: /* Measured Navigation Data */ (void)wmove(mid2win, 1, 6); /* ECEF position */ (void)wprintw(mid2win, "%8d %8d %8d", getbes32(buf, 1), getbes32(buf, 5), getbes32(buf, 9)); (void)wmove(mid2win, 2, 6); /* ECEF velocity */ (void)wprintw(mid2win, "%8.1f %8.1f %8.1f", (double)getbes16(buf, 13) / 8, (double)getbes16(buf, 15) / 8, (double)getbes16(buf, 17) / 8); decode_ecef((double)getbes32(buf, 1), (double)getbes32(buf, 5), (double)getbes32(buf, 9), (double)getbes16(buf, 13) / 8, (double)getbes16(buf, 15) / 8, (double)getbes16(buf, 17) / 8); /* line 3 */ (void)wmove(mid2win, 3, 7); (void)wprintw(mid2win, "%-24s", unix_to_iso8601(session.gpsdata.fix.time, tbuf, sizeof(tbuf)) ); (void)wmove(mid2win, 3, 38); (void)wattrset(mid2win, A_UNDERLINE); if (ppstime_enabled) (void)wprintw(mid2win, "%02d", leapseconds); else (void)wprintw(mid2win, "??"); (void)wattrset(mid2win, A_NORMAL); /* line 4 */ /* HDOP */ (void)wmove(mid2win, 4, 59); (void)wprintw(mid2win, "%4.1f", (double)getub(buf, 20) / 5); /* Mode 1 */ (void)wmove(mid2win, 4, 69); (void)wprintw(mid2win, "%02x", getub(buf, 19)); /* Mode 2 */ (void)wmove(mid2win, 4, 77); (void)wprintw(mid2win, "%02x", getub(buf, 21)); /* SVs in fix */ (void)wmove(mid2win, 4, 6); (void)wprintw(mid2win, "%2d = ", (int)getub(buf, 28)); /* SV list */ (void)wmove(mid2win, 4, 10); /* coverity_submit[tainted_data] */ for (i = 0; i < (int)getub(buf, 28); i++) (void)wprintw(mid2win, " %2d", (int)getub(buf, 29 + i)); monitor_log("MND 0x02="); break; case 0x04: /* Measured Tracking Data */ ch = (int)getub(buf, 7); for (i = 0; i < ch; i++) { int az, el, state, off; double cn; off = 8 + 15 * i; (void)wmove(mid4win, i + 2, 3); sv = (int)getub(buf, off); az = (int)getub(buf, off + 1) * 3 / 2; el = (int)getub(buf, off + 2) / 2; state = (int)getbeu16(buf, off + 3); cn = 0; for (j = 0; j < 10; j++) cn += (int)getub(buf, off + 5 + j); cn /= 10; (void)wprintw(mid4win, " %3d %3d %2d %04x %4.1f %c", sv, az, el, state, cn, state == 0xbf ? 'T' : ' '); } monitor_log("MTD 0x04="); break; #ifdef __UNUSED__ case 0x05: /* raw track data */ for (off = 1; off < len; off += 51) { ch = getbeu32(buf, off); (void)wmove(mid4win, ch + 2, 19); cn = 0; for (j = 0; j < 10; j++) cn += getub(buf, off + 34 + j); printw("%5.1f", (double)cn / 10); printw("%9d%3d%5d", getbeu32(buf, off + 8), (int)getbeu16(buf, off + 12), (int)getbeu16(buf, off + 14)); printw("%8.5f %10.5f", (double)getbeu32(buf, off + 16) / 65536, (double)getbeu32(buf, off + 20) / 1024); } monitor_log("RTD 0x05="); break; #endif /* __UNUSED */ case 0x06: /* firmware version */ display(mid6win, 1, 1, "%s", buf + 1); monitor_log("FV 0x06="); break; case 0x07: /* Response - Clock Status Data */ display(mid7win, 1, 5, "%2d", getub(buf, 7)); /* SVs */ display(mid7win, 1, 16, "%lu", getbeu32(buf, 8)); /* Clock ppstimes */ display(mid7win, 1, 29, "%lu", getbeu32(buf, 12)); /* Clock Bias */ display(mid7win, 2, 11, "%lu", getbeu32(buf, 16)); /* Estimated Time */ monitor_log("CSD 0x07="); break; case 0x08: /* 50 BPS data */ ch = (int)getub(buf, 1); sv = (int)getub(buf, 2); display(mid4win, ch + 2, 27, "%2d", sv); subframe_enabled = true; monitor_log("50B 0x08="); break; case 0x09: /* Throughput */ display(mid9win, 1, 6, "%.3f", (double)getbeu16(buf, 1) / 186); /*SegStatMax */ display(mid9win, 1, 18, "%.3f", (double)getbeu16(buf, 3) / 186); /*SegStatLat */ display(mid9win, 1, 31, "%.3f", (double)getbeu16(buf, 5) / 186); /*SegStatTime */ display(mid9win, 1, 42, "%3d", (int)getbeu16(buf, 7)); /* Last Millisecond */ monitor_log("THR 0x09="); break; case 0x0b: /* Command Acknowledgement */ monitor_log("ACK 0x0b="); break; case 0x0c: /* Command NAcknowledgement */ monitor_log("NAK 0x0c="); break; case 0x0d: /* Visible List */ display(mid13win, 1, 1, "%02d = ", getub(buf, 1)); (void)wmove(mid13win, 1, 5); for (i = 0; i < (int)getub(buf, 1); i++) (void)wprintw(mid13win, " %d", getub(buf, 2 + 5 * i)); monitor_log("VL 0x0d="); break; case 0x13: #define YESNO(n) (((int)getub(buf, n) != 0)?'Y':'N') display(mid19win, 1, 20, "%d", getub(buf, 5)); /* Alt. hold mode */ display(mid19win, 2, 20, "%d", getub(buf, 6)); /* Alt. hold source */ display(mid19win, 3, 20, "%dm", (int)getbeu16(buf, 7)); /* Alt. source input */ if (getub(buf, 9) != (uint8_t) '\0') display(mid19win, 4, 20, "%dsec", getub(buf, 10)); /* Degraded timeout */ else display(mid19win, 4, 20, "N/A "); display(mid19win, 5, 20, "%dsec", getub(buf, 11)); /* DR timeout */ display(mid19win, 6, 20, "%c", YESNO(12)); /* Track smooth mode */ display(mid19win, 7, 20, "%c", YESNO(13)); /* Static Nav. */ display(mid19win, 8, 20, "0x%x", getub(buf, 14)); /* 3SV Least Squares */ display(mid19win, 9, 20, "0x%x", getub(buf, 19)); /* DOP Mask mode */ display(mid19win, 10, 20, "0x%x", (int)getbeu16(buf, 20)); /* Nav. Elev. mask */ display(mid19win, 11, 20, "0x%x", getub(buf, 22)); /* Nav. Power mask */ display(mid19win, 12, 20, "0x%x", getub(buf, 27)); /* DGPS Source */ display(mid19win, 13, 20, "0x%x", getub(buf, 28)); /* DGPS Mode */ display(mid19win, 14, 20, "%dsec", getub(buf, 29)); /* DGPS Timeout */ display(mid19win, 1, 42, "%c", YESNO(34)); /* LP Push-to-Fix */ display(mid19win, 2, 42, "%dms", getbeu32(buf, 35)); /* LP On Time */ display(mid19win, 3, 42, "%d", getbeu32(buf, 39)); /* LP Interval */ display(mid19win, 4, 42, "%c", YESNO(43)); /* User Tasks enabled */ display(mid19win, 5, 42, "%d", getbeu32(buf, 44)); /* User Task Interval */ display(mid19win, 6, 42, "%c", YESNO(48)); /* LP Power Cycling Enabled */ display(mid19win, 7, 42, "%d", getbeu32(buf, 49)); /* LP Max Acq Search Time */ display(mid19win, 8, 42, "%d", getbeu32(buf, 53)); /* LP Max Off Time */ display(mid19win, 9, 42, "%c", YESNO(57)); /* APM Enabled */ display(mid19win, 10, 42, "%d", (int)getbeu16(buf, 58)); /* # of fixes */ display(mid19win, 11, 42, "%d", (int)getbeu16(buf, 60)); /* Time Between fixes */ display(mid19win, 12, 42, "%d", getub(buf, 62)); /* H/V Error Max */ display(mid19win, 13, 42, "%d", getub(buf, 63)); /* Response Time Max */ display(mid19win, 14, 42, "%d", getub(buf, 64)); /* Time/Accu & Duty Cycle Priority */ #undef YESNO monitor_log("NP 0x13="); break; case 0x1b: /****************************************************************** Not actually documented in any published materials before the 1.6 version of the SiRF binary protocol manual. Here is what Chris Kuethe got from the SiRF folks, (plus some corrections from the GpsPaSsion forums): Start of message ---------------- Message ID 1 byte 27 Correction Source 1 byte 0=None, 1=SBAS, 2=Serial, 3=Beacon, 4=Software total: 2 bytes Middle part of message varies if using beacon or other: ------------------------------------------------------- If Beacon: Receiver Freq Hz 4 bytes Bit rate BPS 1 byte Status bit map 1 byte 01=Signal Valid, 02=Auto frequency detect 04=Auto bit rate detect Signal Magnitude 4 bytes Note: in internal units Signal Strength dB 2 bytes derived from Signal Magnitude SNR dB 2 bytes total: 14 bytes If Not Beacon: Correction Age[12] 1 byte x 12 Age in seconds in same order as follows Reserved 2 bytes total: 14 bytes End of Message -------------- Repeated 12 times (pad with 0 if less than 12 SV corrections): SVID 1 byte Correction (cm) 2 bytes (signed short) total 3 x 12 = 36 bytes ******************************************************************/ dgps = getub(buf, 1); display(mid27win, 1, 1, "%8s = ", (CHECK_RANGE(dgpsvec, dgps) ? dgpsvec[dgps] : "???")); (void)wmove(mid27win, 1, 11); for (ch = 0; ch < SIRF_CHANNELS; ch++) if (getub(buf, 16 + 3 * ch) != '\0') (void)wprintw(mid27win, " %d", getub(buf, 16 + 3 * ch)); monitor_log("DST 0x1b="); break; case 0x1c: /* NL Measurement Data */ case 0x1d: /* NL DGPS Data */ case 0x1e: /* NL SV State Data */ case 0x1f: /* NL Initialized Data */ subframe_enabled = true; monitor_log("NL 0x%02x=", buf[0]); break; case 0x29: /* Geodetic Navigation Data */ monitor_log("GND 0x29="); break; case 0x32: /* SBAS Parameters */ monitor_log("SBP 0x32="); break; case 0x34: /* PPS Time */ ppstime_enabled = true; leapseconds = (int)getbeu16(buf, 8); monitor_log("PPS 0x34="); break; case 0xff: /* Development Data */ while (len > 0 && buf[len - 1] == '\n') len--; while (len > 0 && buf[len - 1] == ' ') len--; buf[len] = '\0'; j = 1; for (i = 0; verbpat[i] != NULL; i++) if (str_starts_with((char *)(buf + 1), verbpat[i])) { j = 0; break; } if (j != 0) monitor_log("%s\n", buf + 1); monitor_log("DD 0xff="); break; default: monitor_log("UNK 0x%02x=", buf[0]); break; } #ifdef CONTROLSEND_ENABLE /* elicit navigation parameters */ if (dispmode && (time(NULL) % 10 == 0)) { (void)monitor_control_send((unsigned char *)"\x98\x00", 2); } #endif /* CONTROLSEND_ENABLE */ /* clear the 50bps data field every 6 seconds */ if (subframe_enabled && (time(NULL) % 6 == 0)) { for (ch = 0; ch < SIRF_CHANNELS; ch++) display(mid4win, ch + 2, 27, " "); } if (dispmode) { (void)touchwin(mid19win); (void)wnoutrefresh(mid19win); } #ifdef PPS_ENABLE pps_update(mid7win, 2, 32); #endif /* PPS_ENABLE */ }
/* * Decode the navigation solution message */ static gps_mask_t oncore_msg_navsol(struct gps_device_t *session, unsigned char *buf, size_t data_len) { gps_mask_t mask; unsigned char flags; double lat, lon, alt; float speed, track, dop; unsigned int i, j, st, nsv; int Bbused; struct tm unpacked_date; if (data_len != 76) return 0; mask = ONLINE_SET; gpsd_log(&session->context->errout, LOG_DATA, "oncore NAVSOL - navigation data\n"); flags = (unsigned char)getub(buf, 72); /*@ -predboolothers @*/ if (flags & 0x20) { session->gpsdata.status = STATUS_FIX; session->newdata.mode = MODE_3D; } else if (flags & 0x10) { session->gpsdata.status = STATUS_FIX; session->newdata.mode = MODE_2D; } else { gpsd_log(&session->context->errout, LOG_WARN, "oncore NAVSOL no fix - flags 0x%02x\n", flags); session->newdata.mode = MODE_NO_FIX; session->gpsdata.status = STATUS_NO_FIX; } mask |= MODE_SET; /*@ +predboolothers @*/ /* Unless we have seen non-zero utc offset data, the time is GPS time * and not UTC time. Do not use it. */ if (session->context->leap_seconds) { unsigned int nsec; unpacked_date.tm_mon = (int)getub(buf, 4) - 1; unpacked_date.tm_mday = (int)getub(buf, 5); unpacked_date.tm_year = (int)getbeu16(buf, 6) - 1900; unpacked_date.tm_hour = (int)getub(buf, 8); unpacked_date.tm_min = (int)getub(buf, 9); unpacked_date.tm_sec = (int)getub(buf, 10); unpacked_date.tm_isdst = 0; #ifdef S_SPLINT_S unpacked_date.tm_wday = unpacked_date.tm_yday = 0; #endif /* S_SPLINT_S */ nsec = (uint) getbeu32(buf, 11); /*@ -unrecog */ session->newdata.time = (timestamp_t)mkgmtime(&unpacked_date) + nsec * 1e-9; /*@ +unrecog */ mask |= TIME_SET; gpsd_log(&session->context->errout, LOG_DATA, "oncore NAVSOL - time: %04d-%02d-%02d %02d:%02d:%02d.%09d\n", unpacked_date.tm_year + 1900, unpacked_date.tm_mon + 1, unpacked_date.tm_mday, unpacked_date.tm_hour, unpacked_date.tm_min, unpacked_date.tm_sec, nsec); } /*@-type@*/ lat = getbes32(buf, 15) / 3600000.0f; lon = getbes32(buf, 19) / 3600000.0f; alt = getbes32(buf, 23) / 100.0f; speed = getbeu16(buf, 31) / 100.0f; track = getbeu16(buf, 33) / 10.0f; dop = getbeu16(buf, 35) / 10.0f; /*@+type@*/ gpsd_log(&session->context->errout, LOG_DATA, "oncore NAVSOL - %lf %lf %.2lfm-%.2lfm | %.2fm/s %.1fdeg dop=%.1f\n", lat, lon, alt, wgs84_separation(lat, lon), speed, track, (float)dop); session->newdata.latitude = lat; session->newdata.longitude = lon; session->gpsdata.separation = wgs84_separation(session->newdata.latitude, session->newdata.longitude); session->newdata.altitude = alt - session->gpsdata.separation; session->newdata.speed = speed; session->newdata.track = track; mask |= LATLON_SET | ALTITUDE_SET | SPEED_SET | TRACK_SET; gpsd_zero_satellites(&session->gpsdata); /* Merge the satellite information from the Bb message. */ Bbused = 0; nsv = 0; for (i = st = 0; i < 8; i++) { int sv, mode, sn, status; unsigned int off; off = 40 + 4 * i; sv = (int)getub(buf, off); mode = (int)getub(buf, off + 1); sn = (int)getub(buf, off + 2); status = (int)getub(buf, off + 3); gpsd_log(&session->context->errout, LOG_DATA, "%2d %2d %2d %3d %02x\n", i, sv, mode, sn, status); if (sn) { session->gpsdata.skyview[st].PRN = (short)sv; session->gpsdata.skyview[st].ss = (double)sn; for (j = 0; (int)j < session->driver.oncore.visible; j++) if (session->driver.oncore.PRN[j] == sv) { session->gpsdata.skyview[st].elevation = (short)session->driver.oncore.elevation[j]; session->gpsdata.skyview[st].azimuth = (short)session->driver.oncore.azimuth[j]; Bbused |= 1 << j; break; } /* bit 7 of the status word: sat used for position */ session->gpsdata.skyview[st].used = false; if (status & 0x80) { session->gpsdata.skyview[st].used = true; nsv++; } /* bit 2 of the status word: using for time solution */ if (status & 0x02) mask |= PPSTIME_IS; /* * The PPSTIME_IS mask bit exists distinctly from TIME_SET exactly * so an OnCore running in time-service mode (and other GPS clocks) * can signal that it's returning time even though no position fixes * have been available. */ st++; } } for (j = 0; (int)j < session->driver.oncore.visible; j++) /*@ -boolops @*/ if (!(Bbused & (1 << j))) { session->gpsdata.skyview[st].PRN = (short)session->driver.oncore.PRN[j]; session->gpsdata.skyview[st].elevation = (short)session->driver.oncore.elevation[j]; session->gpsdata.skyview[st].azimuth = (short)session->driver.oncore.azimuth[j]; st++; } /*@ +boolops @*/ session->gpsdata.skyview_time = session->newdata.time; session->gpsdata.satellites_used = (int)nsv; session->gpsdata.satellites_visible = (int)st; mask |= SATELLITE_SET | USED_IS; /* Some messages can only be polled. As they are not so * important, would be enough to poll e.g. one message per cycle. */ (void)oncore_control_send(session, (char *)pollAs, sizeof(pollAs)); (void)oncore_control_send(session, (char *)pollAt, sizeof(pollAt)); (void)oncore_control_send(session, (char *)pollAy, sizeof(pollAy)); (void)oncore_control_send(session, (char *)pollBo, sizeof(pollBo)); (void)oncore_control_send(session, (char *)pollEn, sizeof(pollEn)); gpsd_log(&session->context->errout, LOG_DATA, "NAVSOL: time=%.2f lat=%.2f lon=%.2f alt=%.2f speed=%.2f track=%.2f mode=%d status=%d visible=%d used=%d\n", session->newdata.time, session->newdata.latitude, session->newdata.longitude, session->newdata.altitude, session->newdata.speed, session->newdata.track, session->newdata.mode, session->gpsdata.status, session->gpsdata.satellites_used, session->gpsdata.satellites_visible); return mask; }