/* This code is a modified version of Larry Romans's code BJfmt.c It should conform to vanilla ANSI C. It is compiled on HP-UX with cc -Aa -o BJfmtl BJfmtl.c -lm I intend to continue developing and maintaining it in the foreseeable future, and would very much appreciate hearing of any problems or suggestions. Byron Iijima Dr. Byron A. Iijima Ionospheric and Atmospheric Remote Sensing Group Jet Propulsion Laboratory M/S 138-308 Phone: +1 818 354 8503 4800 Oak Grove Drive Fax: +1 818 393 5115 Pasadena, CA 91109 USA Email: Byron.A.Iijima@jpl.nasa.gov */ /* The input data may or may not have the TRSR wrapper on each packet. ------------------------------------- The TRSR packet consists of: Open packet byte = 0x02 Header: Flags (byte) (0x20 means have CRC) TRSR header length (byte) (Excludes open packet: 0x04 is minimum header length) Data packet length (short) (Does not include header or CRC) Remainder of header if header length > 0x04. Data packet (Blackjack or Turbobinary data) Checksum (if performed) (2 bytes) ------------------------------------- A Blackjack packet consists of: 0xbb = blackjack packet 0xbd = data (or 0xbc = command) short = data length (excludes 0xbb 0xbd length) byte[data length]--the first 4 bytes are library, the second 4 bytes are type (e.g. OBSDqfit) ------------------------------------ A Turbobinary packet consists of: Single byte packet identifier Single byte packet length Data ------------------------------------ If anything after the open packet byte contains an 0x02 or 0x10, then it must be escaped. The escape character is 0x10. The escape sequences are 0x10 0x02 = interrupt packet and open(?)--BJfmt considers this an error, and inteprets 0x02 as open packet byte 0x10 0x4f means 0x02 0x10 0x45 means 0x10 Any other byte following 0x10 is an error Substitution occurs before the length or checksum of the packet is calculated. ------------------------------------ How the TRSR packet is written: The TRSR wrapper ensures that: 0x02 only occurs as open packet marker. 0x10 only occurs as an escape character. This is done as follows: Each packet opens with 0x02. This is followed by header bytes, data bytes, and CRC. If an 0x02 or 0x10 appears in the header, data, or CRC, then it replaced by 0x104f or 0x1045 respectively (?). */ #include #include #include #include #include #define NP 32 #define MAXHR 50 #define NBUF 66000 #define loop(I,N) for(I=0;I "); printf("%c", clast = c); } if (clast!='\n') printf("\n"); } /************************************************* SCAM.attd *************************************************/ void do_SCAM_attd(void) { int i; char conf, Nlocks, Nstars; byte scamflags; double x[4]; long qq[4]; if(!do_scam && !do_all) return; Bpik(ttag); Bpik(scamflags); Bpik(conf); Bpik(Nlocks); Bpik(Nstars); loop(i,4) Bpik(qq[i]), x[i] = ((double)qq[i])/pow(2.0, 31.0); printf(" %d 0x%x %d %d %d %.12f %.12f %.12f %.12f (%d %d %d %d)\n", (long)ttag - ttag_shift, scamflags, conf, Nlocks, Nstars, x[0], x[1], x[2], x[3], qq[0], qq[1], qq[2], qq[3]); } /************************************************* NAVG.ants *************************************************/ void do_NAVG_ants(void) { int i; double x[4], v[4]; float dx[4], dv[4]; if(!do_nav && !do_all) return; Bpik(ttag); Bskip(10); loop (i,4) Bpik(x[i]); loop (i,4) Bpik(dx[i]); loop (i,4) Bpik(v[i]); loop (i,4) Bpik(dv[i]); printf("%d NAVG %.6f %.6f %.6f %.3e %.8f %.8f %.8f %.3e\n", (long)ttag - ttag_shift, x[0]/1000.0, x[1]/1000.0, x[2]/1000.0, x[3], v[0]/1000.0, v[1]/1000.0, v[2]/1000.0, v[3]); ttag_navg=ttag; if(do_tchk) { if(ttag_navg_last == 0) fprintf(ft,"NAVG first t= %d : packet= %d to %d\n",ttag_navg,nbyte_in-pktlength+1,nbyte_in); else if(ttag_navg > ttag_navg_last + maxgap) fprintf(ft,"NAVG gap t= %d to %d : delta= %d : packet= %d to %d : prevpkt= %d to %d\n", ttag_navg_last,ttag_navg,ttag_navg-ttag_navg_last,nbyte_in-pktlength+1,nbyte_in, byte_navg_last-bytelen_navg_last+1,byte_navg_last); else if(ttag_navg < ttag_navg_last - maxback) fprintf(ft,"NAVG back t= %d to %d : delta= %d : packet= %d to %d : prevpkt= %d to %d\n", ttag_navg_last,ttag_navg,ttag_navg-ttag_navg_last,nbyte_in-pktlength+1,nbyte_in, byte_navg_last-bytelen_navg_last+1,byte_navg_last); } ttag_navg_last=ttag_navg; byte_navg_last=nbyte_in; bytelen_navg_last=pktlength; ttag_tchk=ttag; if(do_tchk) { if(ttag_tchk_last == 0) fprintf(ft,"TCHK first t= %d : packet= %d to %d\n",ttag_tchk,nbyte_in-pktlength+1,nbyte_in); else if(ttag_tchk > ttag_tchk_last + maxgap) fprintf(ft,"TCHK gap t= %d to %d : delta= %d : packet= %d to %d : prevpkt= %d to %d\n", ttag_tchk_last,ttag_tchk,ttag_tchk-ttag_tchk_last,nbyte_in-pktlength+1,nbyte_in, byte_tchk_last-bytelen_tchk_last+1,byte_tchk_last); else if(ttag_tchk < ttag_tchk_last - maxback) fprintf(ft,"TCHK back t= %d to %d : delta= %d : packet= %d to %d : prevpkt= %d to %d\n", ttag_tchk_last,ttag_tchk,ttag_tchk-ttag_tchk_last,nbyte_in-pktlength+1,nbyte_in, byte_tchk_last-bytelen_tchk_last+1,byte_tchk_last); } ttag_tchk_last=ttag_tchk; byte_tchk_last=nbyte_in; bytelen_tchk_last=pktlength; if(ttag_tchkttag_tchk_max) ttag_tchk_max=ttag_tchk; } /************************************************* OBSD.qfit *************************************************/ char Rrate; int do_OBSD_qfit(void) { int i, j, has_L1, has_L2; byte prn, ObsType, CA_chan, P1_chan, P2_chan, Utyp; char AntIn, SampInt, prnstr[8], Rtyp, Rscale; double CA_faz, CA_tau,dt; unsigned short CA_snr, P1_snr, P2_snr; float CA_dop, CA_ddop; float P1_faz, P2_faz, P1_tau, P2_tau; long ttag_print; Res_t *pR; if(!do_obs && !do_all) return(0); Bpik(ttag); if (!ttag_last) ttag_last = ttag; Bpik(prn); if (prn < 1 || prn >= NP) { printf(": BAD prn %d\n", prn); return(0); } if (ttag < ttag_last - 1e6 || ttag > ttag_last + 1e6) { fprintf(stderr, "\n%s: WARNING, funny ttag = %ld (previous ttag = %ld)\n", pname, (long)ttag - ttag_shift, (long)ttag_last - ttag_shift); } if(nav_prn && (prn!=nav_prn) ) return(0); Bpik(AntIn); Bpik(ObsType); Bpik(SampInt); for(i=0;iNUMANTENNA-1) { fprintf(stderr,"Too many antennas\n"); exit(1); } ttag_obsd_ant[i]=AntIn; n_obsd_ant++; } /* Occasionally timetag at start of week will be one week off */ if( do_weekbdry && (ttag%604800 == 0) && ttag_obsd_last[i] && (ttag < ttag_obsd_last[i]-601200) && (ttag > ttag_obsd_last[i]-608400) ) ttag+=604800; if( ExitTime && (ttag>ExitTime) ) exit(0); if( (StartTime && (ttag EndTime) ) ) return(0); ttag_obsd[i]=ttag; if(do_tchk) { if(ttag_obsd_last[i] == 0) fprintf(ft,"OBSD %02x first t= %d : packet= %d to %d\n",AntIn,ttag_obsd[i],nbyte_in-pktlength+1,nbyte_in); else if(ttag_obsd[i] > ttag_obsd_last[i] + maxgap) fprintf(ft,"OBSD %02x gap t= %d to %d : delta= %d : packet= %d to %d : prevpkt= %d to %d\n", AntIn,ttag_obsd_last[i],ttag_obsd[i],ttag_obsd[i]-ttag_obsd_last[i],nbyte_in-pktlength+1,nbyte_in, byte_obsd_last[i]-bytelen_obsd_last[i]+1,byte_obsd_last[i]); else if(ttag_obsd[i] < ttag_obsd_last[i] - maxback) fprintf(ft,"OBSD %02x back t= %d to %d : delta= %d : packet= %d to %d : prevpkt= %d to %d\n", AntIn,ttag_obsd_last[i],ttag_obsd[i],ttag_obsd[i]-ttag_obsd_last[i],nbyte_in-pktlength+1,nbyte_in, byte_obsd_last[i]-bytelen_obsd_last[i]+1,byte_obsd_last[i]); } ttag_obsd_last[i]=ttag_obsd[i]; byte_obsd_last[i]=nbyte_in; bytelen_obsd_last[i]=pktlength; ttag_tchk=ttag; if(do_tchk) { if(ttag_tchk_last == 0) fprintf(ft,"TCHK first t= %d : packet= %d to %d\n",ttag_tchk,nbyte_in-pktlength+1,nbyte_in); else if(ttag_tchk > ttag_tchk_last + maxgap) fprintf(ft,"TCHK gap t= %d to %d : delta= %d : packet= %d to %d : prevpkt= %d to %d\n", ttag_tchk_last,ttag_tchk,ttag_tchk-ttag_tchk_last,nbyte_in-pktlength+1,nbyte_in, byte_tchk_last-bytelen_tchk_last+1,byte_tchk_last); else if(ttag_tchk < ttag_tchk_last - maxback) fprintf(ft,"TCHK back t= %d to %d : delta= %d : packet= %d to %d : prevpkt= %d to %d\n", ttag_tchk_last,ttag_tchk,ttag_tchk-ttag_tchk_last,nbyte_in-pktlength+1,nbyte_in, byte_tchk_last-bytelen_tchk_last+1,byte_tchk_last); } ttag_tchk_last=ttag_tchk; byte_tchk_last=nbyte_in; bytelen_tchk_last=pktlength; if(ttag_tchkttag_tchk_max) ttag_tchk_max=ttag_tchk; /* Length of BJ OBSDqfit data packet 4 LibID 4 PktID 8 Time,prn,ant,obstype,samprate 19 CA (chn, snr, ph, pr) 11 P2 11 P1 8 CAdop,CAddop 3+2*rate Ph rsds 3+2*rate Amp rsds Typical low rate: 4+4+8+19+11+11 =57 Add 50 Hz CA phase: 57+8+103 =168 Add 50 Hz CA amp: 168+103 =271 */ Bpik(CA_chan); Bpik(CA_snr); Bpik(CA_faz); Bpik(CA_tau); has_L1 = has_L2 = 0; if (CA_chan < 128) { has_L2 = 1; Bpik(P2_chan); Bpik(P2_snr); Bpik(P2_faz); Bpik(P2_tau); if (P2_chan < 128) { has_L1 = 1; Bpik(P1_chan); Bpik(P1_snr); Bpik(P1_faz); Bpik(P1_tau); } else P2_chan %= 128; } else CA_chan %= 128; CA_tau *= (10*Pcodechip); P1_tau *= Pcodechip; P2_tau *= Pcodechip; sprintf(prnstr, "prn%02d", prn); ttag_last = ttag; ttag_print = ttag; printf("%d OBSD %s %02x %02x %02x %d CA: %02x %d %lf %lf P2: %02x %d %f %f P1: %02x %d %f %f \n", (long)ttag_print - ttag_shift, prnstr, (unsigned char) AntIn, (unsigned char) ObsType, (unsigned char) SampInt, bjdlength, CA_chan, CA_snr, CA_faz , CA_tau, P2_chan, P2_snr, (CA_faz - P2_faz)*120.0/154.0, CA_tau - P2_tau, P1_chan, P1_snr, CA_faz - P1_faz, CA_tau - P1_tau); if (Bleft) { Bpik(CA_dop); Bpik(CA_ddop); printf("RSD %s %f %f",prnstr,CA_dop,CA_ddop); loop(i,5) Res[i].flag_faz = Res[i].flag_amp = 0; while (Bleft) { Bpik(Rtyp); /* For phase: CA 0xfc, P1 0xf1, P2 0xf2. For amp: CA 0xac, P1 0xa1, P2 0xa2. */ Bpik(Rscale); Bpik(Rrate); Utyp = Rtyp & 0x000000ff; /* unneeded? */ printf(" %02x %d %d", Utyp, Rscale, Rrate); switch (Utyp) { case 0xfc: do_phase_res(Res, CA_faz); break; case 0xf1: do_phase_res(Res + 1, CA_faz - (double)P1_faz); break; case 0xf2: do_phase_res(Res + 2, CA_faz - (double)P2_faz); break; case 0xf3: do_phase_res(Res + 3, CA_faz); break; case 0xf4: do_phase_res(Res + 4, CA_faz - (double)P1_faz); break; case 0xac: do_amp_res(Res); break; case 0xa1: do_amp_res(Res + 1); break; case 0xa2: do_amp_res(Res + 2); break; case 0xa3: do_amp_res(Res + 3); break; case 0xa4: do_amp_res(Res + 4); break; default: fprintf(stderr, "\n%s: Unrecognized ResidualType 0x%02x\n", pname, Utyp); leave(1); } } printf("\n"); loop(i,Rrate) { dt = ((double)i)/((double)Rrate) - 0.5; loop(j,5) { pR = Res + j; if (pR->flag_faz || pR->flag_amp) { printf("%.2f prn%02d HR", (double)ttag - ttag_shift + dt, prn); if (pR->flag_faz) { if (j==2) printf (" %sfaz %f", pR->typ, (pR->faz + CA_dop*dt + CA_ddop*dt*dt/2.)*60./77. + pR->res[i]*Rscale/8192.0); else printf (" %sfaz %f", pR->typ, pR->faz + CA_dop*dt + CA_ddop*dt*dt/2.0 + pR->res[i]*Rscale/8192.0); } if (pR->flag_amp) printf(" %samp %d", pR->typ, pR->amp[i]); if (do_obs2) printf(" %d",(int)(pR->res[i])); printf("\n"); } } } } return(0); } void do_phase_res(Res_t *pR, double faz) { int i; pR->flag_faz = 1; pR->faz = faz; loop(i,Rrate) Bpik(pR->res[i]); } void do_amp_res(Res_t *pR) { int i; pR->flag_amp = 1; loop(i,Rrate) Bpik(pR->amp[i]); } /************************************************* unknown *************************************************/ int do_unknown_type(void) { return(0); } /************************************************* reading Buf *************************************************/ void pick(byte *A, int m) { int i; Bleft -= m; if (Bleft < 0) { fprintf(stderr, "\n%s: Attempting to read past end of packet\n", pname); leave(1); } if (flip) { A = A + m - 1; loop(i,m) *A-- = *pBuf++; } else { loop(i,m) *A++ = *pBuf++; } } void Bskip(int n) { pBuf += n; Bleft -= n; } /************************************************* stripping *************************************************/ /* Reads stdin and writes data packet stripped of the TRSR wrapper to Buf */ /* okflag will be set to 1 if packet is OK. 0 means bad packet */ /* newpkt will be set to 1 if an open flag was found in the middle of a packet, which indicates bad packet */ int get_packet(void) { int i; /* If no need to strip wrapper, just read in Blackjack packet into Buf and return*/ /* Does not work for Turborogue data !!!*/ if (do_nostrip) { loop(i,4) Buf[i] = get_byte(0); *((char*)(&bjdlength)) = Buf[2]; *((char*)(&bjdlength) + 1) = Buf[3]; if (flip) flipit(bjdlength); loop(i,bjdlength) Buf[i+4] = get_byte(0); nbyte_pkt += (bjdlength+4); return(1); } /* Strip wrapper */ /* nbyte_searchopen is a counter for bytes which were skipped during search for open packet byte */ /* okflag means that the data are progressing as expected */ /* Find first open packet byte */ /* It's possible that newpkt is already set to 1 */ nbyte_beginsearch=nbyte_in; if(!newpkt) { while (!newpkt) get_byte(0); /* get_byte(0) means get byte and don't update TRSR checksum */ nbyte_searchopen = nbyte_in - nbyte_beginsearch - 1; if(nbyte_searchopen && do_printskip) { fprintf(stderr, "%s: At incoming byte %d (%d outgoing): skipped %d bytes searching for open flag\n", pname, nbyte_in, nbyte_out, nbyte_searchopen); } } nbyte_searchopen=0; nbyte_beginsearch=0; newpkt = 0; nbyte_curpkt=1; nbyte_curpktesc=0; /* Start check sum */ chksum = 0; /* Set okflag to 1. If anything goes wrong inside packet, set okflag to zero and stop reading */ okflag = 1; /* Read first 4 bytes of header after open packet byte */ /* This may be the entire header */ /* The checksum is begun here */ for (i = 0; okflag && (i < 4); i++) Buf[i] = get_byte(1); /* get_byte(1) means get byte and update TRSR checksum */ if (okflag) { flags = Buf[0]; hlength = Buf[1]; *((char*)(&dlength)) = Buf[2]; *((char*)(&dlength) + 1) = Buf[3]; if (flip) flipit(dlength); if ((flags & 0x20) && (flags & 0x10)) { fprintf(stderr, "%s: Bad flags at incoming byte %d (%d outgoing): 0x%02x\n", pname, nbyte_in, nbyte_out, flags); okflag = 0; } } /* read rest of header */ /* This is the completion of the portion of the TRSR wrapper prior to the BJ (or other) packet */ for (i = 4; okflag && (i < hlength); i++) Buf[i] = get_byte(1); /* read BJ packet or other data */ for (i = 0; okflag && (i < dlength); i++) Buf[i] = get_byte(1); /* Examine TRSR checksum */ if (okflag && (flags & 0x20)) { /* Read 2 checksum bytes */ *((char*)(&chk)) = get_byte(2); if (okflag) *((char*)(&chk) + 1) = get_byte(2); if (flip) flipit(chk); /* Compare checksum */ if (okflag && (chksum != chk)) { fprintf(stderr, "%s: Bad checksum at incoming byte %d (%d outgoing): sum = 0x%04x, chk = 0x%04x, lost %d bytes\n", pname, nbyte_in, nbyte_out, chksum, chk, nbyte_curpkt); okflag = 0; nbyte_curpkt=0; nbadchksum++; return(1); } } /* Do packets statistics */ if (okflag) { nbyte_pkt += dlength; nbyte_out += dlength; npkts++; if (do_pkts) { printf("Stripped packet %d, length %d, header %02X %02X at incoming byte %d (%d outgoing)\n", npkts, dlength, Buf[0], Buf[1], nbyte_in, nbyte_out); } } if(!okflag || newpkt) { funnypkts++; fprintf(stderr, "%s: Due to problem at incoming byte %d (%d outgoing): lost %d bytes\n", pname, nbyte_in, nbyte_out, nbyte_curpkt); } nbyte_curpkt=0; nbyte_searchopen=0; pktlength=hlength+dlength+1+nbyte_curpktesc; if(flags & 0x20) pktlength+=2; if(okflag || !newpkt) { byte_good_last=nbyte_in; bytelen_good_last=pktlength; if(npkts==1 && do_tchk) fprintf(ft,"TCHK first good packet= %d to %d\n",byte_good_last-bytelen_good_last+1,byte_good_last); } return(1); } /* get_byte Reads input (stdin) and returns one byte If (do_nostrip), just return a byte Otherwise need to look for new packets, interpret escape characters, increment checksum If unexpected open byte, set newpkt=1 and okflag=0 If unexpected escape sequence, set okflag=0 If find open packet byte, set newpkt=1 If find normal escape character in data, interpret and return appropriate byte midst=0 means ignore checksum stuff (we're before the data) midst=1 means increment checksum (we're in the midst of data) midst=2 means do not increment checksum (we're after the data) */ byte get_byte(int midst) { byte b, bb; int c; /* Read a byte */ if ((c=getchar()) == EOF) leave(0); b=(byte)c; nbyte_in++; nbyte_curpkt++; /* If pre-stripped, just return byte */ if (do_nostrip) return(b); /* Two special cases: 0x02 (open packet) and 0x10 (escape) */ /* 0x02 is open new packet byte */ newpkt = 0; if (b == 0x02) newpkt = 1; /* 0x10 is the escape sequence byte */ /* 0x104f is interpreted as 0x02 */ /* 0x1045 is interpreted as 0x10 */ /* 0x1002 is interpreted as an improper open new packet byte */ else if (b == 0x10) { nbyte_curpktesc++; if ((c=getchar()) == EOF) { fprintf(stderr, "%s: Problem stripping at incoming byte %d (%d outgoing)\n", pname, nbyte_in, nbyte_out); leave(1); } bb=(byte)c; nbyte_in++; nbyte_curpkt++; if (bb == 0x4f) b = 0x02; else if (bb == 0x45) b = 0x10; else { if (bb == 0x02) newpkt = 1; fprintf(stderr, "%s: Bad escape sequence at incoming byte %d (%d outgoing)\n", pname, nbyte_in, nbyte_out); okflag = 0; } } /* if midst=1 or 2, then there should not have been an open new packet byte */ if (midst && newpkt) { fprintf(stderr, "%s: Unexpected new packet at incoming byte %d (%d outgoing)\n", pname, nbyte_in, nbyte_out); okflag = 0; } /* increment checksum */ if (midst == 1) chksum = (chksum << 8) ^ pTable[(chksum >> 8) ^ ((unsigned short)(b))]; return(b); } /* Table for checksum arithmetic */ /* CRC-16 constant array... from Usenet contribution by Mark G. Mendel, Network Systems Corp. (ihnp4!umn-cs!hyper!mark) */ unsigned short Table[] = { 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 }; void init_strip(void) { pTable = Table; } void memflip(char *p, int n) { char ctmp; char *q; q = p + n - 1; while (q > p) { ctmp = *p; *p++ = *q; *q-- = ctmp; } } void leave(int ierr) { int i; if(nbyte_beginsearch) nbyte_searchopen = nbyte_in - nbyte_beginsearch; else nbyte_searchopen=0; if(nbyte_beginsearch) nbyte_curpkt=0; fprintf(stderr,"\n%s Exit stats:\n",pname); fprintf(stderr,"Total incoming bytes: %d\n",nbyte_in); fprintf(stderr,"Total outgoing bytes: %d\n",nbyte_out); fprintf(stderr,"Good packets: %d\n",npkts); fprintf(stderr,"Bad checksums: %d\n",nbadchksum); fprintf(stderr,"Funny packets: %d\n",funnypkts); fprintf(stderr,"Bytes searching: %d\n",nbyte_searchopen); fprintf(stderr,"Bytes current pkt: %d\n",nbyte_curpkt); if(do_tchk) { fprintf(ft,"TCHK last t= %d : packet= %d to %d\n",ttag_tchk,byte_tchk_last-bytelen_tchk_last+1,byte_tchk_last); fprintf(ft,"TCHK min t= %d\n",ttag_tchk_min); fprintf(ft,"TCHK max t= %d\n",ttag_tchk_max); fprintf(ft,"TCHK last good packet= %d to %d\n",byte_good_last-bytelen_good_last+1,byte_good_last); fprintf(ft,"NAVG last t= %d : packet= %d to %d\n",ttag_navg,byte_navg_last-bytelen_navg_last+1,byte_navg_last); for(i=0;i n) { fprintf(stderr, "\n%s (Warning): Length of argument \"%s\" for flag \"%s\" exceeds allowance %d; truncated to \"%s\"\n", pname, argval, arg, n, s); } } void do_ptr(char **s) { if (iarg == NARGS) argprob(arg); *s = ARGV[iarg++]; } void do_int(int *v) { if (iarg == NARGS) argprob(arg); if (strchr(ARGV[iarg],'.')) argprob(arg); if (sscanf(ARGV[iarg], "%d", v) != 1) argprob(arg); iarg++; } void do_real(double *v) { if (iarg == NARGS) argprob(arg); if (sscanf(ARGV[iarg], "%lf", v) != 1) argprob(arg); iarg++; } void do_vec(double *v) { int i; char *argval; loop (i,3) { if (iarg + i == NARGS) argprob(arg); argval = ARGV[iarg + i]; if (sscanf(argval, "%lf", v + i) != 1) argprob(arg); } iarg += 3; } /************************************************* help *************************************************/ void do_usage(void) { fprintf(stderr, "\n"); fprintf(stderr, "Usage: E.g. cat file | %s -obs > file.obs \n", pname); fprintf(stderr, " Type: %s -h\n", pname); fprintf(stderr, " for more details\n"); fprintf(stderr, "\n"); exit(0); } void do_help(void) { fprintf(stderr,"\n"); fprintf(stderr,"BJfmtl reads BlackJack GPS receiver binary data (with or without the Turborogue Space Receiver (TRSR) wrapper), and writes ASCII output.\n"); fprintf(stderr,"\n"); fprintf(stderr,"An example of usage is\n"); fprintf(stderr,"\n"); fprintf(stderr,"cat file | BJfmtl -obs > file.obs\n"); fprintf(stderr,"\n"); fprintf(stderr,"where \"file\" is binary BlackJack data with TRSR wrapper, and \"file.obs\" contains the observable (tracking) data (observables are pseudorange, phase, snr) recorded by the receiver. This command will also write info to stderr including formatting errors (such as faulty checksums), number of data packets, etc, which can typically be ignored.\n"); fprintf(stderr,"\n"); fprintf(stderr,"---------------------------------------------------------\n"); fprintf(stderr,"\n"); fprintf(stderr,"Useful flags\n"); fprintf(stderr,"-h : help\n"); fprintf(stderr,"-obs : output observable data\n"); fprintf(stderr,"-nav : output navigation solutions\n"); fprintf(stderr,"-log : output receiver log data\n"); fprintf(stderr,"-prn nn : output observable data for PRN nn only\n"); fprintf(stderr,"-S stime : output data for time >= stime. stime is integer seconds past 6 Jan 1980 0 UT\n"); fprintf(stderr,"-E etime : output data for time <= etime. etime is integer seconds past 6 Jan 1980 0 UT\n"); fprintf(stderr,"-exit exittime: stop reading input when find data for time >= exittime. exittime is integer seconds past 6 Jan 1980 0 UT\n"); fprintf(stderr,"-weekbdry : attempt to correct faulty time tags at week boundaries\n"); fprintf(stderr,"-strip : Instead of ASCII output, write binary data with TRSR wrapper removed.\n"); fprintf(stderr,"-nostrip : Input already has TRSR wrapper removed.\n"); fprintf(stderr,"-flip : flag for Linux (or similar endian) machines\n"); fprintf(stderr,"\n"); fprintf(stderr,"---------------------------------------------------------\n"); fprintf(stderr,"\n"); fprintf(stderr,"ASCII output format\n"); fprintf(stderr,"\n"); fprintf(stderr,"---------------------------------------------------------\n"); fprintf(stderr,"\n"); fprintf(stderr,"Observable data format:\n"); fprintf(stderr,"\n"); fprintf(stderr,"time (sec past J2000), OBSD, prn (prnxx), antenna index (hex), obstype (hex--does not have stable definition--I currently ignore this one), sample interval (seconds, hex), BlackJack packet size (bytes, decimal), CA:, CA channel (hex), CA SNR, CA phase (cyc), CA pseudorange (meters), P2:, (similar fields), P1:, (similar fields).\n"); fprintf(stderr," \n"); fprintf(stderr,"Observable data packets with a \"sample interval\" of 1 second may also contain high rate (e.g. 50 Hz) data arrays. These will be signaled by large BlackJack packet size (thus far, size > 57 for packets with high rate data) and additional lines following the OBSD line:\n"); fprintf(stderr,"\n"); fprintf(stderr,"One line signaling high rate data types:\n"); fprintf(stderr,"RSD, prn (prnxx), CA doppler (cyc/sec), CA doppler rate (cyc/sec/sec), data type (hex) , data scale (ignore), data sample rate (e.g. 50 for 50 Hz data), (repeat last three for each \"data type\" with high rate data. \"Data types\" are--for phase: CA 0xfc, P1 0xf1, P2 0xf2. For amplitude: CA 0xac, P1 0xa1, P2 0xa2. )\n"); fprintf(stderr,"\n"); fprintf(stderr,"Multiple lines with the high rate data:\n"); fprintf(stderr,"time (sec past J2000), prn (prnxx), HR, phasetype (e.g. CAfaz), phase (cyc), optional amptype (e.g. CAamp), optional amp.\n"); fprintf(stderr,"\n"); fprintf(stderr,"All SNRs are 1 second voltage SNRs on phase.\n"); fprintf(stderr,"CAamp, etc. can be converted to SNR by multiplying by 50.0 * 4.0 / sqrt(20.456e6 * .75 * .9 * 2.0)\n"); fprintf(stderr,"\n"); fprintf(stderr,"---------------------------------------------------------\n"); fprintf(stderr,"\n"); fprintf(stderr,"Navigation data format:\n"); fprintf(stderr,"\n"); fprintf(stderr,"time (sec past J2000), NAVG, x, y, z (km), t_offset (sec), vx, vy, vz (km/sec), t_offset_rate (sec/sec)\n"); fprintf(stderr,"\n"); fprintf(stderr,"---------------------------------------------------------\n"); fprintf(stderr,"\n"); fprintf(stderr,"Log data format\n"); fprintf(stderr,"\n"); fprintf(stderr," log> , receiver log message\n"); fprintf(stderr,"\n"); exit(0); } /************************************************* end *************************************************/