Esempio n. 1
0
int
main(int argc, char **argv)
{
  long long	a, b, c;

  if (argc!=3 && argc!=4)
    {
      fprintf(stderr, "Usage: %s a [step] b\n", argv[0]);
      return 1;
    }
  a	= getll(argv[1]);
  b	= getll(argv[2]);
  if (argc==3)
    {
      c	= b;
      b = 1;
    }
  else
    c	= getll(argv[3]);
  if (!b)
    {
      fprintf(stderr, "Step cannot be 0\n");
      return 3;
    }
  if (b<0)
    for (; a>=c; a+=b)
      out(a);
  else
    for (; a<=c; a+=b)
      out(a);
  return 0;
}
Esempio n. 2
0
// expects single null terminated strings (line ends dont matter)
int getgpsinfo(char *buf)
{
    char *c, *d;
    int i, fmax;
    c = buf;
    d = NULL;
    // required for pathologic cases of $GPABC...$GPXYZ...*ck
    // where $GPABC... resolves to zero
    for (;;) {                  // find last $ - start of NMEA
        c = strchr(c, '$');
        if (!c)
            break;
        d = c;
        c++;
    }
    if (!d)
        return 0;
    // ignore all but standard NMEA
    if (*d != '$')
        return 0;
    if (d[1] != 'G')
        return 0;
    if (d[2] != 'P' && d[2] != 'N' && d[2] != 'L')
        return 0;
    c = d;
    c++;
    //verify checksum
    i = 0;
    while (*c && *c != '*')
        i ^= *c++;
    if (!*c || (unsigned) (i & 0xff) != strtoul(++c, NULL, 16)) {
        printf("Bad NMEA Checksum, calc'd %02x:\n %s", i, d);
        return -1;
    }
    --c;
    //null out asterisk
    *c = 0;
    c = d;
    //Split into fields at the commas
    fmax = 0;
    c += 2;
    char satype = *c++;         // P,L,N
    for (;;) {
        field[fmax++] = c;
        c = strchr(c, ',');
        if (c == NULL)
            break;
        *c++ = 0;
    }
    //Latitude, Longitude, and other info
    if (fmax == 13 && !strcmp(field[0], "RMC")) {
        //NEED TO VERIFY FMAX FOR EACH
        if (field[2][0] != 'A') {
            if (gpst.lock)
                gpst.lock = 0;
            return 1;
        }
        else {
            if (!gpst.lock)
                gpst.lock = 1;
            gethms(1);
            getll(3);
            gpst.gspd = getndp(field[7], 3) * 1151 / 1000;
            //convert to MPH
            gpst.gtrk = getndp(field[8], 3);
            //Date, DDMMYY
            gpst.dy = get2(field[9]);
            gpst.mo = get2(&field[9][2]);
            gpst.yr = get2(&field[9][4]);
            // this will be slightly late
            if (!firstlock)
                writelock();
        }
    }
    else if (fmax == 15 && (!strcmp(field[0], "GGA") || !strcmp(field[0], "GNS"))) {
        i = field[6][0] - '0';
        // was gpst.lock, but it would prevent GPRMC alt
        if (!i)
            return 1;
        else if (gpst.lock != i)
            gpst.lock = i;
        // Redundant: getll(2);
        // don't get this here since it won't increment the YMD
        // and create a midnight bug
        //       gethms(1);
        //7 - 2 plc Sats Used
        // 8 - HDOP
        gpst.hdop = getndp(field[8], 3);
        gpst.alt = getndp(field[9], 3);
        //9, 10 - Alt, units M
    }
    else if (fmax == 8 && !strcmp(field[0], "GLL")) {
        if (field[6][0] != 'A') {
            if (strlen(field[5]))
                gethms(5);
            if (gpst.lock)
                gpst.lock = 0;
            return 1;
        }
        if (!gpst.lock)
            gpst.lock = 1;
        getll(1);
        gethms(5);
    }
    else if (fmax == 10 && !strcmp(field[0], "VTG")) {
        gpst.gtrk = getndp(field[1], 3);
        gpst.gspd = getndp(field[5], 3) * 1151 / 1000;
        //convert to MPH
    }
    //Satellites and status
    else if (!(fmax & 3) && fmax >= 8 && fmax <= 20 && !strcmp(field[0], "GSV")) {
        int j, tot, seq;
        //should check (fmax % 4 == 3)
        tot = getndp(field[1], 0);
        seq = getndp(field[2], 0);
        if (satype == 'P') {
            if (seq == 1)
                for (j = 0; j < 65; j++)
                    gpsat.view[j] = 0;
            gpsat.pnsats = getndp(field[3], 0);
            gpsat.psatset &= (1 << tot) - 1;
            gpsat.psatset &= ~(1 << (seq - 1));
        }
        else {
            if (seq == 1)
                for (j = 65; j < 100; j++)
                    gpsat.view[j] = 0;
            gpsat.lnsats = getndp(field[3], 0);
            gpsat.lsatset &= (1 << tot) - 1;
            gpsat.lsatset &= ~(1 << (seq - 1));
        }
        for (j = 4; j < 20 && j < fmax; j += 4) {
            i = getndp(field[j], 0);
            if (!i)
                break;
            if (i > 119)        // WAAS,EGNOS high numbering
                i -= 87;
            gpsat.view[i] = 1;
            gpsat.el[i] = getndp(field[j + 1], 0);
            gpsat.az[i] = getndp(field[j + 2], 0);
            gpsat.sn[i] = getndp(field[j + 3], 0);
        }
        int n;
        if (satype == 'P' && !gpsat.psatset) {
            gpst.pnsats = 0;
            gpst.pnused = 0;
            for (n = 0; n < 65; n++) {
                if (gpsat.view[n]) {
                    int k = gpst.pnsats++;
                    gpst.psats[k].num = n;
                    gpst.psats[k].el = gpsat.el[n];
                    gpst.psats[k].az = gpsat.az[n];
                    gpst.psats[k].sn = gpsat.sn[n];
                    if (gpsat.used[n]) {
                        gpst.pnused++;
                        gpst.psats[k].num = -n;
                    }
                    else
                        gpst.psats[k].num = n;
                }
            }
        }
        // else
        if (satype == 'L' && !gpsat.lsatset) {
            gpst.lnsats = 0;
            gpst.lnused = 0;
            for (n = 65; n < 99; n++) {
                if (gpsat.view[n]) {
                    int k = gpst.lnsats++;
                    gpst.lsats[k].num = n;
                    gpst.lsats[k].el = gpsat.el[n];
                    gpst.lsats[k].az = gpsat.az[n];
                    gpst.lsats[k].sn = gpsat.sn[n];
                    if (gpsat.used[n]) {
                        gpst.lnused++;
                        gpst.lsats[k].num = -n;
                    }
                    else
                        gpst.lsats[k].num = n;
                }
            }
        }
    }
    else if (fmax == 18 && !strcmp(field[0], "GSA")) {
        gpst.fix = getndp(field[2], 0);
        gpst.pdop = getndp(field[15], 3);
        gpst.hdop = getndp(field[16], 3);
        gpst.vdop = getndp(field[17], 3);
        int j = getndp(field[3], 0);
        if (j > 119)
            j -= 87;
        if (j && j < 65) {
            gpsat.psatset = 255;
            for (i = 0; i < 65; i++)
                gpsat.used[i] = 0;
            gpsat.pnused = 0;
            for (i = 3; i < 15; i++) {
                int k = getndp(field[i], 0);
                if (k > 119)
                    k -= 87;
                if (k) {
                    gpsat.used[k]++;
                    gpsat.pnused++;
                }
                // else break;?
            }
        }
        if (j && j > 64) {
            gpsat.lsatset = 255;
            for (i = 65; i < 100; i++)
                gpsat.used[i] = 0;
            gpsat.lnused = 0;
            for (i = 3; i < 15; i++) {
                int k = getndp(field[i], 0);
                if (k > 119)
                    k -= 87;
                if (k) {
                    gpsat.used[k]++;
                    gpsat.lnused++;
                }
                // else break;?
            }
        }
    }
    else
        printf("?%s\n", field[0]);
    return -1;
}
Esempio n. 3
0
// expects single null terminated strings (line ends dont matter)
int getgpsinfo(int chan, char *buf, int msclock)
{
    char *c, *d;
    int i, fmax;

    c = buf;

    d = NULL;
    // required for pathologic cases of $GPABC...$GPXYZ...*ck 
    // where $GPABC... resolves to zero
    for (;;) {                  // find last $ - start of NMEA
        c = strchr(c, '$');
        if (!c)
            break;
        d = c;
        c++;
    }
    if (!d)
        return 0;

    // ignore all but standard NMEA
    if (*d != '$')
        return 0;
    if (d[1] != 'G')
        return 0;
    if (d[2] != 'P' && d[2] != 'N' && d[2] != 'L')
        return 0;

    c = d;
    c++;

    //verify checksum
    i = 0;
    while (*c && *c != '*')
        i ^= *c++;
    if (!*c || (unsigned) (i & 0xff) != strtoul(++c, NULL, 16)) {
        fprintf(errfd, "Bad NMEA Checksum, calc'd %02x:\n %s", i, d);
        return -1;
    }
    --c;
    //null out asterisk
    *c = 0;

    c = d;

    //find and update timestamp
    for (cidx = 0; cidx < MAXSRC; cidx++)
        if (gpst[cidx].gpsfd == chan || gpst[cidx].gpsfd == -2) // found or EOL
            break;
    if (cidx == MAXSRC)         // full, find empty or stale
        for (cidx = 0; cidx < MAXSRC; cidx++)
            if (gpst[cidx].gpsfd < 0 || (100000 + msclock - gpst[cidx].lastseen) % 100000 > 1250)
                break;
    gpst[cidx].gpsfd = chan;
    gpst[cidx].lastseen = msclock;

    //Split into fields at the commas
    fmax = 0;
    c += 2;
    char satype = *c++;         // P,L,N
    for (;;) {
        field[fmax++] = c;
        c = strchr(c, ',');
        if (c == NULL)
            break;
        *c++ = 0;
    }

    //Latitude, Longitude, and other info
    if (fmax == 13 && !strcmp(field[0], "RMC")) {
        //NEED TO VERIFY FMAX FOR EACH
        if (field[2][0] != 'A') {
            if (gpst[cidx].lock)
                gpst[cidx].lock = 0;
            return 1;
        } else {
            if (!gpst[cidx].lock)
                gpst[cidx].lock = 1;
            gethms(1);
            getll(3);
            gpst[cidx].gspd = getndp(field[7], 3) * 1151 / 1000;
            //convert to MPH
            gpst[cidx].gtrk = getndp(field[8], 3);
            //Date, DDMMYY
            gpst[cidx].dy = get2(field[9]);
            gpst[cidx].mo = get2(&field[9][2]);
            gpst[cidx].yr = get2(&field[9][4]);

            // this will be slightly late
            if (!firstlock)
                writelock();
        }
    } else if (fmax == 15 && (!strcmp(field[0], "GGA") || !strcmp(field[0], "GNS"))) {
        i = field[6][0] - '0';
        // was gpst[cidx].lock, but it would prevent GPRMC alt
        if (!i)
            return 1;
        else if (gpst[cidx].lock != i)
            gpst[cidx].lock = i;
        // Redundant: getll(2);
        // don't get this here since it won't increment the YMD
        // and create a midnight bug
        //       gethms(1);
        //7 - 2 plc Sats Used
        // 8 - HDOP
        gpst[cidx].hdop = getndp(field[8], 3);
        gpst[cidx].alt = getndp(field[9], 3);
        //9, 10 - Alt, units M
    }
#if 0                           // depend on RMC to avoid midnight bugs
    else if (fmax == 8 && !strcmp(field[0], "GLL")) {
        if (field[6][0] != 'A') {
#if 0                           // this will cause problems for the kml rotate if the time is wrong
            if (strlen(field[5]))
                gethms(5);
#endif
            if (gpst[cidx].lock)
                gpst[cidx].lock = 0;
            return 1;
        }
        if (!gpst[cidx].lock)
            gpst[cidx].lock = 1;
        getll(1);
        gethms(5);
    }
#endif
#if 0
    else if (fmax == 10 && !strcmp(field[0], "VTG")) {
        gpst[cidx].gtrk = getndp(field[1], 3);
        gpst[cidx].gspd = getndp(field[5], 3) * 1151 / 1000;
        //convert to MPH
    }
#endif
    //Satellites and status
    else if (!(fmax & 3) && fmax >= 8 && fmax <= 20 && !strcmp(field[0], "GSV")) {
        int j, tot, seq;
        //should check (fmax % 4 == 3)
        tot = getndp(field[1], 0);
        seq = getndp(field[2], 0);
        if (satype == 'P') {
            if (seq == 1)
                for (j = 0; j < 65; j++)
                    gpsat[cidx].view[j] = 0;
            gpsat[cidx].pnsats = getndp(field[3], 0);
            gpsat[cidx].psatset &= (1 << tot) - 1;
            gpsat[cidx].psatset &= ~(1 << (seq - 1));
        } else {
            if (seq == 1)
                for (j = 65; j < 100; j++)
                    gpsat[cidx].view[j] = 0;
            gpsat[cidx].lnsats = getndp(field[3], 0);
            gpsat[cidx].lsatset &= (1 << tot) - 1;
            gpsat[cidx].lsatset &= ~(1 << (seq - 1));
        }

        for (j = 4; j < 20 && j < fmax; j += 4) {
            i = getndp(field[j], 0);
            if (!i)
                break;
            if (i > 119)        // WAAS,EGNOS high numbering
                i -= 87;
            if (i > 100)
                i -= 46; //QZSS will be 60..64
            gpsat[cidx].view[i] = 1;
            gpsat[cidx].el[i] = getndp(field[j + 1], 0);
            gpsat[cidx].az[i] = getndp(field[j + 2], 0);
            gpsat[cidx].sn[i] = getndp(field[j + 3], 0);
        }
        int n;
        if (satype == 'P' && !gpsat[cidx].psatset) {
            gpst[cidx].pnsats = 0;
            gpst[cidx].pnused = 0;
            for (n = 0; n < 65; n++) {
                if (gpsat[cidx].view[n]) {
                    int k = gpst[cidx].pnsats++;
                    gpst[cidx].psats[k].num = n;
                    gpst[cidx].psats[k].el = gpsat[cidx].el[n];
                    gpst[cidx].psats[k].az = gpsat[cidx].az[n];
                    gpst[cidx].psats[k].sn = gpsat[cidx].sn[n];
                    if (gpsat[cidx].used[n]) {
                        gpst[cidx].pnused++;
                        gpst[cidx].psats[k].num = -n;
                    } else
                        gpst[cidx].psats[k].num = n;
                }
            }
        }
        // else
        if (satype == 'L' && !gpsat[cidx].lsatset) {
            gpst[cidx].lnsats = 0;
            gpst[cidx].lnused = 0;
            for (n = 65; n < 99; n++) {
                if (gpsat[cidx].view[n]) {
                    int k = gpst[cidx].lnsats++;
                    gpst[cidx].lsats[k].num = n;
                    gpst[cidx].lsats[k].el = gpsat[cidx].el[n];
                    gpst[cidx].lsats[k].az = gpsat[cidx].az[n];
                    gpst[cidx].lsats[k].sn = gpsat[cidx].sn[n];
                    if (gpsat[cidx].used[n]) {
                        gpst[cidx].lnused++;
                        gpst[cidx].lsats[k].num = -n;
                    } else
                        gpst[cidx].lsats[k].num = n;
                }
            }
        }
    } else if (fmax == 18 && !strcmp(field[0], "GSA")) {
        gpst[cidx].fix = getndp(field[2], 0);
        gpst[cidx].pdop = getndp(field[15], 3);
        gpst[cidx].hdop = getndp(field[16], 3);
        gpst[cidx].vdop = getndp(field[17], 3);

        int j = getndp(field[3], 0);
        if (j > 119)
            j -= 87;
        if (j && j < 65) {
            gpsat[cidx].psatset = 255;
            for (i = 0; i < 65; i++)
                gpsat[cidx].used[i] = 0;
            gpsat[cidx].pnused = 0;
            for (i = 3; i < 15; i++) {
                int k = getndp(field[i], 0);
                if (k > 119)
                    k -= 87;
                if (k) {
                    gpsat[cidx].used[k]++;
                    gpsat[cidx].pnused++;
                }
                // else break;?
            }
        }
        if (j && j > 64) {
            gpsat[cidx].lsatset = 255;
            for (i = 65; i < 100; i++)
                gpsat[cidx].used[i] = 0;
            gpsat[cidx].lnused = 0;
            for (i = 3; i < 15; i++) {
                int k = getndp(field[i], 0);
                if (k > 119)
                    k -= 87;
                if (k) {
                    gpsat[cidx].used[k]++;
                    gpsat[cidx].lnused++;
                }
                // else break;?
            }
        }
    }
#if 0
    else
        printf("?%s\n", field[0]);
#endif
    if (bestgps != cidx)
        return 1;

    if (!gpst[cidx].mo || !gpst[cidx].dy)
        return 1;
    // within 24 hours, only when gpst[cidx].lock since two unlocked GPS can have different times
    // only when sc < 30 to avoid bestgps jitter (5:00->4:59) causing a hiccup
    if (firstlock == 1 || (kmlinterval && gpst[cidx].lock && gpst[cidx].sc < 30
        && kmmn != (gpst[cidx].hr * 60 + gpst[cidx].mn) / kmlinterval)) {
        firstlock = 2;
        kmmn = (gpst[cidx].hr * 60 + gpst[cidx].mn) / kmlinterval;
        rotatekml();

        sprintf(currkml, "%02d%02d%02d%02d%02d%02d.kml",
          gpst[cidx].yr, gpst[cidx].mo, gpst[cidx].dy, gpst[cidx].hr, gpst[cidx].mn, gpst[cidx].sc);
        logfd = fopen(currkml, "w+b");
        if (logfd) {
            symlink(currkml, "current.kml");    // this will fail on FAT
            fprintf(logfd, kmlhead, kmlname, gpst[cidx].llon / 1000000, abs(gpst[cidx].llon % 1000000),
              gpst[cidx].llat / 1000000, abs(gpst[cidx].llat % 1000000), gpst[cidx].gtrk / 1000, gpst[cidx].gtrk % 1000);
            fflush(logfd);
        }
    }
    if (kmlsc == gpst[cidx].sc && kmscth == gpst[cidx].scth)
        return 1;
    if (!gpst[cidx].llat && !gpst[cidx].llon)   // time, but no location
        return 1;

    if (kmlsc != gpst[cidx].sc) {
        if (!kmlinterval || !logfd)
            return 1;
        kmlsc = gpst[cidx].sc;
        sprintf(&kmlstr[kmlful], pmarkfmt, gpst[cidx].llon / 1000000, abs(gpst[cidx].llon % 1000000), gpst[cidx].llat / 1000000, abs(gpst[cidx].llat % 1000000), gpst[cidx].gspd / 1000, gpst[cidx].gspd % 1000,        // last point this second, first point next below.
          gpst[cidx].yr, gpst[cidx].mo, gpst[cidx].dy, gpst[cidx].hr, gpst[cidx].mn, gpst[cidx].sc);
        kmlful = strlen(kmlstr);
    }

    kmscth = gpst[cidx].scth;
    sprintf(&kmlstr[kmlful], "%d.%06d,%d.%06d,%d.%03d\n", gpst[cidx].llon / 1000000, abs(gpst[cidx].llon % 1000000),
      gpst[cidx].llat / 1000000, abs(gpst[cidx].llat % 1000000), gpst[cidx].gspd / 1000, gpst[cidx].gspd % 1000);
    kmlful = strlen(kmlstr);

    if (kmlful > BUFLEN / 2)
        dokmltail();
    return 2;
}