static void earthmate_event_hook(struct gps_device_t *session, event_t event) { if (session->context->readonly) return; if (event == event_identified) { (void)gpsd_write(session, "EARTHA\r\n", 8); (void)usleep(10000); (void)gpsd_switch_driver(session, "Zodiac Binary"); } }
/*@ +charint -usedef -compdef @*/ static bool evermore_write(struct gps_device_t *session, unsigned char *msg, size_t msglen) { unsigned int crc; size_t i, len; unsigned char stuffed[MAX_PACKET_LENGTH*2], *cp; /* prepare a DLE-stuffed copy of the message */ cp = stuffed; *cp++ = 0x10; /* message starts with DLE STX */ *cp++ = 0x02; len = (size_t)(msglen + 2); /* msglen < 254 !! */ *cp++ = (unsigned char)len; /* message length */ if (len == 0x10) *cp++ = 0x10; /* payload */ crc = 0; for (i = 0; i < msglen; i++) { *cp++ = msg[i]; if (msg[i] == 0x10) *cp++ = 0x10; crc += msg[i]; } crc &= 0xff; /* enter CRC after payload */ *cp++ = crc; if (crc == 0x10) *cp++ = 0x10; *cp++ = 0x10; /* message ends with DLE ETX */ *cp++ = 0x03; len = (size_t)(cp - stuffed); /* we may need to dump the message */ gpsd_report(LOG_IO, "writing EverMore control type 0x%02x: %s\n", msg[0], gpsd_hexdump(stuffed, len)); #ifdef ALLOW_RECONFIGURE return (gpsd_write(session, stuffed, len) == (ssize_t)len); #else return 0; #endif /* ALLOW_RECONFIGURE */ }
/*@ +charint -usedef -compdef @*/ static ssize_t evermore_control_send(struct gps_device_t *session, char *buf, size_t len) { unsigned int crc; size_t i; char *cp; /*@ +charint +ignoresigns @*/ /* prepare a DLE-stuffed copy of the message */ cp = session->msgbuf; *cp++ = 0x10; /* message starts with DLE STX */ *cp++ = 0x02; session->msgbuflen = (size_t) (len + 2); /* len < 254 !! */ *cp++ = (char)session->msgbuflen; /* message length */ if (session->msgbuflen == 0x10) *cp++ = 0x10; /* payload */ crc = 0; for (i = 0; i < len; i++) { *cp++ = buf[i]; if (buf[i] == 0x10) *cp++ = 0x10; crc += buf[i]; } crc &= 0xff; /* enter CRC after payload */ *cp++ = crc; if (crc == 0x10) *cp++ = 0x10; *cp++ = 0x10; /* message ends with DLE ETX */ *cp++ = 0x03; session->msgbuflen = (size_t) (cp - session->msgbuf); /*@ -charint -ignoresigns @*/ return gpsd_write(session, session->msgbuf, session->msgbuflen); }
static bool sky_write(struct gps_device_t *session, unsigned char *msg) { unsigned int crc; size_t i, len; bool ok; unsigned int type = (unsigned int)msg[4]; len = (size_t) ((msg[2] << 8) | msg[3]); /* calculate Checksum */ crc = 0; /* coverity_submit[tainted_data] */ for (i = 0; i < len; i++) crc ^= (int)msg[4 + i]; /* enter CRC after payload */ msg[len + 4] = (unsigned char)(crc & 0x00ff); gpsd_log(&session->context->errout, LOG_PROG, "Skytraq: Writing control type %02x:\n", type); ok = (gpsd_write(session, (const char *)msg, len+7) == (ssize_t) (len+7)); return (ok); }
static void italk_ping(struct gps_device_t *session) /* send a "ping". it may help us detect an itrax more quickly */ { char *ping = "<?>"; (void)gpsd_write(session, ping, 3); }
static void nmea_event_hook(struct gps_device_t *session, event_t event) { if (session->context->readonly) return; /* * This is where we try to tickle NMEA devices into revealing their * inner natures. */ if (event == event_configure) { /* * The reason for splitting these probes up by packet sequence * number, interleaving them with the first few packet receives, * is because many generic-NMEA devices get confused if you send * too much at them in one go. * * A fast response to an early probe will change drivers so the * later ones won't be sent at all. Thus, for best overall * performance, order these to probe for the most popular types * soonest. * * Note: don't make the trigger strings identical to the probe, * because some NMEA devices (notably SiRFs) will just echo * unknown strings right back at you. A useful dodge is to append * a comma to the trigger, because that won't be in the response * unless there is actual following data. */ switch (session->packet.counter) { #ifdef NMEA_ENABLE case 0: /* probe for Garmin serial GPS -- expect $PGRMC followed by data */ gpsd_report(LOG_PROG, "=> Probing for Garmin NMEA\n"); (void)nmea_send(session, "$PGRMCE"); break; #endif /* NMEA_ENABLE */ #ifdef SIRF_ENABLE case 1: /* * We used to try to probe for SiRF by issuing "$PSRF105,1" * and expecting "$Ack Input105.". But it turns out this * only works for SiRF-IIs; SiRF-I and SiRF-III don't respond. * Thus the only reliable probe is to try to flip the SiRF into * binary mode, cluing in the library to revert it on close. * * SiRFs dominate the GPS-mouse market, so we used to put this test * first. Unfortunately this causes problems for gpsctl, as it cannot * select the NMEA driver without switching the device back to * binary mode! Fix this if we ever find a nondisruptive probe string. */ gpsd_report(LOG_PROG, "=> Probing for SiRF\n"); (void)nmea_send(session, "$PSRF100,0,%d,%d,%d,0", session->gpsdata.dev.baudrate, 9 - session->gpsdata.dev.stopbits, session->gpsdata.dev.stopbits); session->back_to_nmea = true; break; #endif /* SIRF_ENABLE */ #ifdef NMEA_ENABLE case 2: /* probe for the FV-18 -- expect $PFEC,GPint followed by data */ gpsd_report(LOG_PROG, "=> Probing for FV-18\n"); (void)nmea_send(session, "$PFEC,GPint"); break; case 3: /* probe for the Trimble Copernicus */ gpsd_report(LOG_PROG, "=> Probing for Trimble Copernicus\n"); (void)nmea_send(session, "$PTNLSNM,0139,01"); break; #endif /* NMEA_ENABLE */ #ifdef EVERMORE_ENABLE case 4: gpsd_report(LOG_PROG, "=> Probing for Evermore\n"); /* Enable checksum and GGA(1s), GLL(0s), GSA(1s), GSV(1s), RMC(1s), VTG(0s), PEMT101(1s) */ /* EverMore will reply with: \x10\x02\x04\x38\x8E\xC6\x10\x03 */ (void)gpsd_write(session, "\x10\x02\x12\x8E\x7F\x01\x01\x00\x01\x01\x01\x00\x01\x00\x00\x00\x00\x00\x00\x13\x10\x03", 22); break; #endif /* EVERMORE_ENABLE */ #ifdef GPSCLOCK_ENABLE case 5: /* probe for Furuno Electric GH-79L4-N (GPSClock); expect $PFEC,GPssd */ gpsd_report(LOG_PROG, "=> Probing for GPSClock\n"); (void)nmea_send(session, "$PFEC,GPsrq"); break; #endif /* GPSCLOCK_ENABLE */ #ifdef ASHTECH_ENABLE case 6: /* probe for Ashtech -- expect $PASHR,RID */ gpsd_report(LOG_PROG, "=> Probing for Ashtech\n"); (void)nmea_send(session, "$PASHQ,RID"); break; #endif /* ASHTECH_ENABLE */ #ifdef UBX_ENABLE case 7: /* probe for UBX -- query software version */ gpsd_report(LOG_PROG, "=> Probing for UBX\n"); (void)ubx_write(session, 0x0au, 0x04, NULL, 0); break; #endif /* UBX_ENABLE */ #ifdef MTK3301_ENABLE case 8: /* probe for MTK-3301 -- expect $PMTK705 */ gpsd_report(LOG_PROG, "=> Probing for MediaTek\n"); (void)nmea_send(session, "$PMTK605"); break; #endif /* MTK3301_ENABLE */ default: break; } } }