Hi
Tom.
I'm
currently without a device to do test, especially test your
version of the code. At least I had finally time to give a
look at the proposed changes. They are a little bit different
from mine but I'm not sure if they are enough different to
justify my bad results.
Just
in case, here are my changes. What do you think about them?
The main differences that I can see are that I've added a
dedicated message for the antenna with a dedicated flag and
the fact that I didn't edit the xml file. Apart from those
bigger differences the approach is not that different. I'm
quite sure that at the time of first writing I've done tests
with fake data and it was correctly sent to the client side.
Any
advice is much appreciated. Thanks in advance.
F.
diff --git a/gps.h b/gps.h
index 5929be2..1954e29 100644
--- a/gps.h
+++ b/gps.h
@@ -1892,6 +1892,12 @@ struct
timedelta_t {
};
#endif /* TIMEDELTA_DEFINED
*/
+struct hardware_t {
+ char antenna_status;
+ char antenna_power;
+ char antenna_flags;
+};
+
/*
* Someday we may support
Windows, under which socket_t is a separate type.
* In the meantime, having a
typedef for this semantic kind is no bad thing,
@@ -1955,7 +1961,8 @@ struct
gps_data_t {
#define ERROR_SET (1llu<<31)
#define TOFF_SET (1llu<<32) /*
not yet used */
#define PPS_SET (1llu<<33)
-#define SET_HIGH_BIT 34
+#define HARDWARE_SET (1llu<<34)
/* antenna and more */
+#define SET_HIGH_BIT 35
timestamp_t online; /*
NZ if GPS is on line, 0 if not.
*
* Note: gpsd clears this time when sentences
@@ -2003,6 +2010,8 @@ struct
gps_data_t {
struct
devconfig_t list[MAXUSERDEVS];
} devices;
+ struct hardware_t
hardware;
+
/* pack things never
reported together to reduce structure size */
#define UNION_SET (RTCM2_SET|RTCM3_SET|SUBFRAME_SET|AIS_SET|ATTITUDE_SET|GST_SET|VERSION_SET|LOGMESSAGE_SET|ERROR_SET|TOFF_SET|PPS_SET)
union {
diff --git a/gps_json.h
b/gps_json.h
index 15eb039..f14d50c 100644
--- a/gps_json.h
+++ b/gps_json.h
@@ -20,6 +20,7 @@ void
json_data_report(const gps_mask_t,
char
*json_stringify(/address@hidden@*/char *, size_t, /address@hidden@*/const
char *);
void json_tpv_dump(const
struct gps_device_t *,
const struct policy_t *, /address@hidden@*/char *, size_t);
+void json_hardware_dump(const
struct hardware_t *hardware, /address@hidden@*/char *, size_t);
void json_noise_dump(const
struct gps_data_t *, /address@hidden@*/char *, size_t);
void json_sky_dump(const
struct gps_data_t *, /address@hidden@*/char *, size_t);
void json_att_dump(const
struct gps_data_t *, /address@hidden@*/char *, size_t);
diff --git a/gpsd.c b/gpsd.c
index aafb126..90b93a0 100644
--- a/gpsd.c
+++ b/gpsd.c
@@ -1442,6 +1442,13 @@ static
void pseudonmea_report(struct subscriber_t *sub,
(void)throttled_write(sub, buf, strlen(buf));
}
#endif /* AIVDM_ENABLE */
+ if ((changed &
HARDWARE_SET) != 0) {
+
nmea_hardware_dump(device, buf, sizeof(buf));
+
gpsd_log(&context.errout, LOG_IO,
+ "<=
HARDWARE (binary hardware) %s: %s\n",
+
device->gpsdata.dev.path, buf);
+
(void)throttled_write(sub, buf, strlen(buf));
+ }
}
}
#endif /*
SOCKET_EXPORT_ENABLE */
diff --git a/gpsd_json.c
b/gpsd_json.c
index c7ceb4d..e850d1c 100644
--- a/gpsd_json.c
+++ b/gpsd_json.c
@@ -214,6 +214,14 @@ void
json_tpv_dump(const struct gps_device_t *session,
(void)strlcat(reply,
"}\r\n", replylen);
}
+void json_hardware_dump(const
struct hardware_t *hardware,
+ char
*reply, size_t replylen)
+{
+ (void)snprintf(reply,
replylen,
+
"{\"class\":\"HARDWARE\",\"antenna_status\":\"%c\",\"antenna_power\":\"%c\",\"antenna_flags\":\"%c\"}\r\n",
+
hardware->antenna_status, hardware->antenna_power,
hardware->antenna_flags);
+}
+
void json_noise_dump(const
struct gps_data_t *gpsdata,
/address@hidden@*/ char *reply, size_t replylen)
{
@@ -3439,6 +3447,10 @@ void
json_data_report(const gps_mask_t changed,
buf+strlen(buf),
buflen-strlen(buf));
}
#endif /* AIVDM_ENABLE */
+
+ if ((changed &
HARDWARE_SET) != 0) {
+
json_hardware_dump(&datap->hardware,
buf+strlen(buf), buflen-strlen(buf));
+ }
}
#undef JSON_BOOL
diff --git a/libgps_core.c
b/libgps_core.c
index 9a26124..6666e2e 100644
--- a/libgps_core.c
+++ b/libgps_core.c
@@ -376,6 +376,9 @@ void
libgps_dump_state(struct gps_data_t *collect)
}
}
+ if (collect->set &
HARDWARE_SET)
+
(void)fprintf(debugfp, "HARDWARE: antenna status is '%d',
antenna power status is '%d', antenna flags status is
'%d'\n",
+
collect->hardware.antenna_status,
collect->hardware.antenna_power,
collect->hardware.antenna_flags);
}
#endif /* LIBGPS_DEBUG */
diff --git a/libgps_json.c
b/libgps_json.c
index ba967ca..e509561 100644
--- a/libgps_json.c
+++ b/libgps_json.c
@@ -24,6 +24,27 @@ PERMISSIONS
#ifdef SOCKET_EXPORT_ENABLE
#include "gps_json.h"
+static int
json_hardware_read(const char *buf, struct gps_data_t
*gpsdata,
+
/address@hidden@*/ const char **endptr)
+{
+ /*@ -fullinitblock @*/
+ const struct json_attr_t
json_attrs_hardware[] = {
+ /* *INDENT-OFF* */
+ {"class", t_check,
.dflt.check = "HARDWARE"},
+ {"antenna_status",
t_character, .addr.character =
&gpsdata->hardware.antenna_status,
+
.dflt.character = '*'},
+ {"antenna_power",
t_character, .addr.character =
&gpsdata->hardware.antenna_power,
+
.dflt.character = '*'},
+ {"antenna_flags",
t_character, .addr.character =
&gpsdata->hardware.antenna_flags,
+
.dflt.character = '*'},
+ {NULL},
+ /* *INDENT-ON* */
+ };
+ /*@ +fullinitblock @*/
+
+ return
json_read_object(buf, json_attrs_hardware, endptr);
+}
+
/*
* There's a splint
limitation that parameters can be declared
* @out@ or @null@ but not,
apparently, both. This collides with
@@ -550,6 +571,12 @@ int
libgps_json_unpack(const char *buf,
}
return
status;
#endif /* AIVDM_ENABLE */
+ } else if
(str_starts_with(classtag, "\"class\":\"HARDWARE\"")) {
+ status =
json_hardware_read(buf, gpsdata, end);
+ if (status == 0) {
+ gpsdata->set
|= HARDWARE_SET;
+ }
+ return status;
} else if
(str_starts_with(classtag, "\"class\":\"ERROR\"")) {
status
= json_error_read(buf, gpsdata, end);
if
(status == 0) {
diff --git a/pseudonmea.c
b/pseudonmea.c
index 96c80b7..5f59e5b 100644
--- a/pseudonmea.c
+++ b/pseudonmea.c
@@ -377,6 +377,17 @@ static
void gpsd_binary_ais_dump(struct gps_device_t *session,
}
#endif /* AIVDM_ENABLE */
+static void
gpsd_binary_hardware_dump(struct gps_device_t *session,
+
char bufp[], size_t len)
+{
+ (void)snprintf(bufp, len,
+
"$PGTOP,%d,%d,%d",
+
session->gpsdata.hardware.antenna_status,
+
session->gpsdata.hardware.antenna_power,
+
session->gpsdata.hardware.antenna_flags);
+ nmea_add_checksum(bufp);
+}
+
/address@hidden address@hidden/
/* *INDENT-OFF* */
void nmea_tpv_dump(struct
gps_device_t *session,
@@ -428,6 +439,15 @@ void
nmea_ais_dump(struct gps_device_t *session,
}
#endif /* AIVDM_ENABLE */
+void
nmea_hardware_dump(struct gps_device_t *session,
+ /address@hidden@*/
char bufp[], size_t len)
+{
+ bufp[0] = '\0';
+ if
((session->gpsdata.set & HARDWARE_SET) != 0)
+
gpsd_binary_hardware_dump(session, bufp + strlen(bufp),
+
len - strlen(bufp));
+}
+
/address@hidden address@hidden/
/* pseudonmea.c ends here */