www.pudn.com > opengpssim.zip > ogsencdec.c
/* ************************************************************************ * * * GPS Simulation * * * * -------------------------------------------------------------------- * * * * Module: ogsencdec.cpp * * * * Version: 0.1 * * * * Date: 17.05.02 * * * * Author: G. Beyerle * * * * -------------------------------------------------------------------- * * * * Copyright (C) 2002-2006 Georg Beyerle * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * * * -------------------------------------------------------------------- * * * * The files 'gpsfuncs.cpp', 'gpsrcvr.cpp' and 'gp2021.cpp' are modi- * * fied versions of the files with the same name from Clifford Kelley's * * OpenSourceGPS distribution. The unmodified files can be obtained * * from http://www.home.earthlink.net/~cwkelley * * * * -------------------------------------------------------------------- * * * * Encode / decode navigation message * * * ************************************************************************ */ /* ******************************* changes ******************************** dd.mm.yy - ************************************************************************ */ // to do: /* ------------------------------- includes ------------------------------- */ #include#include #include #include #include #include #define MAIN #include "ogsdefine.h" #include "ogsstructs.h" #include "ogsextern.h" #include "ogsprototypes.h" #include "ogslibrary.h" #include "ogsnavencode.h" #include "ogsnavdecode.h" #undef MAIN /* ------------------------------- defines -------------------------------- */ //#define XMTRBUFLEN 150000 #define RECLEN 256 #define NBUFLEN 3000 #define TMPNAMELEN 32 /* ------------------------------- structs -------------------------------- */ typedef struct { char *record; unsigned long cnt50hz, data_encoded, data_decoded; int sv, parityok; } REC0x36; /* ------------------------------- globals -------------------------------- */ static char NavBit[NAVMSGLEN]; //static unsigned long sf_noparity[6][11]; static unsigned long SubFrame[6][11]; static short int Hist[SUBFRAMELEN]; static short int HistInv[SUBFRAMELEN]; static NAVDATA Nav; static int NBufPos = 0; static char NBuf[NBUFLEN]; char ProgramName[] = "ogsencdec"; static char Version[] = "0.1.1"; //extern char *InputFileName; extern int ReadAsyncOutput, ReadOGSRcvrOutput; extern int SatID; extern int ListOnlyPRN; extern int optind; /* ------------------------------ prototypen ------------------------------ */ static int analyze_databit_histogram( int *maxhist, short int hist[]); static void find_preamble( char message[], int *idx, int *invert); static void copy_msg_to_subframe( char message[], int ofs, int invert, unsigned long sf[6][11]); void getargs( int argc, char *argv[]); int copy_to_navbuf( FILE *fd, int sel_sv, char *buf, long *c50_ptr, int *svprnlist); /* ------------------------------ procedures ------------------------------ */ void usage( void) { printf( "usage: %s [options] filename\n", ProgramName); printf( "version %s (compiled %s %s) \n", Version, __DATE__, __TIME__); printf( " options:\n"); printf( " -h : print this message \n"); printf( " -v : verbose \n"); printf( " -s PRN : satellite id (PRN) \n"); printf( " -a : data from 'async' output \n"); printf( " -l : list PRN present in async file \n"); printf( " -r : data from 'ogsrcvr' output \n"); exit( 0); } void check_options( void) { if ( ReadAsyncOutput && ReadOGSRcvrOutput) { printf( "Option -a and -r cannot be set both at the same time.\n"); usage(); exit( -1); } if (( SatID < 1 || SatID > 32) && ReadAsyncOutput && !ListOnlyPRN) { printf( "Satellite id outside allowed range 1-32 (option -s).\n"); usage(); exit( -1); } if ( ListOnlyPRN && !ReadAsyncOutput) { printf( "Option -l allowed only in combination with option -a.\n"); usage(); exit( -1); } return; } static void conv_async_to_binaryASCII( char *infile) { int i, k, j, len; int found = 0, buflen; int svprnlist[33]; long c50; unsigned char id, reclen, sv; unsigned char rec[RECLEN]; char *tmpfile; char tmpname[TMPNAMELEN]; static FILE *fp = NULL, *fpout; for ( i=1; i<=32; i++) svprnlist[i] = 0; len = strlen( OGSDataDir); tmpfile = conmalloc( len+TMPNAMELEN+1); // ".../data/nav-wwww-ssssss.txt" if ( !fp) { fp = fopen( infile, "rb"); if ( !fp) { printf( "Error opening file '%s'.\n", infile); exit( -1); } else printf( "Opened file '%s'.\n", infile); } do { // buflen = copy_to_navbuf( fp, SatID-1, NavBit, &c50, svprnlist); buflen = copy_to_navbuf( fp, SatID-1, NavBit, &c50, svprnlist); if ( buflen == NAVMSGLEN) { found = 1; copy_msg_to_subframe( NavBit, 0, 0, SubFrame); decode_navmsg( SubFrame, &Nav); // write 1500 bits as byte stream (1500 bytes) to file ... strcpy( tmpfile, OGSDataDir); sprintf( tmpname, "nav-%02d-%04d-%06d-%02d-%02d", SatID, Nav.eph.week, Nav.eph.tow, Nav.sf4pageno, Nav.sf5pageno); strcat( tmpfile, tmpname); fpout = fopen( tmpfile, "wb"); if ( !fpout) { printf( "Error opening file %s.\n", tmpfile); exit(-1); } fwrite( NavBit, NAVMSGLEN, 1, fpout); fclose( fpout); // ... and write as ASCII to file strcpy( tmpfile, OGSDataDir); sprintf( tmpname, "nav-%02d-%04d-%06d-%02d-%02d.txt", SatID, Nav.eph.week, Nav.eph.tow, Nav.sf4pageno, Nav.sf5pageno); strcat( tmpfile, tmpname); fpout = fopen( tmpfile, "w"); if ( !fpout) { printf( "Error opening file %s.\n", tmpfile); exit(-1); } // printf( "\n%s\n", tmpfile); // getchar(); write_sf1to3( &Nav, fpout); write_sf4( &Nav, fpout); write_sf5( &Nav, fpout); fclose( fpout); // printf( "file %s written\n", tmpfile); } } while ( buflen > 0); if ( feof( fp)) { printf( "\n"); // printf("NBufPos = %d\n", NBufPos); printf( "File %s closed!\n", infile); fclose( fp); fp = NULL; } if ( !found || ListOnlyPRN) { int first = 1; printf( "\n"); if ( !ListOnlyPRN) printf( "No data record found for PRN %d\n", SatID); printf( "Following PRNs found: "); for ( i=1; i<=32; i++) if ( svprnlist[i]) { if ( !first) printf( ", ", i); printf( "%d", i); first = 0; } printf( "\n"); } return; } static void conv_ogsrcvr_to_ASCII( char *infile) { int i, k, j, nof, sfno, d30; int startidx, invert; int buflen; int svprnlist[33]; long c50; unsigned char id, reclen, sv; unsigned char rec[RECLEN]; char *ptr; FILE *fp; for ( i=1; i<=32; i++) svprnlist[i] = 0; // len = strlen( OGSDataDir); fp = fopen( infile, "rb"); if ( !fp) { printf( "Error opening file '%s'.\n", infile); exit( -1); } else printf( "Opened file '%s'.\n", infile); nof = fread( NavBit, sizeof( char), NAVMSGLEN, fp); if ( nof != NAVMSGLEN) { printf( "File %s contains just %d bytes (should be 1500).\n", infile, nof); exit(-1); } // for ( i=0; i<=40; i++) // printf( "%d ", NavBit[i]); // printf( "Read %d bytes.\n", nof); find_preamble( NavBit, &startidx, &invert); printf( "Preamble found at byte offset %d.\n", startidx); if ( invert) printf( "Bits are sign inverted.\n"); copy_msg_to_subframe( NavBit, startidx, invert, SubFrame); decode_navmsg( SubFrame, &Nav); // place first subframe at beginning // re-read data from preamble location fseek( fp, startidx, SEEK_SET); nof = fread( NavBit, sizeof( char), NAVMSGLEN, fp); if ( nof != NAVMSGLEN) { printf( "Read only %d bytes (should be 1500).\n", nof); exit(-1); } fclose( fp); copy_msg_to_subframe( NavBit, 0, invert, SubFrame); decode_navmsg( SubFrame, &Nav); // place first subframe at beginning sfno = Nav.sf1how & 0x7; // re-arrange ptr = conmalloc( NAVMSGLEN); for ( i=0; i > 1; j++; } } } return; } // // convert from ASCII to binary // static void conv_ASCII_to_binary( char *infile) { int len; char *tmpfile; FILE *fp; fp = fopen( infile, "r"); if ( !fp) { printf( "Error opening file %s.\n", infile); exit(-1); } else printf( "Reading file %s.\n", infile); // getchar(); read_sf1to3( &Nav, fp); read_sf4( &Nav, fp); read_sf5( &Nav, fp); fclose( fp); encode_navmsg( &Nav, SubFrame); copy_subframe_to_msg( SubFrame, NavBit); len = strlen( infile); tmpfile = conmalloc( len+1); strcpy( tmpfile, infile); tmpfile[len-4] = '\0'; // printf( ">%s<\n", tmpfile); // getchar(); fp = fopen( tmpfile, "wb"); if ( !fp) { printf( "Error opening file %s.\n", tmpfile); exit( -1); } fwrite( NavBit, NAVMSGLEN, 1, fp); fclose( fp); printf( "Finished writing file '%s'.\n", tmpfile); return; } // // convert from binary to ASCII // static void conv_binary_to_ASCII( char *infile) { int nof; char *tmpfile; FILE *fp; tmpfile = infile; fp = fopen( tmpfile, "rb"); if ( !fp) { printf( "Error opening file '%s'.\n", tmpfile); exit(-1); } else printf( "Reading file '%s'.\n", tmpfile); nof = fread( NavBit, sizeof( char), NAVMSGLEN, fp); if ( nof != NAVMSGLEN) { printf( "Could only read %d bytes from file %s (expected 1500 bytes).\n", nof, tmpfile); exit(-1); } fclose( fp); copy_msg_to_subframe( NavBit, 0, 0, SubFrame); decode_navmsg( SubFrame, &Nav); tmpfile = conmalloc( strlen( infile) + 5); strcpy( tmpfile, infile); strcat( tmpfile, ".txt"); fp = fopen( tmpfile, "w"); if ( !fp) { printf( "Error opening file %s.\n", tmpfile); exit(-1); } write_sf1to3( &Nav, fp); write_sf4( &Nav, fp); write_sf5( &Nav, fp); fclose( fp); printf( "Finished writing file '%s'.\n", tmpfile); return; } // // find preamble // static void find_preamble( char message[], int *idx, int *invert) { int i; int idxinv, pattern = 0, maxhist, maxhistinv; short int hist[SUBFRAMELEN]; short int hist_inv[SUBFRAMELEN]; // init to zero for ( i=0; i = 7) { if ( pattern == 0x8b) hist[(i-7)%SUBFRAMELEN] += 1; else if ( pattern == 0x74) hist_inv[(i-7)%SUBFRAMELEN] += 1; } } *idx = analyze_databit_histogram( &maxhist, hist); idxinv = analyze_databit_histogram( &maxhistinv, hist_inv); if ( maxhistinv > maxhist) { *idx = idxinv; *invert = 1; } else *invert = 0; // printf("find_preamble(): maxhistinv = %d, maxhist = %d\n", maxhistinv, maxhist); return; } // // copy 1500 bit nav msg to frame buffer sf[][] // invert = 1: invert msg bits // invert = 0: don't invert msg bits // static void copy_msg_to_subframe( char message[], int ofs, int invert, unsigned long sf[6][11]) { int i, j, sfr, word; unsigned long scale; // printf( "\n"); j=0; for ( sfr=1; sfr<=5; sfr++) { for ( word=1; word<=10; word++) { // scale = 536870912L; // 2^29 scale = 0x1L << 29; sf[sfr][word] = 0; for ( i=0; i<30; i++) { // printf( " %d", message[j+ofs]); if ( !invert) { if ( message[(j+ofs)%1500] == 1) sf[sfr][word] += scale; } else { if ( message[(j+ofs)%1500] != 1) sf[sfr][word] += scale; } scale = scale >> 1; j++; } // printf( " %08x", sf[sfr][word]); } // printf( "\n"); } return; } /******************************************************************************* FUNCTION analyze_databit_histogram() RETURNS Start of bit transition (number between 0,...,19) or -1 (too noise, back to acq) PARAMETERS ch : channel number PURPOSE Find start of bit transition within 20 x 1 msec segments (bit synchronization) using histogram method. REFERENCES Krunvieda et al., A complete IF software GPS receiver: a tutorial about the detail, Data Fusion Corporation WRITTEN BY G. Beyerle TO DO NOTES *******************************************************************************/ static int analyze_databit_histogram( int *maxhist, short int hist[]) { int i, maxhistidx; // unsigned int nofentry = 0; *maxhist = 0; for ( i=0; i<300; i++) { // nofentry += hist[i]; if ( *maxhist < hist[i]) { *maxhist = hist[i]; maxhistidx = i; } // --- clear array --- hist[i] = 0; } return (maxhistidx); } // // main routine // int main( int argc, char *argv[]) { int j, nof, sgn, len; long i, nofwritten; unsigned long cntMSB; double dt; char *infile; char *tmpfile; FILE *fp; // printf("argc = %d\n", argc); // getchar(); if ( argc < 2) usage(); set_directories( argv[0]); // process options getargs( argc, argv); check_options(); #if 0 printf("argc = %d\n", argc); printf("optind = %d\n", optind); printf("argv[0] = %s\n", argv[0]); printf("argv[1] = %s\n", argv[1]); printf("argv[2] = %s\n", argv[2]); getchar(); #endif if ( argc <= optind) usage(); infile = argv[optind]; // --- welcome --- printf("-------------------------------- OpenGPSSim ---------------------------------\n"); printf("ogsencdec version %s\n", Version); printf("Copyright (C) 2001-2006 G. Beyerle, A. Tabernero, C. Kelley and others. \n"); printf("ogsencdec comes with ABSOLUTELY NO WARRANTY; for details see file 'warranty'.\n"); printf("This is free software, and you are welcome to redistribute it under \n"); printf("certain conditions; see file 'copying' for details. \n"); printf("-----------------------------------------------------------------------------\n"); // data files are located in sub directory '.../data/' len = strlen( OGSDataDir) + strlen( infile); tmpfile = conmalloc( len+1); strcpy( tmpfile, OGSDataDir); strcat( tmpfile, infile); len = strlen( tmpfile); if ( ReadAsyncOutput) { // read async files and write as binary and ASCII files conv_async_to_binaryASCII( tmpfile); } else if ( ReadOGSRcvrOutput) { // read ogsrcvr files and write as binary and ASCII files // printf(">%s<", tmpfile + strlen( tmpfile) - 2); // getchar(); // SatID = atoi( tmpfile + strlen( tmpfile) - 2); conv_ogsrcvr_to_ASCII( tmpfile); } else if ( !strcmp( tmpfile + len-4, ".txt")) { // printf(">1:%s<\n", tmpfile); // getchar(); // convert from ASCII to binary conv_ASCII_to_binary( tmpfile); } else { // printf(">2:%s<\n", tmpfile); // getchar(); // convert from binary to ASCII conv_binary_to_ASCII( tmpfile); } exit( 0); #if 0 write_sf1to3( &Nav, FpAsc); write_sf4( &Nav, FpAsc); write_sf5( &Nav, FpAsc); fclose( FpAsc); exit(1); printf( "Finished writing file.\n"); getchar(); // print_nav_data( &Nav); char msg[1500]; // encode_navmsg( i4satid, i5satid, &Nav, msg); // // decode again // find_preamble( msg, &startidx, &invert); copy_msg_to_subframe( NavBit, startidx, invert, SubFrame); decode_navmsg( SubFrame, &Nav); // print_nav_data( &Nav); // // compare // int k; for (k=0;k<1500;k+=70) { for (j=k;j 0)?1:0)); printf("\n"); getchar(); } exit(0); #endif } /* ------------------------------ end of file ----------------------------- */