summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gpsd.h-tail3
-rw-r--r--libgpsd_core.c23
-rw-r--r--netlib.c21
-rw-r--r--serial.c3
4 files changed, 44 insertions, 6 deletions
diff --git a/gpsd.h-tail b/gpsd.h-tail
index a7501306..34ea7a0a 100644
--- a/gpsd.h-tail
+++ b/gpsd.h-tail
@@ -272,7 +272,8 @@ typedef enum {source_unknown,
source_rs232,
source_usb,
source_pty,
- source_socket}
+ source_tcp,
+ source_udp}
sourcetype_t;
struct gps_device_t {
diff --git a/libgpsd_core.c b/libgpsd_core.c
index 11c4c79e..95a4370c 100644
--- a/libgpsd_core.c
+++ b/libgpsd_core.c
@@ -317,7 +317,7 @@ int gpsd_activate(struct gps_device_t *session)
if (netgnss_uri_check(session->gpsdata.dev.path)) {
session->gpsdata.gps_fd = netgnss_uri_open(session->context,
session->gpsdata.dev.path);
- session->sourcetype = source_socket;
+ session->sourcetype = source_tcp;
gpsd_report(LOG_SPIN,
"netgnss_uri_open(%s) returns socket on fd %d\n",
session->gpsdata.dev.path, session->gpsdata.gps_fd);
@@ -341,6 +341,27 @@ int gpsd_activate(struct gps_device_t *session)
return -1;
}
session->gpsdata.gps_fd = dsock;
+ session->sourcetype = source_tcp;
+ } else if (strncmp(session->gpsdata.dev.path, "udp://", 6) == 0) {
+ char server[GPS_PATH_MAX], *port;
+ socket_t dsock;
+ (void)strlcpy(server, session->gpsdata.dev.path + 6, sizeof(server));
+ session->gpsdata.gps_fd = -1;
+ port = strchr(server, ':');
+ if (port == NULL) {
+ gpsd_report(LOG_ERROR, "Missing colon in UDP feed spec.\n");
+ return -1;
+ }
+ *port++ = '\0';
+ gpsd_report(LOG_INF, "opening UDP feed at %s, port %s.\n", server,
+ port);
+ if ((dsock = netlib_connectsock(AF_UNSPEC, server, port, "udp")) < 0) {
+ gpsd_report(LOG_ERROR, "UDP device open error %s.\n",
+ netlib_errstr(dsock));
+ return -1;
+ }
+ session->gpsdata.gps_fd = dsock;
+ session->sourcetype = source_udp;
}
/* otherwise, ordinary serial device */
else
diff --git a/netlib.c b/netlib.c
index f9a854be..a385ba95 100644
--- a/netlib.c
+++ b/netlib.c
@@ -51,6 +51,7 @@ socket_t netlib_connectsock(int af, const char *host, const char *service,
struct addrinfo *result, *rp;
int ret, type, proto, one = 1;
socket_t s = -1;
+ bool bind_me;
/*@-type@*/
ppe = getprotobyname(protocol);
@@ -63,9 +64,14 @@ socket_t netlib_connectsock(int af, const char *host, const char *service,
}
/*@+type@*/
+ /* we probably ought to pass this in as an explicit flag argument */
+ bind_me = (type == SOCK_DGRAM);
+
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = af;
hints.ai_socktype = type;
+ if (bind_me)
+ hints.ai_flags = AI_PASSIVE;
hints.ai_protocol = proto;
#ifndef S_SPLINT_S
if ((ret = getaddrinfo(host, service, &hints, &result))) {
@@ -92,9 +98,18 @@ socket_t netlib_connectsock(int af, const char *host, const char *service,
(s, SOL_SOCKET, SO_REUSEADDR, (char *)&one,
sizeof(one)) == -1)
ret = NL_NOSOCKOPT;
- else if (connect(s, rp->ai_addr, rp->ai_addrlen) == 0) {
- ret = 0;
- break;
+ else {
+ if (bind_me) {
+ if (bind(s, rp->ai_addr, rp->ai_addrlen) == 0) {
+ ret = 0;
+ break;
+ }
+ } else {
+ if (connect(s, rp->ai_addr, rp->ai_addrlen) == 0) {
+ ret = 0;
+ break;
+ }
+ }
}
if (s > 0) {
diff --git a/serial.c b/serial.c
index 550ba408..499dd3cb 100644
--- a/serial.c
+++ b/serial.c
@@ -37,8 +37,9 @@ static sourcetype_t gpsd_classify(const char *path)
return source_unknown;
else if (S_ISREG(sb.st_mode))
return source_blockdev;
+ /* this assumes we won't get UDP from a filesystem socket */
else if (S_ISSOCK(sb.st_mode))
- return source_socket;
+ return source_tcp;
else if (S_ISCHR(sb.st_mode)) {
sourcetype_t devtype = source_unknown;
#ifdef __linux__