示例#1
0
文件: net_ntrip.c 项目: mcb30/gpsd
static int ntrip_sourcetable_parse(struct gps_device_t *device)
{
    struct ntrip_stream_t hold;
    ssize_t llen, len = 0;
    char *line;
    bool sourcetable = false;
    bool match = false;
    char buf[BUFSIZ];
    size_t blen = sizeof(buf);
    int fd = device->gpsdata.gps_fd;

    for (;;) {
	char *eol;
	ssize_t rlen;

	memset(&buf[len], 0, (size_t) (blen - len));
	rlen = read(fd, &buf[len], (size_t) (blen - 1 - len));
	if (rlen == -1) {
	    if (errno == EINTR) {
		continue;
	    }
	    if (sourcetable && !match && errno == EAGAIN) { // we have not yet found a match, but there currently is no more data
		return 0;
	    }
	    if (match) {
		return 1;
	    }
	    gpsd_log(&device->context->errout, LOG_ERROR,
		     "ntrip stream read error %d on fd %d\n",
		     errno, fd);
	    return -1;
	} else if (rlen == 0) { // server closed the connection
	    gpsd_log(&device->context->errout, LOG_ERROR,
		     "ntrip stream unexpected close %d on fd %d during sourcetable read\n",
		     errno, fd);
	    return -1;
	}

	line = buf;
	rlen = len += rlen;

	gpsd_log(&device->context->errout, LOG_RAW,
		 "Ntrip source table buffer %s\n", buf);

	sourcetable = device->ntrip.sourcetable_parse;
	if (!sourcetable) {
	    /* parse SOURCETABLE */
	    if (str_starts_with(line, NTRIP_SOURCETABLE)) {
		sourcetable = true;
		device->ntrip.sourcetable_parse = true;
		llen = (ssize_t) strlen(NTRIP_SOURCETABLE);
		line += llen;
		len -= llen;
	    } else {
		gpsd_log(&device->context->errout, LOG_WARN,
			 "Received unexpexted Ntrip reply %s.\n",
			 buf);
		return -1;
	    }
	}

	while (len > 0) {
	    /* parse ENDSOURCETABLE */
	    if (str_starts_with(line, NTRIP_ENDSOURCETABLE))
		goto done;

	    /* coverity[string_null] - nul-terminated by previous memset */
	    if (!(eol = strstr(line, NTRIP_BR)))
		break;

	    gpsd_log(&device->context->errout, LOG_DATA,
		     "next Ntrip source table line %s\n", line);

	    *eol = '\0';
	    llen = (ssize_t) (eol - line);

	    /* todo: parse headers */

	    /* parse STR */
	    if (str_starts_with(line, NTRIP_STR)) {
		ntrip_str_parse(line + strlen(NTRIP_STR),
				(size_t) (llen - strlen(NTRIP_STR)),
				&hold, &device->context->errout);
		if (strcmp(device->ntrip.stream.mountpoint, hold.mountpoint) == 0) {
		    /* todo: support for RTCM 3.0, SBAS (WAAS, EGNOS), ... */
		    if (hold.format == fmt_unknown) {
			gpsd_log(&device->context->errout, LOG_ERROR,
				 "Ntrip stream %s format not supported\n",
				 line);
			return -1;
		    }
		    /* todo: support encryption and compression algorithms */
		    if (hold.compr_encryp != cmp_enc_none) {
			gpsd_log(&device->context->errout, LOG_ERROR,
				 "Ntrip stream %s compression/encryption algorithm not supported\n",
				 line);
			return -1;
		    }
		    /* todo: support digest authentication */
		    if (hold.authentication != auth_none
			    && hold.authentication != auth_basic) {
			gpsd_log(&device->context->errout, LOG_ERROR,
				 "Ntrip stream %s authentication method not supported\n",
				line);
			return -1;
		    }
		    /* no memcpy, so we can keep the other infos */
		    device->ntrip.stream.format = hold.format;
		    device->ntrip.stream.carrier = hold.carrier;
		    device->ntrip.stream.latitude = hold.latitude;
		    device->ntrip.stream.longitude = hold.longitude;
		    device->ntrip.stream.nmea = hold.nmea;
		    device->ntrip.stream.compr_encryp = hold.compr_encryp;
		    device->ntrip.stream.authentication = hold.authentication;
		    device->ntrip.stream.fee = hold.fee;
		    device->ntrip.stream.bitrate = hold.bitrate;
		    device->ntrip.stream.set = true;
		    match = true;
		}
		/* todo: compare stream location to own location to
		 * find nearest stream if user hasn't provided one */
	    }
	    /* todo: parse CAS */
	    /* else if (str_starts_with(line, NTRIP_CAS)); */

	    /* todo: parse NET */
	    /* else if (str_starts_with(line, NTRIP_NET)); */

	    llen += strlen(NTRIP_BR);
	    line += llen;
	    len -= llen;
	    gpsd_log(&device->context->errout, LOG_RAW,
		     "Remaining Ntrip source table buffer %zd %s\n", len,
		     line);
	}
	/* message too big to fit into buffer */
	if ((size_t)len == blen - 1)
	    return -1;

	if (len > 0)
	    memmove(buf, &buf[rlen - len], (size_t) len);
    }

done:
    return match ? 1 : -1;
}
示例#2
0
static int ntrip_sourcetable_parse(int fd, char *buf, ssize_t blen,
				   const char *stream,
				   struct ntrip_stream_t *keep)
{
    struct ntrip_stream_t hold;
    ssize_t llen, len = 0;
    char *line;
    bool srctbl = false;
    bool match = false;

