summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2009-01-09 02:49:09 +0000
committerEric S. Raymond <esr@thyrsus.com>2009-01-09 02:49:09 +0000
commit7e855354b7794090e27a7056d465677e9aa688c9 (patch)
tree7fdb4d1cb736830873c1b6ee2efd61455f229e3a
parent67f9dd1352082c4dac3c68e59bcfb519efb97f5f (diff)
downloadgpsd-7e855354b7794090e27a7056d465677e9aa688c9.tar.gz
Experimental code for sending hexified binary over the control channel.
-rw-r--r--NEWS3
-rw-r--r--gpsd.c21
-rw-r--r--gpsd.h-tail2
-rwxr-xr-xgpsd.hotplug3
-rw-r--r--gpsd.xml4
-rw-r--r--hex.c3
6 files changed, 33 insertions, 3 deletions
diff --git a/NEWS b/NEWS
index 83e982c9..4e21c040 100644
--- a/NEWS
+++ b/NEWS
@@ -8,7 +8,8 @@
gpsd_hexdump to save CPU. Lots of little fixes to various packet
parsers. Always keep the device open: "-n" is not optional any
more. xgpsspeed no longer depends on Motif. gpsctl can now ship
- arbitrary payloads to a device.
+ arbitrary payloads to a device. It's possible to send binary through the
+ control channel with the new & command.
* Sun Feb 17 2008 Chris Kuethe <ckuethe@mail.berlios.de> - 2.37
The C++ bindings, Garmin USB support, and multiple instances of ntp
diff --git a/gpsd.c b/gpsd.c
index 94311a9a..4a739dbd 100644
--- a/gpsd.c
+++ b/gpsd.c
@@ -1266,6 +1266,27 @@ static void handle_control(int sfd, char *buf)
assert(write(sfd, "ERROR\n", 6) != -1);
}
}
+ } else if (buf[0] == '&') {
+ size_t len;
+ p = snarfline(buf+1, &stash);
+ eq = strchr(stash, '=');
+ if (eq == NULL) {
+ gpsd_report(LOG_WARN,"<= control(%d): ill-formed command \n", sfd);
+ assert(write(sfd, "ERROR\n", 6) != -1);
+ } else {
+ *eq++ = '\0';
+ len = strlen(eq)+5;
+ if ((chp = find_device(stash)) != NULL) {
+ gpsd_report(LOG_INF,"<= control(%d): writing fromhex(%s) to %s\n", sfd, eq, stash);
+ /* NOTE: this destroys the original buffer contents */
+ len = gpsd_hexpack(eq, eq, len);
+ assert(write(chp->gpsdata.gps_fd, eq, len) != 1);
+ assert(write(sfd, "OK\n", 3) != -1);
+ } else {
+ gpsd_report(LOG_INF,"<= control(%d): %s not active \n", sfd, stash);
+ assert(write(sfd, "ERROR\n", 6) != -1);
+ }
+ }
}
/*@ +sefparams @*/
}
diff --git a/gpsd.h-tail b/gpsd.h-tail
index 2653ea83..21183c3b 100644
--- a/gpsd.h-tail
+++ b/gpsd.h-tail
@@ -393,7 +393,7 @@ extern void gpsd_zero_satellites(/*@out@*/struct gps_data_t *sp)/*@modifies sp@*
extern void gpsd_interpret_subframe(struct gps_device_t *, unsigned int[]);
extern /*@ observer @*/ char *gpsd_hexdump(/*@null@*/const void *, size_t);
extern /*@ observer @*/ char *gpsd_hexdump_wrapper(/*@null@*/const void *, size_t, int);
-extern int gpsd_hexpack(char *, char *, int);
+extern int gpsd_hexpack(char *, char *, size_t);
extern int hex2bin(char *);
extern void ntpd_link_activate(struct gps_device_t *session);
extern char /*@observer@*/ *gpsd_id(/*@in@*/struct gps_device_t *);
diff --git a/gpsd.hotplug b/gpsd.hotplug
index eac47675..a70d66a4 100755
--- a/gpsd.hotplug
+++ b/gpsd.hotplug
@@ -52,6 +52,9 @@ def gpsd_control(action, argument):
elif action == 'remove':
connect.sendall("-%s\r\n" % argument)
connect.recv(12)
+ elif action == 'send':
+ connect.sendall("%s\r\n" % argument)
+ connect.recv(12)
connect.close()
#syslog.syslog("gpsd_control ends")
return action
diff --git a/gpsd.xml b/gpsd.xml
index c7b7a558..dbbd3b50 100644
--- a/gpsd.xml
+++ b/gpsd.xml
@@ -709,6 +709,10 @@ list. send "-/dev/foo\n".</para>
control socket a '!', followed by the device name, followed by '=',
followed by the control string.</para>
+<para>To send a binary control string to a specified device, write to the
+control socket a '&', followed by the device name, followed by '=',
+followed by the control string in paired hex digits.</para>
+
<para>Your client may await a response, which will be a line beginning
with either "OK" or "ERROR". An ERROR reponse to an add command means
the device did not emit data recognizable as GPS packets; an ERROR
diff --git a/hex.c b/hex.c
index 19e08cbf..d4d52980 100644
--- a/hex.c
+++ b/hex.c
@@ -52,7 +52,8 @@ char /*@ observer @*/ *gpsd_hexdump(const void *binbuf, size_t binbuflen)
return hexbuf;
}
-int gpsd_hexpack(char *src, char *dst, int len){
+int gpsd_hexpack(char *src, char *dst, size_t len){
+/* hex2bin source string to destination - destination can be same as source */
int i, k, l;
l = (int)(strlen(src) / 2);