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;j0)?1:0)); 
    printf("\n"); 
 
    getchar(); 
  } 
 
  exit(0); 
#endif   
} 
 
/* ------------------------------ end of file ----------------------------- */