    for (;;) {
	char *eol;
	ssize_t rlen;

	memset(&buf[len], 0, (size_t) (blen - len));

	if ((rlen = recv(fd, &buf[len], (size_t) (blen - 1 - len), 0)) == -1) {
	    if (errno == EINTR)
		continue;
	    return -1;
	}
	if (rlen == 0)
	    continue;

	line = buf;
	rlen = len += rlen;

	gpsd_report(LOG_RAW, "Ntrip source table buffer %s\n", buf);

	if (!srctbl) {
	    /* parse SOURCETABLE */
	    if (strncmp(line, NTRIP_SOURCETABLE, strlen(NTRIP_SOURCETABLE)) ==
		0) {
		srctbl = true;
		llen = (ssize_t) strlen(NTRIP_SOURCETABLE);
		line += llen;
		len -= llen;
	    } else {
		gpsd_report(LOG_WARN, "Received unexpexted Ntrip reply %s.\n",
			    buf);
		return -1;
	    }
	}
	if (!srctbl)
	    return -1;

	while (len > 0) {
	    /* parse ENDSOURCETABLE */
	    if (strncmp
		(line, NTRIP_ENDSOURCETABLE,
		 strlen(NTRIP_ENDSOURCETABLE)) == 0)
		goto done;

	    if (!(eol = strstr(line, NTRIP_BR)))
		break;

	    gpsd_report(LOG_IO, "next Ntrip source table line %s\n", line);

	    *eol = '\0';
	    llen = (ssize_t) (eol - line);

	    /* todo: parse headers */

	    /* parse STR */
	    if (strncmp(line, NTRIP_STR, strlen(NTRIP_STR)) == 0) {
		ntrip_str_parse(line + strlen(NTRIP_STR),
				(size_t) (llen - strlen(NTRIP_STR)), &hold);
		if (stream != NULL && strcmp(stream, hold.mountpoint) == 0) {
		    /* todo: support for RTCM 3.0, SBAS (WAAS, EGNOS), ... */
		    if (hold.format == fmt_unknown) {
			gpsd_report(LOG_ERROR,
				    "Ntrip stream %s format not supported\n",
				    line);
			return -1;
		    }
		    /* todo: support encryption and compression algorithms */
		    if (hold.compr_encryp != cmp_enc_none) {
			gpsd_report(LOG_ERROR,
				    "Ntrip stream %s compression/encryption algorithm not supported\n",
				    line);
			return -1;
		    }
		    /* todo: support digest authentication */
		    if (hold.authentication != auth_none
			&& hold.authentication != auth_basic) {
			gpsd_report(LOG_ERROR,
				    "Ntrip stream %s authentication method not supported\n",
				    line);
			return -1;
		    }
		    memcpy(keep, &hold, sizeof(hold));
		    match = true;
		}
		/* todo: compare stream location to own location to
		 * find nearest stream if user hasn't provided one */
	    }
	    /* todo: parse CAS */
	    /* else if (strncmp(line, NTRIP_CAS, strlen(NTRIP_CAS))==0); */

	    /* todo: parse NET */
	    /* else if (strncmp(line, NTRIP_NET, strlen(NTRIP_NET))==0); */

	    llen += strlen(NTRIP_BR);
	    line += llen;
	    len -= llen;
	    gpsd_report(LOG_RAW,
			"Remaining Ntrip source table buffer %zd %s\n", len,
			line);
	}
	/* message too big to fit into buffer */
	if (len == blen - 1)
	    return -1;

	if (len > 0)
	    memcpy(buf, &buf[rlen - len], (size_t) len);
    }

  done:
    return match ? 0 : -1;
}