gpsd-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [gpsd-users] Antenna status U-BLOX


From: Federico Buti
Subject: Re: [gpsd-users] Antenna status U-BLOX
Date: Tue, 12 Dec 2017 14:45:45 +0100

​​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.

     case UBX_MON_HW:
- gpsd_log(&session->context->errout, LOG_DATA, "UBX_MON_HW\n");
- break;
+        mask |= ubx_msg_hw(session, &buf[UBX_PREFIX_LEN], data_len);
+        gpsd_log(&session->context->errout, LOG_DATA, "UBX_MON_HW\n");
+        break;
+static gps_mask_t ubx_msg_hw(struct gps_device_t *session, unsigned char *buf, size_t data_len)
+{
+    gps_mask_t mask = 0;
+
+    if ( 60 > data_len ) {
+        /* incomplete message */
+        return mask;
+    }
+
+    char aStatus = (char)getub(buf, 20);
+    char aPower = (char)getub(buf, 21);
+    char flags = (char)getsb(buf, 22);
+
+    session->gpsdata.hardware.antenna_status = aStatus;
+    session->gpsdata.hardware.antenna_power = aPower;
+    session->gpsdata.hardware.antenna_flags = flags;
+    mask |= HARDWARE_SET;
+
+    return mask;
+}

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



On 17 November 2017 at 08:17, Federico Buti <address@hidden> wrote:
Hi Tom.

Thanks for the reply. I just skimmed the mailing list when I wrote the mail and didn't find your original message. Sorry for the duplicate then.
I've looked at the patch and probably/possibly there are difference with my approach. Currently I'm finalizing some other stuff for a deadline. As soon as the deadline is over and I can get back to the gpsd stuff I'm going to try out that patch and see if that can help in solving my issue.

Thanks a lot!
F.


---
Federico Buti

On 17 November 2017 at 04:12, tom <address@hidden> wrote:
where are you parsing the UBX_MON_HW message ? I remember trying a different way of doing it and it turned out that if there is no antenna the gps data is not valid and it doesn't go into the sending loop.. you might have run into the same problem ? I remember finding it using the debugger, then i went back and asked for some advice and they told me to do it in the way below: (if you search in the email list you will find my communication about this topic)

I've included a patch that i did to get it working here. please note that this assumes your client uses libgpsd to receive the antenna status and that something else sends the BX-UBX-CFG-ANT and MON-HW. (but it sounds like you already do that)

perhaps you could use it.

From c486e9f1ec90bc33b4a63733b76e94aced35228c Mon Sep 17 00:00:00 2001
From: tom schuring <address@hidden>
Date: Tue, 19 Sep 2017 17:10:05 +1000
Subject: [PATCH] handle the antenna status in the UBX HW-MON msg

---
 driver_ubx.c  | 33 +++++++++++++++++++++++++++++++++
 gps.h         |  7 +++++++
 gpsd_json.c   |  2 ++
 gpsd_json.xml |  5 +++++
 libgps_json.c |  2 ++
 5 files changed, 49 insertions(+)

diff --git a/driver_ubx.c b/driver_ubx.c
index 88be6c0..421aa04 100644
--- a/driver_ubx.c
+++ b/driver_ubx.c
@@ -73,6 +73,8 @@ static gps_mask_t ubx_msg_nav_timegps(struct gps_device_t
*session,
       unsigned char *buf, size_t data_len);
 static void ubx_msg_mon_ver(struct gps_device_t *session,
       unsigned char *buf, size_t data_len);
+static void ubx_msg_mon_hw(struct gps_device_t *session,
+ unsigned char *buf);
 #ifdef RECONFIGURE_ENABLE
 static void ubx_mode(struct gps_device_t *session, int mode);
 #endif /* RECONFIGURE_ENABLE */
