Пример #1
0
bool
PortWriteNMEA(Port &port, const char *line, OperationEnvironment &env)
{
  assert(line != nullptr);

  /* reasonable hard-coded timeout; do we need to make this a
     parameter? */
  const unsigned timeout_ms = 1000;

  if (!port.Write('$') ||
      !port.FullWrite(line, strlen(line), env, timeout_ms))
    return false;

  char checksum[16];
  sprintf(checksum, "*%02X\r\n", NMEAChecksum(line));
  return port.FullWrite(checksum, strlen(checksum), env, timeout_ms);
}
Пример #2
0
int
main(int argc, char **argv)
{
  char buffer[1024];

  const char *start = buffer;
  while ((start = fgets(buffer, sizeof(buffer) - 3, stdin)) != NULL) {
    const char *end = strchr(start, '*');
    if (end == NULL) {
      end = start + strlen(start);
      while (end > start && (end[-1] == '\n' || end[-1] == '\r'))
        --end;
    }

    printf("%.*s*%02x\n", (int)(end - buffer), buffer,
           NMEAChecksum(start, end - start));
  }

  return 0;
}
Пример #3
0
  char *GetLine() {
    const auto src = buffer.Read();
    char *const end = src.data + src.length;

    /* a NMEA line starts with a dollar symbol ... */
    char *dollar = std::find(src.data, end, '$');
    if (dollar == end) {
      buffer.Clear();
      return nullptr;
    }

    char *start = dollar + 1;

    /* ... and ends with an asterisk */
    char *asterisk = std::find(start, end, '*');
    if (asterisk + 3 > end)
      /* need more data */
      return nullptr;

    /* verify the checksum following the asterisk (two hex digits) */

    const uint8_t calculated_checksum = NMEAChecksum(start, asterisk - start);

    const char checksum_buffer[3] = { asterisk[1], asterisk[2], 0 };
    char *endptr;
    const uint8_t parsed_checksum = strtoul(checksum_buffer, &endptr, 16);
    if (endptr != checksum_buffer + 2 ||
        parsed_checksum != calculated_checksum) {
      buffer.Clear();
      return nullptr;
    }

    buffer.Consume(asterisk + 3 - src.data);

    *asterisk = 0;
    return start;
  }
Пример #4
0
bool
NMEAParser::ParseLine(const char *string, NMEAInfo &info)
{
    assert(positive(info.clock));

    if (string[0] != '$')
        return false;

    if (!NMEAChecksum(string))
        return false;

    NMEAInputLine line(string);

    char type[16];
    line.Read(type, 16);

    if (IsAlphaASCII(type[1]) && IsAlphaASCII(type[2])) {
        if (StringIsEqual(type + 3, "GSA"))
            return GSA(line, info);

        if (StringIsEqual(type + 3, "GLL"))
            return GLL(line, info);

        if (StringIsEqual(type + 3, "RMC"))
            return RMC(line, info);

        if (StringIsEqual(type + 3, "GGA"))
            return GGA(line, info);

        if (StringIsEqual(type + 3, "HDM"))
            return HDM(line, info);
    }

    // if (proprietary sentence) ...
    if (type[1] == 'P') {
        // Airspeed and vario sentence
        if (StringIsEqual(type + 1, "PTAS1"))
            return PTAS1(line, info);

        // FLARM sentences
        if (StringIsEqual(type + 1, "PFLAE")) {
            ParsePFLAE(line, info.flarm.error, info.clock);
            return true;
        }

        if (StringIsEqual(type + 1, "PFLAV")) {
            ParsePFLAV(line, info.flarm.version, info.clock);
            return true;
        }

        if (StringIsEqual(type + 1, "PFLAA")) {
            ParsePFLAA(line, info.flarm.traffic, info.clock);
            return true;
        }

        if (StringIsEqual(type + 1, "PFLAU")) {
            ParsePFLAU(line, info.flarm.status, info.clock);
            return true;
        }

        // Garmin altitude sentence
        if (StringIsEqual(type + 1, "PGRMZ"))
            return RMZ(line, info);

        return false;
    }

    return false;
}