summaryrefslogtreecommitdiff
path: root/driver_skytraq.c
diff options
context:
space:
mode:
authorGary E. Miller <gem@rellim.com>2016-03-29 21:02:37 -0700
committerGary E. Miller <gem@rellim.com>2016-03-29 21:02:37 -0700
commit969da0a10042fdc323b65a05344204746b51c9eb (patch)
treea66837d39e8b25ebf8a94f01a74804be1a982887 /driver_skytraq.c
parent686eaea63c44399dee5e80b699747e3d323f66d4 (diff)
downloadgpsd-969da0a10042fdc323b65a05344204746b51c9eb.tar.gz
Skytraq binary now decodes type 0XDE, SV/Chan status
Diffstat (limited to 'driver_skytraq.c')
-rw-r--r--driver_skytraq.c74
1 files changed, 73 insertions, 1 deletions
diff --git a/driver_skytraq.c b/driver_skytraq.c
index ea8e926f..09c56e4c 100644
--- a/driver_skytraq.c
+++ b/driver_skytraq.c
@@ -26,10 +26,79 @@
* No ACK/NAK? Just rety after 6 seconds
*/
#define SKY_RETRY_TIME 6
-#define SKY_CHANNELS 28 /* max channels allowed in format */
+#define SKY_CHANNELS 48 /* max channels allowed in format */
static gps_mask_t sky_parse(struct gps_device_t *, unsigned char *, size_t);
+static gps_mask_t sky_msg_svinfo(struct gps_device_t *, unsigned char *,
+ size_t);
+
+/*
+ * decode MID 0xDE, SV and channel status
+ *
+ * max payload: 3 + (Num_sats * 10) = 483 bytes
+ */
+static gps_mask_t sky_msg_svinfo(struct gps_device_t *session,
+ unsigned char *buf, size_t len)
+{
+ int st, i, j, nsv;
+ unsigned int iod; /* Issue of data 0 - 255 */
+ int nsvs; /* number of SVs in this packet */
+
+ iod = (unsigned int)buf[5];
+ nsvs = (int)buf[6];
+ /* too many sats? */
+ if ( SKY_CHANNELS < nsvs )
+ return 0;
+
+ gpsd_zero_satellites(&session->gpsdata);
+ for (i = st = nsv = 0; i < nsvs; i++) {
+ int off = 5 + 10 * i; /* offset into buffer of start of this sat */
+ bool good; /* do we have a good record ? */
+ unsigned short sv_stat;
+ unsigned short chan_stat;
+ unsigned short ura;
+
+ session->gpsdata.skyview[st].PRN = (short)getub(buf, off + 1);
+ sv_stat = (unsigned short)getub(buf, off + 2);
+ ura = (unsigned short)getub(buf, off + 3);
+ session->gpsdata.skyview[st].ss = (float)getub(buf, off + 4);
+ session->gpsdata.skyview[st].elevation =
+ (short)getles16(buf, off + 5);
+ session->gpsdata.skyview[st].azimuth =
+ (short)getles16(buf, off + 7);
+ chan_stat = (unsigned short)getub(buf, off + 9);
+
+ session->gpsdata.skyview[st].used = (bool)(chan_stat & 0x30);
+ good = session->gpsdata.skyview[st].PRN != 0 &&
+ session->gpsdata.skyview[st].azimuth != 0 &&
+ session->gpsdata.skyview[st].elevation != 0;
+// #ifndef UNUSED
+ gpsd_log(&session->context->errout, 1, /* PROG, */
+ "SiRF: PRN=%2d El=%d Az=%d ss=%3.2f stat=%02x,%02x ura=%d %c\n",
+ session->gpsdata.skyview[st].PRN,
+ session->gpsdata.skyview[st].elevation,
+ session->gpsdata.skyview[st].azimuth,
+ session->gpsdata.skyview[st].ss,
+ chan_stat, sv_stat, ura,
+ good ? '*' : ' ');
+// #endif /* UNUSED */
+ if ( 0 != good ) {
+ st += 1;
+ if (session->gpsdata.skyview[st].used)
+ nsv++;
+ }
+ }
+
+ session->gpsdata.satellites_visible = st;
+ session->gpsdata.satellites_used = nsv;
+
+ gpsd_log(&session->context->errout, LOG_DATA,
+ "Skytraq: MID 0xDE: visible=%d mask={SATELLITE} iod=%d\n",
+ session->gpsdata.satellites_visible, iod);
+ return SATELLITE_SET;
+}
+
static gps_mask_t sky_parse(struct gps_device_t * session, unsigned char *buf,
size_t len)
@@ -46,6 +115,9 @@ static gps_mask_t sky_parse(struct gps_device_t * session, unsigned char *buf,
session->cycle_end_reliable = true;
switch (buf[0]) {
+ case 0xDE:
+ return sky_msg_svinfo(session, buf, len);
+
default:
gpsd_log(&session->context->errout, LOG_PROG,
"Skytraq: Unknown packet id %d length %zd\n",