@@ -393,6 +395,36 @@ static void ubx_msg_sbas(struct gps_device_t *session,
unsigned char *buf)
 }

 /*
+ * Hardare Monitor status
+ */
+static void ubx_msg_mon_hw(struct gps_device_t *session, unsigned char
*buf)
+{
+ session->gpsdata.ant_status = (int)getub(buf, 20);
+
+ switch( session->gpsdata.ant_status )
+ {
+ case ANT_STATUS_INIT:
+ gpsd_log(&session->context->errout, LOG_PROG, "ANT_STATUS: INIT\n");
+ break;
+ case ANT_STATUS_DONT_KNOW:
+ gpsd_log(&session->context->errout, LOG_PROG, "ANT_STATUS: DONT_KNOW\n");
+ break;
+ case ANT_STATUS_OK:
+ gpsd_log(&session->context->errout, LOG_PROG, "ANT_STATUS: OK\n");
+ break;
+ case ANT_STATUS_SHORT:
+ gpsd_log(&session->context->errout, LOG_PROG, "ANT_STATUS: SHORT\n");
+ break;
+ case ANT_STATUS_OPEN:
+ gpsd_log(&session->context->errout, LOG_PROG, "ANT_STATUS: OPEN\n");
+ break;
+ default:
+ gpsd_log(&session->context->errout, LOG_PROG, "ANT_STATUS: : %d\n",
session->gpsdata.ant_status );
+ break;
+ }
+}
+
+/*
  * Raw Subframes
  */
 static gps_mask_t ubx_msg_sfrb(struct gps_device_t *session, unsigned char
*buf)
@@ -578,6 +610,7 @@ gps_mask_t ubx_parse(struct gps_device_t * session,
unsigned char *buf,
  break;
     case UBX_MON_HW:
  gpsd_log(&session->context->errout, LOG_DATA, "UBX_MON_HW\n");
+ ubx_msg_mon_hw(session, &buf[6]);
  break;
     case UBX_MON_USB:
  gpsd_log(&session->context->errout, LOG_DATA, "UBX_MON_USB\n");
diff --git a/gps.h b/gps.h
index 77c1bcb..c6fc4e9 100644
--- a/gps.h
+++ b/gps.h
@@ -2024,9 +2024,16 @@ struct gps_data_t {
 #define STATUS_FIX 1 /* yes, without DGPS */
 #define STATUS_DGPS_FIX 2 /* yes, with DGPS */

+/* Antenna status */
+#define ANT_STATUS_INIT 0
+#define ANT_STATUS_DONT_KNOW 1
+#define ANT_STATUS_OK 2
+#define ANT_STATUS_SHORT 3
+#define ANT_STATUS_OPEN  4
     /* precision of fix -- valid if satellites_used > 0 */
     int satellites_used; /* Number of satellites used in solution */
     struct dop_t dop;
+    int ant_status; /* antenna status */

     /* redundant with the estimate elements in the fix structure */
     double epe;  /* spherical position error, 95% confidence (meters)  */
diff --git a/gpsd_json.c b/gpsd_json.c
index 825851e..84f443e 100644
--- a/gpsd_json.c
+++ b/gpsd_json.c
@@ -287,6 +287,8 @@ void json_sky_dump(const struct gps_data_t *datap,
  str_appendf(reply, replylen, "\"gdop\":%.2f,", datap->dop.gdop);
     if (isnan(datap->dop.pdop) == 0)
  str_appendf(reply, replylen, "\"pdop\":%.2f,", datap->dop.pdop);
+    if (isnan(datap->ant_status) == 0 && datap->ant_status !=
ANT_STATUS_INIT)
+ str_appendf(reply, replylen, "\"ant\":%d,", datap->ant_status);
     /* insurance against flaky drivers */
     for (i = 0; i < datap->satellites_visible; i++)
  if (datap->skyview[i].PRN)
diff --git a/gpsd_json.xml b/gpsd_json.xml
index 88c8a66..a89b7f7 100644
--- a/gpsd_json.xml
+++ b/gpsd_json.xml
@@ -337,6 +337,11 @@ yet, only the "class" field will reliably be
present.</para>
  error estimate.</entry>
 </row>
 <row>
+        <entry>ant</entry>
+ <entry>No</entry>
+ <entry>numeric</entry>
+ <entry>Antenna status. If supported by the driver and the device</entry>
+<row>
  <entry>satellites</entry>
  <entry>Yes</entry>
  <entry>list</entry>
diff --git a/libgps_json.c b/libgps_json.c
index 6a71185..b0c6273 100644
--- a/libgps_json.c
+++ b/libgps_json.c
@@ -142,6 +142,8 @@ static int json_sky_read(const char *buf, struct
gps_data_t *gpsdata,
                              .dflt.real = NAN},
  {"gdop",       t_real,    .addr.real    = &gpsdata->dop.gdop,
                              .dflt.real = NAN},
+ {"ant",       t_integer, .addr.integer = &gpsdata->ant_status,
+         .dflt.integer = ANT_STATUS_INIT},
  {"satellites", t_array,
                            STRUCTARRAY(gpsdata->skyview,
  json_attrs_satellites,



On Fri, 17 Nov 2017 at 1:14 pm, Federico Buti <address@hidden> wrote:
Hi Tom.

Thanks for the reply.
I should have specified that statement, sorry. I was meaning the antenna. If I unscrew the antenna, the PVT messages stop whereas the antenna messages keep coming. Unfortunately those antenna message are always "OK".
I've also read of a specific command to be sent to activate the three pin antenna supervisor (0x06 0x41) but even after sending it, there has been no improvement at all.

Beste regards,
F.






reply via email to

[Prev in Thread] Current Thread [Next in Thread]