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 */