示例#1
0
文件: net_ntrip.c 项目: mcb30/gpsd
int ntrip_open(struct gps_device_t *device, char *caster)
    /* open a connection to a Ntrip broadcaster */
{
    char *amp, *colon, *slash;
    char *auth = NULL;
    char *port = NULL;
    char *stream = NULL;
    char *url = NULL;
    int ret = -1;
    char t[strlen(caster) + 1];
    char *tmp = t;

    switch (device->ntrip.conn_state) {
	case ntrip_conn_init:
	    /* this has to be done here, because it is needed for multi-stage connection */
	    device->servicetype = service_ntrip;
	    device->ntrip.works = false;
	    device->ntrip.sourcetable_parse = false;
	    device->ntrip.stream.set = false;
	    (void)strlcpy(tmp, caster, sizeof(t));

	    if ((amp = strchr(tmp, '@')) != NULL) {
		if (((colon = strchr(tmp, ':')) != NULL) && colon < amp) {
		    auth = tmp;
		    *amp = '\0';
		    tmp = amp + 1;
		    url = tmp;
		} else {
		    gpsd_log(&device->context->errout, LOG_ERROR,
			     "can't extract user-ID and password from %s\n",
			     caster);
		    device->ntrip.conn_state = ntrip_conn_err;
		    return -1;
		}
	    }
	    if ((slash = strchr(tmp, '/')) != NULL) {
		*slash = '\0';
		stream = slash + 1;
	    } else {
		/* todo: add autoconnect like in dgpsip.c */
		gpsd_log(&device->context->errout, LOG_ERROR,
			 "can't extract Ntrip stream from %s\n",
			 caster);
		device->ntrip.conn_state = ntrip_conn_err;
		return -1;
	    }
	    if ((colon = strchr(tmp, ':')) != NULL) {
		port = colon + 1;
		*colon = '\0';
	    }
	    if (!port) {
		port = "rtcm-sc104";
		if (!getservbyname(port, "tcp"))
		    port = DEFAULT_RTCM_PORT;
	    }

	    (void)strlcpy(device->ntrip.stream.mountpoint,
		    stream,
		    sizeof(device->ntrip.stream.mountpoint));
	    if (auth != NULL)
		(void)strlcpy(device->ntrip.stream.credentials,
			      auth,
			      sizeof(device->ntrip.stream.credentials));
	    /*
	     * Semantically url and port ought to be non-NULL by now,
	     * but just in case...this code appeases Coverity.
	     */
	    if (url != NULL)
		(void)strlcpy(device->ntrip.stream.url,
			      url,
			      sizeof(device->ntrip.stream.url));
	    if (port != NULL)
		(void)strlcpy(device->ntrip.stream.port,
			      port,
			      sizeof(device->ntrip.stream.port));

	    ret = ntrip_stream_req_probe(&device->ntrip.stream,
					 &device->context->errout);
	    if (ret == -1) {
		device->ntrip.conn_state = ntrip_conn_err;
		return -1;
	    }
	    device->gpsdata.gps_fd = ret;
	    device->ntrip.conn_state = ntrip_conn_sent_probe;
	    return ret;
	case ntrip_conn_sent_probe:
	    ret = ntrip_sourcetable_parse(device);
	    if (ret == -1) {
		device->ntrip.conn_state = ntrip_conn_err;
		return -1;
	    }
	    if (ret == 0 && device->ntrip.stream.set == false) {
		return ret;
	    }
	    (void)close(device->gpsdata.gps_fd);
	    if (ntrip_auth_encode(&device->ntrip.stream, device->ntrip.stream.credentials, device->ntrip.stream.authStr, sizeof(device->ntrip.stream.authStr)) != 0) {
		device->ntrip.conn_state = ntrip_conn_err;
		return -1;
	    }
	    ret = ntrip_stream_get_req(&device->ntrip.stream,
				       &device->context->errout);
	    if (ret == -1) {
		device->ntrip.conn_state = ntrip_conn_err;
		return -1;
	    }
	    device->gpsdata.gps_fd = ret;
	    device->ntrip.conn_state = ntrip_conn_sent_get;
	    break;
	case ntrip_conn_sent_get:
	    ret = ntrip_stream_get_parse(&device->ntrip.stream,
					 device->gpsdata.gps_fd,
					 &device->context->errout);
	    if (ret == -1) {
		device->ntrip.conn_state = ntrip_conn_err;
		return -1;
	    }
	    device->ntrip.conn_state = ntrip_conn_established;
	    device->ntrip.works = true; // we know, this worked.
	    break;
	case ntrip_conn_established:
	case ntrip_conn_err:
	    return -1;
    }
    return ret;
}
示例#2
0
/*@ -nullpass @*//* work around a splint bug */
static int ntrip_stream_open(const char *caster, const char *port,
			     /*@null@*/ const char *auth,
			     struct gps_context_t *context,
			     struct ntrip_stream_t *stream)
{
    char buf[BUFSIZ];
    char authstr[128];
    int opts;

    if (ntrip_auth_encode(stream, auth, authstr, sizeof(authstr)) < 0) {
	gpsd_report(LOG_ERROR, "User-ID and password needed for %s:%s/%s\n",
		    caster, port, stream->mountpoint);
	return -1;
    }
    if ((context->dsock =
	 netlib_connectsock(AF_UNSPEC, caster, port, "tcp")) < 0)
	return -1;

    (void)snprintf(buf, sizeof(buf),
		   "GET /%s HTTP/1.1\r\n"
		   "User-Agent: NTRIP gpsd/%s\r\n"
		   "Accept: rtk/rtcm, dgps/rtcm\r\n"
		   "%s"
		   "Connection: close\r\n"
		   "\r\n", stream->mountpoint, VERSION, authstr);
    if (write(context->dsock, buf, strlen(buf)) != (ssize_t) strlen(buf)) {
	printf("ntrip stream write error on %d\n", context->dsock);
	return -1;
    }

    memset(buf, 0, sizeof(buf));
    if (read(context->dsock, buf, sizeof(buf) - 1) == -1)
	goto close;

    /* parse 401 Unauthorized */
    if (strstr(buf, NTRIP_UNAUTH)) {
	gpsd_report(LOG_ERROR,
		    "%s not authorized for Ntrip stream %s:%s/%s\n", auth,
		    caster, port, stream->mountpoint);
	goto close;
    }
    /* parse SOURCETABLE */
    if (strstr(buf, NTRIP_SOURCETABLE)) {
	gpsd_report(LOG_ERROR,
		    "Broadcaster doesn't recognize Ntrip stream %s:%s/%s\n",
		    caster, port, stream->mountpoint);
	goto close;
    }
    /* parse ICY 200 OK */
    if (!strstr(buf, NTRIP_ICY)) {
	gpsd_report(LOG_ERROR,
		    "Unknown reply %s from Ntrip service %s:%s/%s\n", buf,
		    caster, port, stream->mountpoint);
	goto close;
    }
    opts = fcntl(context->dsock, F_GETFL);

    if (opts >= 0)
	(void)fcntl(context->dsock, F_SETFL, opts | O_NONBLOCK);

    context->netgnss_service = netgnss_ntrip;
#ifndef S_SPLINT_S
    context->netgnss_privdata = stream;
#endif
    return context->dsock;
  close:
    (void)close(context->dsock);
    return -1;
}