test_novatel.c

Go to the documentation of this file.
00001 /** 
00002 \file    test_novatel.c
00003 \brief   unit tests for novatel.c/.h
00004 \author  Glenn D. MacGougan (GDM)
00005 \date    2007-11-26
00006 \since   2007-11-26
00007 
00008 \b "LICENSE INFORMATION" \n
00009 Copyright (c) 2007, refer to 'author' doxygen tags \n
00010 All rights reserved. \n
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided the following conditions are met: \n
00014 
00015 - Redistributions of source code must retain the above copyright
00016   notice, this list of conditions and the following disclaimer. \n
00017 - Redistributions in binary form must reproduce the above copyright
00018   notice, this list of conditions and the following disclaimer in the
00019   documentation and/or other materials provided with the distribution. \n
00020 - The name(s) of the contributor(s) may not be used to endorse or promote 
00021   products derived from this software without specific prior written 
00022   permission. \n
00023 
00024 THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS 
00025 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
00026 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00027 DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
00028 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00029 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
00030 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
00031 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
00032 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
00033 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
00034 SUCH DAMAGE.
00035 */
00036 #include <stdio.h>
00037 #include "Basic.h"     // CUnit/Basic.h
00038 #include "gps.h"
00039 #include "novatel.h"
00040 #include "constants.h"
00041 
00042 
00043 int init_suite_NOVATELOEM4(void)
00044 {
00045   return 0;
00046 }
00047 
00048 int clean_suite_NOVATELOEM4(void)
00049 {
00050   return 0;
00051 }
00052 
00053 
00054 void test_NOVATELOEM4_FindNextMessageInFile(void)
00055 {
00056   FILE* fid;
00057   BOOL result;
00058   unsigned char message[8192];
00059   BOOL wasMessageFound = FALSE;
00060   BOOL wasEndOfFileReached = FALSE;
00061   unsigned filePosition = 0;
00062   unsigned short messageLength = 0;
00063   unsigned short messageID = 0;
00064   unsigned numberBadCRC = 0;
00065   
00066   result = fopen_s( &fid, "crctest.bin", "rb" );
00067   CU_ASSERT_FATAL( result == 0 );
00068 
00069   if( result == 0 )
00070     return;
00071 
00072   // crctest.bin - has NovAtel OEM4 binary messages.
00073   // A valid ALMANAC messages, type 73.
00074   // An invalid BESTPOS message, type 42.
00075   // A strange length (100 ) but valid crc RAWGPSSUBFRAME message, type 25.
00076   // An invalid TRACKSTAT message, type 83.
00077   // A valid ALMANAC messages, type 73.  
00078   // A valid BESTPOS message, type 42
00079   // A strange length (100 ) but valid crc RAWGPSSUBFRAME message, type 25.
00080   // An invalid message with a large data length and cut off before the crc is present.
00081   // A valid but emply RANGE message, type 43. 
00082 
00083   result = NOVATELOEM4_FindNextMessageInFile(
00084     fid,
00085     message,
00086     8192, 
00087     &wasEndOfFileReached,
00088     &wasMessageFound,
00089     &filePosition,
00090     &messageLength,
00091     &messageID,
00092     &numberBadCRC );
00093 
00094   CU_ASSERT( !wasEndOfFileReached );
00095   CU_ASSERT( wasMessageFound );
00096   CU_ASSERT( messageID == 73 );
00097   CU_ASSERT( messageLength == 3508 );
00098   CU_ASSERT( numberBadCRC == 0 );
00099 
00100   result = NOVATELOEM4_FindNextMessageInFile(
00101     fid,
00102     message,
00103     8192, 
00104     &wasEndOfFileReached,
00105     &wasMessageFound,
00106     &filePosition,
00107     &messageLength,
00108     &messageID,
00109     &numberBadCRC );
00110 
00111   CU_ASSERT( !wasEndOfFileReached );
00112   CU_ASSERT( wasMessageFound );
00113   CU_ASSERT( messageID == 25 );
00114   CU_ASSERT( numberBadCRC == 1 );
00115   
00116   result = NOVATELOEM4_FindNextMessageInFile(
00117     fid,
00118     message,
00119     8192, 
00120     &wasEndOfFileReached,
00121     &wasMessageFound,
00122     &filePosition,
00123     &messageLength,
00124     &messageID,
00125     &numberBadCRC );
00126 
00127   CU_ASSERT( !wasEndOfFileReached );
00128   CU_ASSERT( wasMessageFound );
00129   CU_ASSERT( messageID == 73 );
00130   CU_ASSERT( messageLength == 3508 );  
00131   CU_ASSERT( numberBadCRC == 1 );
00132 
00133   result = NOVATELOEM4_FindNextMessageInFile(
00134     fid,
00135     message,
00136     8192, 
00137     &wasEndOfFileReached,
00138     &wasMessageFound,
00139     &filePosition,
00140     &messageLength,
00141     &messageID,
00142     &numberBadCRC );
00143 
00144   CU_ASSERT( !wasEndOfFileReached );
00145   CU_ASSERT( wasMessageFound );
00146   CU_ASSERT( messageID == 42 );
00147   CU_ASSERT( messageLength == 72+28+4 );  
00148   CU_ASSERT( numberBadCRC == 0 );
00149 
00150   result = NOVATELOEM4_FindNextMessageInFile(
00151     fid,
00152     message,
00153     8192, 
00154     &wasEndOfFileReached,
00155     &wasMessageFound,
00156     &filePosition,
00157     &messageLength,
00158     &messageID,
00159     &numberBadCRC );
00160 
00161   CU_ASSERT( !wasEndOfFileReached );
00162   CU_ASSERT( wasMessageFound );
00163   CU_ASSERT( messageID == 25 );
00164   CU_ASSERT( numberBadCRC == 0 );
00165   
00166   result = NOVATELOEM4_FindNextMessageInFile(
00167     fid,
00168     message,
00169     8192, 
00170     &wasEndOfFileReached,
00171     &wasMessageFound,
00172     &filePosition,
00173     &messageLength,
00174     &messageID,
00175     &numberBadCRC );
00176 
00177   CU_ASSERT( !wasEndOfFileReached );
00178   CU_ASSERT( wasMessageFound );
00179   CU_ASSERT( messageID == 43 );
00180   CU_ASSERT( numberBadCRC == 0 );
00181   CU_ASSERT( messageLength == 4+28+4 );  
00182 
00183   result = NOVATELOEM4_FindNextMessageInFile(
00184     fid,
00185     message,
00186     8192, 
00187     &wasEndOfFileReached,
00188     &wasMessageFound,
00189     &filePosition,
00190     &messageLength,
00191     &messageID,
00192     &numberBadCRC );
00193 
00194   CU_ASSERT( wasEndOfFileReached );
00195   CU_ASSERT( !wasMessageFound );
00196   
00197   if( fid != NULL )
00198   {
00199     result = fclose( fid );
00200     CU_ASSERT( result == 0 );
00201   }
00202 }
00203 
00204 void test_NOVATELOEM4_DecodeRANGEB(void)
00205 {
00206   unsigned char rangeb[564] = { 
00207     0xaa,0x44,0x12,0x1c,0x2b,0x00,0x02,0x20,0x14,0x02,0x00,0x00,0x6a,0x78, 
00208     0x8a,0x04,0x78,0xbb,0xce,0x0c,0x08,0x00,0x04,0x00,0xa7,0xdd,0xa7,0x00,
00209     0x0c,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x31,0xa1,0x18,0xd7,0xeb,0x0a,
00210     0x77,0x41,0x92,0xa4,0x27,0x3e,0xb8,0x1b,0x6d,0x18,0x00,0x21,0x38,0xc1,
00211     0x03,0xae,0xec,0x3b,0x80,0xac,0x1b,0xc5,0x2a,0x68,0x36,0x42,0xa4,0x70,
00212     0x2a,0x42,0x24,0x3c,0x10,0x08,0x03,0x00,0x00,0x00,0xe4,0x13,0x12,0x64,
00213     0xec,0x0a,0x77,0x41,0xda,0x36,0xf1,0x40,0x06,0x5f,0x3d,0x93,0x6a,0xe7,
00214     0xbb,0xc0,0xf0,0xd8,0x35,0x3c,0x96,0x9b,0xf2,0xc4,0x37,0x27,0x09,0x42,
00215     0x52,0xb8,0x7e,0x40,0x2b,0x3c,0xb0,0x00,0x05,0x00,0x00,0x00,0xd8,0x63,
00216     0x24,0x86,0x32,0x40,0x77,0x41,0xe1,0x30,0x82,0x3e,0xb3,0x50,0xbe,0xc2,
00217     0x44,0xe7,0xf9,0x40,0x6a,0x3b,0xfb,0x3b,0x00,0x78,0x35,0x45,0x9b,0x53,
00218     0x36,0x42,0xf6,0x28,0xd4,0x41,0x84,0x3c,0x10,0x08,0x05,0x00,0x00,0x00,
00219     0xd1,0x8c,0x28,0x81,0x32,0x40,0x77,0x41,0x73,0x93,0x40,0x40,0x42,0x57,
00220     0xc7,0x96,0x6e,0x61,0xd5,0x40,0xa5,0xe2,0xc5,0x3c,0x79,0x67,0x0d,0x45,
00221     0xcb,0xc7,0x0a,0x42,0x14,0xae,0x1f,0x41,0x8b,0x3c,0x30,0x01,0x11,0x00,
00222     0x00,0x00,0x83,0x85,0x7c,0xd3,0x93,0x50,0x75,0x41,0xa7,0x22,0xc1,0x3d,
00223     0x6a,0x92,0xed,0xee,0xee,0xe6,0x36,0xc1,0x37,0x06,0xe0,0x3b,0x00,0x69,
00224     0xa9,0xc4,0x24,0x47,0x38,0x42,0xcd,0x4c,0x8d,0x42,0xa4,0x3c,0x10,0x08,
00225     0x11,0x00,0x00,0x00,0x24,0x77,0xd3,0xb4,0x93,0x50,0x75,0x41,0xb5,0x3d,
00226     0x70,0x3f,0xb2,0x56,0xfe,0xc6,0xe8,0x3a,0x55,0xc0,0xa5,0xea,0x81,0x3b,
00227     0x02,0x02,0x84,0xc4,0xc6,0x9e,0x16,0x42,0x00,0x00,0x00,0x42,0xab,0x3c,
00228     0xb0,0x00,0x18,0x00,0x00,0x00,0xcb,0x42,0x45,0x60,0xe4,0x0a,0x75,0x41,
00229     0x7e,0x79,0x0d,0x3e,0x8a,0xac,0xf3,0x97,0xce,0x46,0x35,0xc1,0x0c,0x77,
00230     0xe5,0x3b,0x00,0xfe,0xb9,0x44,0xa2,0x9f,0x38,0x42,0x9a,0x99,0x3c,0x42,
00231     0xc4,0x3c,0x10,0x08,0x18,0x00,0x00,0x00,0x30,0xdf,0xaf,0x58,0xe4,0x0a,
00232     0x75,0x41,0x9c,0xe5,0xa0,0x3f,0x40,0x1d,0xea,0xd2,0xc6,0x77,0xe5,0x40,
00233     0x6c,0xaf,0x57,0x3b,0xd3,0xed,0x90,0x44,0xd3,0x12,0x16,0x42,0x3d,0x0a,
00234     0xbf,0x41,0xcb,0x3c,0xb0,0x00,0x0e,0x00,0x00,0x00,0x1a,0xff,0x74,0xdf,
00235     0xb6,0x93,0x77,0x41,0xe9,0xe6,0x14,0x3e,0xeb,0x83,0x55,0xf8,0x02,0x44,
00236     0x35,0xc1,0x3a,0xea,0x01,0x3c,0x00,0xa1,0x96,0x44,0x47,0x07,0x35,0x42,
00237     0xb8,0x1e,0x4b,0x42,0xe4,0x3c,0x10,0x08,0x0e,0x00,0x00,0x00,0x6a,0xdb,
00238     0x85,0xd3,0xb6,0x93,0x77,0x41,0x46,0xed,0xa0,0x3f,0x79,0x67,0xa3,0x29,
00239     0x44,0x21,0xe3,0x40,0x31,0x70,0x54,0x3b,0x17,0xbf,0x6a,0x44,0x91,0x50,
00240     0x11,0x42,0x3d,0x0a,0xbf,0x41,0xeb,0x3c,0xb0,0x00,0x17,0x00,0x00,0x00,
00241     0x3e,0x36,0xb1,0x2e,0xab,0xe6,0x76,0x41,0xfb,0x75,0xce,0x3d,0xa8,0x48,
00242     0xae,0x50,0x5c,0xf8,0x31,0xc1,0xdb,0xf8,0xfd,0x3b,0x00,0xa5,0x44,0x45,
00243     0x73,0xcf,0x35,0x42,0xb8,0x9e,0x8f,0x42,0x64,0x3d,0x10,0x08,0x17,0x00,
00244     0x00,0x00,0x5f,0xa8,0xa2,0x08,0xab,0xe6,0x76,0x41,0xf0,0x94,0x65,0x3f,
00245     0x3b,0xa8,0xc4,0xf5,0xd1,0xc3,0xfc,0x40,0x47,0xab,0x99,0x3b,0xbf,0x3a,
00246     0x19,0x45,0x30,0x26,0x12,0x42,0x00,0x00,0x06,0x42,0x6b,0x3d,0xb0,0x00,
00247     0xe1,0xfa,0xa9,0x05 };
00248 
00249   /* The ASCII equivalent of above message
00250   #RANGEA,COM1,0,53.0,COARSESTEERING,1162,214875.000,00040008,dda7,167;
00251   12,
00252   3,0,24161981.444,0.164,-1581312.095,0.007,-2490.781,45.6,42.610,08103c24,
00253   3,0,24161990.254,7.538,-7143.416,0.011,-1940.862,34.3,3.980,00b03c2b,
00254   5,0,24380200.384,0.254,106100.298,0.008,2903.500,45.6,26.520,08103c84,
00255   5,0,24380200.072,3.009,21893.728,0.024,2262.467,34.7,9.980,01303c8b,
00256   17,0,22350141.218,0.094,-1500910.933,0.007,-1355.281,46.1,70.650,08103ca4,
00257   17,0,22350139.302,0.938,-84.920,0.004,-1056.063,37.7,32.000,00b03cab,
00258   24,0,22064710.017,0.138,-1394382.594,0.007,1487.938,46.2,47.150,08103cc4,
00259   24,0,22064709.543,1.257,43966.213,0.003,1159.432,37.5,23.880,00b03ccb,
00260   14,0,24722285.966,0.145,-1393666.970,0.008,1205.031,45.3,50.780,08103ce4,
00261   14,0,24722285.220,1.257,39178.130,0.003,938.986,36.3,23.880,00b03ceb,
00262   23,0,24013490.918,0.101,-1177692.315,0.008,3146.312,45.5,71.810,08103d64,
00263   23,0,24013488.540,0.897,117821.123,0.005,2451.672,36.5,33.500,00b03d6b*c43bd266
00264   */
00265   BOOL result;
00266   unsigned nrObs = 0;
00267   unsigned i = 0;
00268 
00269   NOVATELOEM4_structBinaryHeader header;
00270   NOVATELOEM4_structObservation obsArray[24];
00271 
00272   result = NOVATELOEM4_DecodeRANGEB(
00273     rangeb, 
00274     564,
00275     &header,
00276     obsArray,
00277     24,
00278     &nrObs );
00279   CU_ASSERT( result );
00280   CU_ASSERT( nrObs == 12 );
00281 
00282   CU_ASSERT( header.gpsWeek == 1162 );
00283   CU_ASSERT( header.gpsMilliSeconds == 214875000 );
00284   CU_ASSERT( header.eTimeStatus == NOVATELOEM4_TIMESTATUS_COARSESTEERING );
00285   CU_ASSERT( header.receiverStatus.isErrorIndicated == 0 );
00286   
00287 
00288   for( i = 0; i < nrObs; i++ )
00289     CU_ASSERT( obsArray[i].reserved == 0 );
00290 
00291   // 3,0,24161981.444,0.164,-1581312.095,0.007,-2490.781,45.6,42.610,08103c24,
00292   CU_ASSERT( obsArray[0].prn == 3 );
00293   CU_ASSERT_DOUBLE_EQUAL( obsArray[0].psr,    24161981.444, 1E-03  );
00294   CU_ASSERT_DOUBLE_EQUAL( obsArray[0].psrstd,        0.164, 1E-03  );
00295   CU_ASSERT_DOUBLE_EQUAL( obsArray[0].adr,    -1581312.095, 1E-03  );
00296   CU_ASSERT_DOUBLE_EQUAL( obsArray[0].adrstd,        0.007, 1E-03  );
00297   CU_ASSERT_DOUBLE_EQUAL( obsArray[0].doppler,   -2490.781, 1E-03  );
00298   CU_ASSERT_DOUBLE_EQUAL( obsArray[0].cno,            45.6, 1E-01  );
00299   CU_ASSERT_DOUBLE_EQUAL( obsArray[0].locktime,     42.610, 1E-03  );
00300   CU_ASSERT( obsArray[0].rawTrackingStatus == 0x08103c24 );
00301   CU_ASSERT( obsArray[0].trackingStatus.eTrackingState == NOVATELOEM4_L1PhaseLockLoop );
00302   CU_ASSERT( obsArray[0].trackingStatus.channelNumber == 1 );
00303   CU_ASSERT( obsArray[0].trackingStatus.isPhaseLocked == TRUE );
00304   CU_ASSERT( obsArray[0].trackingStatus.isParityKnown == TRUE );
00305   CU_ASSERT( obsArray[0].trackingStatus.isCodeLocked == TRUE );
00306   CU_ASSERT( obsArray[0].trackingStatus.eCorrelatorSpacing == NOVATELOEM4_OneChipSpacing );
00307   CU_ASSERT( obsArray[0].trackingStatus.eSatelliteSystem == NOVATELOEM4_GPSSystem );
00308   CU_ASSERT( obsArray[0].trackingStatus.isGrouped == TRUE );
00309   CU_ASSERT( obsArray[0].trackingStatus.eFrequency == NOVATELOEM4_L1 );
00310   CU_ASSERT( obsArray[0].trackingStatus.eCodeType == NOVATELOEM4_CACode );
00311   CU_ASSERT( obsArray[0].trackingStatus.isFECEnabled == FALSE );
00312   CU_ASSERT( obsArray[0].trackingStatus.isPrimaryL1Channel == TRUE );
00313   CU_ASSERT( obsArray[0].trackingStatus.isHalfCycleAdded == FALSE );
00314   CU_ASSERT( obsArray[0].trackingStatus.isForcedAssignment == FALSE );
00315 
00316 
00317   // 3,0,24161990.254,7.538,-7143.416,0.011,-1940.862,34.3,3.980,00b03c2b,
00318   CU_ASSERT( obsArray[1].prn == 3 );
00319   CU_ASSERT_DOUBLE_EQUAL( obsArray[1].psr,    24161990.254, 1E-03  );
00320   CU_ASSERT_DOUBLE_EQUAL( obsArray[1].psrstd,        7.538, 1E-03  );
00321   CU_ASSERT_DOUBLE_EQUAL( obsArray[1].adr,       -7143.416, 1E-03  );
00322   CU_ASSERT_DOUBLE_EQUAL( obsArray[1].adrstd,        0.011, 1E-03  );
00323   CU_ASSERT_DOUBLE_EQUAL( obsArray[1].doppler,   -1940.862, 1E-03  );
00324   CU_ASSERT_DOUBLE_EQUAL( obsArray[1].cno,            34.3, 1E-01  );
00325   CU_ASSERT_DOUBLE_EQUAL( obsArray[1].locktime,      3.980, 1E-03  );
00326   CU_ASSERT( obsArray[1].rawTrackingStatus == 0x00b03c2b );
00327   CU_ASSERT( obsArray[1].trackingStatus.eTrackingState == NOVATELOEM4_L2PhaseLockLoop );
00328   CU_ASSERT( obsArray[1].trackingStatus.channelNumber == 1 );
00329   CU_ASSERT( obsArray[1].trackingStatus.isPhaseLocked == TRUE );
00330   CU_ASSERT( obsArray[1].trackingStatus.isParityKnown == TRUE );
00331   CU_ASSERT( obsArray[1].trackingStatus.isCodeLocked == TRUE );
00332   CU_ASSERT( obsArray[1].trackingStatus.eCorrelatorSpacing == NOVATELOEM4_OneChipSpacing );
00333   CU_ASSERT( obsArray[1].trackingStatus.eSatelliteSystem == NOVATELOEM4_GPSSystem );
00334   CU_ASSERT( obsArray[1].trackingStatus.isGrouped == TRUE );
00335   CU_ASSERT( obsArray[1].trackingStatus.eFrequency == NOVATELOEM4_L2 );
00336   CU_ASSERT( obsArray[1].trackingStatus.eCodeType == NOVATELOEM4_PCode );
00337   CU_ASSERT( obsArray[1].trackingStatus.isFECEnabled == FALSE );
00338   CU_ASSERT( obsArray[1].trackingStatus.isPrimaryL1Channel == FALSE );
00339   CU_ASSERT( obsArray[1].trackingStatus.isHalfCycleAdded == FALSE );
00340   CU_ASSERT( obsArray[1].trackingStatus.isForcedAssignment == FALSE );
00341 
00342   //5,0,24380200.384,0.254,106100.298,0.008,2903.500,45.6,26.520,08103c84,
00343   CU_ASSERT( obsArray[2].prn == 5 );
00344   CU_ASSERT_DOUBLE_EQUAL( obsArray[2].psr,    24380200.384, 1E-03  );
00345   CU_ASSERT_DOUBLE_EQUAL( obsArray[2].psrstd,        0.254, 1E-03  );
00346   CU_ASSERT_DOUBLE_EQUAL( obsArray[2].adr,      106100.298, 1E-03  );
00347   CU_ASSERT_DOUBLE_EQUAL( obsArray[2].adrstd,        0.008, 1E-03  );
00348   CU_ASSERT_DOUBLE_EQUAL( obsArray[2].doppler,    2903.500, 1E-03  );
00349   CU_ASSERT_DOUBLE_EQUAL( obsArray[2].cno,            45.6, 1E-01  );
00350   CU_ASSERT_DOUBLE_EQUAL( obsArray[2].locktime,     26.520, 1E-03  );
00351   CU_ASSERT( obsArray[2].rawTrackingStatus == 0x08103c84 );
00352 
00353   //5,0,24380200.072,3.009,21893.728,0.024,2262.467,34.7,9.980,01303c8b,  
00354   CU_ASSERT( obsArray[3].prn == 5 );
00355   CU_ASSERT_DOUBLE_EQUAL( obsArray[3].psr,    24380200.072, 1E-03  );
00356   CU_ASSERT_DOUBLE_EQUAL( obsArray[3].psrstd,        3.009, 1E-03  );
00357   CU_ASSERT_DOUBLE_EQUAL( obsArray[3].adr,       21893.728, 1E-03  );
00358   CU_ASSERT_DOUBLE_EQUAL( obsArray[3].adrstd,        0.024, 1E-03  );
00359   CU_ASSERT_DOUBLE_EQUAL( obsArray[3].doppler,    2262.467, 1E-03  );
00360   CU_ASSERT_DOUBLE_EQUAL( obsArray[3].cno,            34.7, 1E-01  );
00361   CU_ASSERT_DOUBLE_EQUAL( obsArray[3].locktime,      9.980, 1E-03  );
00362   CU_ASSERT( obsArray[3].rawTrackingStatus == 0x01303c8b );
00363 
00364   //17,0,22350141.218,0.094,-1500910.933,0.007,-1355.281,46.1,70.650,08103ca4,
00365   CU_ASSERT( obsArray[4].prn == 17 );
00366   CU_ASSERT_DOUBLE_EQUAL( obsArray[4].psr,    22350141.218, 1E-03  );
00367   CU_ASSERT_DOUBLE_EQUAL( obsArray[4].psrstd,        0.094, 1E-03  );
00368   CU_ASSERT_DOUBLE_EQUAL( obsArray[4].adr,    -1500910.933, 1E-03  );
00369   CU_ASSERT_DOUBLE_EQUAL( obsArray[4].adrstd,        0.007, 1E-03  );
00370   CU_ASSERT_DOUBLE_EQUAL( obsArray[4].doppler,   -1355.281, 1E-03  );
00371   CU_ASSERT_DOUBLE_EQUAL( obsArray[4].cno,            46.1, 1E-01  );
00372   CU_ASSERT_DOUBLE_EQUAL( obsArray[4].locktime,     70.650, 1E-03  );
00373   CU_ASSERT( obsArray[4].rawTrackingStatus == 0x08103ca4 );
00374 
00375   //17,0,22350139.302,0.938,-84.920,0.004,-1056.063,37.7,32.000,00b03cab,
00376   CU_ASSERT( obsArray[5].prn == 17 );
00377   CU_ASSERT_DOUBLE_EQUAL( obsArray[5].psr,    22350139.302, 1E-03  );
00378   CU_ASSERT_DOUBLE_EQUAL( obsArray[5].psrstd,        0.938, 1E-03  );
00379   CU_ASSERT_DOUBLE_EQUAL( obsArray[5].adr,         -84.920, 1E-03  );
00380   CU_ASSERT_DOUBLE_EQUAL( obsArray[5].adrstd,        0.004, 1E-03  );
00381   CU_ASSERT_DOUBLE_EQUAL( obsArray[5].doppler,   -1056.063, 1E-03  );
00382   CU_ASSERT_DOUBLE_EQUAL( obsArray[5].cno,            37.7, 1E-01  );
00383   CU_ASSERT_DOUBLE_EQUAL( obsArray[5].locktime,     32.000, 1E-03  );
00384   CU_ASSERT( obsArray[5].rawTrackingStatus == 0x00b03cab );
00385 
00386   //24,0,22064710.017,0.138,-1394382.594,0.007,1487.938,46.2,47.150,08103cc4,
00387   CU_ASSERT( obsArray[6].prn == 24 );
00388   CU_ASSERT_DOUBLE_EQUAL( obsArray[6].psr,    22064710.017, 1E-03  );
00389   CU_ASSERT_DOUBLE_EQUAL( obsArray[6].psrstd,        0.138, 1E-03  );
00390   CU_ASSERT_DOUBLE_EQUAL( obsArray[6].adr,    -1394382.594, 1E-03  );
00391   CU_ASSERT_DOUBLE_EQUAL( obsArray[6].adrstd,        0.007, 1E-03  );
00392   CU_ASSERT_DOUBLE_EQUAL( obsArray[6].doppler,    1487.938, 1E-03  );
00393   CU_ASSERT_DOUBLE_EQUAL( obsArray[6].cno,            46.2, 1E-01  );
00394   CU_ASSERT_DOUBLE_EQUAL( obsArray[6].locktime,     47.150, 1E-03  );
00395   CU_ASSERT( obsArray[6].rawTrackingStatus == 0x08103cc4 );
00396 
00397   //24,0,22064709.543,1.257,43966.213,0.003,1159.432,37.5,23.880,00b03ccb,
00398   CU_ASSERT( obsArray[7].prn == 24 );
00399   CU_ASSERT_DOUBLE_EQUAL( obsArray[7].psr,    22064709.543, 1E-03  );
00400   CU_ASSERT_DOUBLE_EQUAL( obsArray[7].psrstd,        1.257, 1E-03  );
00401   CU_ASSERT_DOUBLE_EQUAL( obsArray[7].adr,       43966.213, 1E-03  );
00402   CU_ASSERT_DOUBLE_EQUAL( obsArray[7].adrstd,        0.003, 1E-03  );
00403   CU_ASSERT_DOUBLE_EQUAL( obsArray[7].doppler,    1159.432, 1E-03  );
00404   CU_ASSERT_DOUBLE_EQUAL( obsArray[7].cno,            37.5, 1E-01  );
00405   CU_ASSERT_DOUBLE_EQUAL( obsArray[7].locktime,     23.880, 1E-03  );
00406   CU_ASSERT( obsArray[7].rawTrackingStatus == 0x00b03ccb );
00407 
00408   //14,0,24722285.966,0.145,-1393666.970,0.008,1205.031,45.3,50.780,08103ce4,
00409   CU_ASSERT( obsArray[8].prn == 14 );
00410   CU_ASSERT_DOUBLE_EQUAL( obsArray[8].psr,    24722285.966, 1E-03  );
00411   CU_ASSERT_DOUBLE_EQUAL( obsArray[8].psrstd,        0.145, 1E-03  );
00412   CU_ASSERT_DOUBLE_EQUAL( obsArray[8].adr,    -1393666.970, 1E-03  );
00413   CU_ASSERT_DOUBLE_EQUAL( obsArray[8].adrstd,        0.008, 1E-03  );
00414   CU_ASSERT_DOUBLE_EQUAL( obsArray[8].doppler,    1205.031, 1E-03  );
00415   CU_ASSERT_DOUBLE_EQUAL( obsArray[8].cno,            45.3, 1E-01  );
00416   CU_ASSERT_DOUBLE_EQUAL( obsArray[8].locktime,     50.780, 1E-03  );
00417   CU_ASSERT( obsArray[8].rawTrackingStatus == 0x08103ce4 );
00418 
00419   //14,0,24722285.220,1.257,39178.130,0.003,938.986,36.3,23.880,00b03ceb,
00420   CU_ASSERT( obsArray[9].prn == 14 );
00421   CU_ASSERT_DOUBLE_EQUAL( obsArray[9].psr,    24722285.220, 1E-03  );
00422   CU_ASSERT_DOUBLE_EQUAL( obsArray[9].psrstd,        1.257, 1E-03  );
00423   CU_ASSERT_DOUBLE_EQUAL( obsArray[9].adr,       39178.130, 1E-03  );
00424   CU_ASSERT_DOUBLE_EQUAL( obsArray[9].adrstd,        0.003, 1E-03  );
00425   CU_ASSERT_DOUBLE_EQUAL( obsArray[9].doppler,     938.986, 1E-03  );
00426   CU_ASSERT_DOUBLE_EQUAL( obsArray[9].cno,            36.3, 1E-01  );
00427   CU_ASSERT_DOUBLE_EQUAL( obsArray[9].locktime,     23.880, 1E-03  );
00428   CU_ASSERT( obsArray[9].rawTrackingStatus == 0x00b03ceb );
00429 
00430   //23,0,24013490.918,0.101,-1177692.315,0.008,3146.312,45.5,71.810,08103d64,
00431   CU_ASSERT( obsArray[10].prn == 23 );
00432   CU_ASSERT_DOUBLE_EQUAL( obsArray[10].psr,    24013490.918, 1E-03  );
00433   CU_ASSERT_DOUBLE_EQUAL( obsArray[10].psrstd,        0.101, 1E-03  );
00434   CU_ASSERT_DOUBLE_EQUAL( obsArray[10].adr,    -1177692.315, 1E-03  );
00435   CU_ASSERT_DOUBLE_EQUAL( obsArray[10].adrstd,        0.008, 1E-03  );
00436   CU_ASSERT_DOUBLE_EQUAL( obsArray[10].doppler,    3146.312, 1E-03  );
00437   CU_ASSERT_DOUBLE_EQUAL( obsArray[10].cno,            45.5, 1E-01  );
00438   CU_ASSERT_DOUBLE_EQUAL( obsArray[10].locktime,     71.810, 1E-03  );
00439   CU_ASSERT( obsArray[10].rawTrackingStatus == 0x08103d64 );
00440   CU_ASSERT( obsArray[10].trackingStatus.eTrackingState == NOVATELOEM4_L1PhaseLockLoop );
00441   CU_ASSERT( obsArray[10].trackingStatus.channelNumber == 11 );
00442   CU_ASSERT( obsArray[10].trackingStatus.isPhaseLocked == TRUE );
00443   CU_ASSERT( obsArray[10].trackingStatus.isParityKnown == TRUE );
00444   CU_ASSERT( obsArray[10].trackingStatus.isCodeLocked == TRUE );
00445   CU_ASSERT( obsArray[10].trackingStatus.eCorrelatorSpacing == NOVATELOEM4_OneChipSpacing );
00446   CU_ASSERT( obsArray[10].trackingStatus.eSatelliteSystem == NOVATELOEM4_GPSSystem );
00447   CU_ASSERT( obsArray[10].trackingStatus.isGrouped == TRUE );
00448   CU_ASSERT( obsArray[10].trackingStatus.eFrequency == NOVATELOEM4_L1 );
00449   CU_ASSERT( obsArray[10].trackingStatus.eCodeType == NOVATELOEM4_CACode );
00450   CU_ASSERT( obsArray[10].trackingStatus.isFECEnabled == FALSE );
00451   CU_ASSERT( obsArray[10].trackingStatus.isPrimaryL1Channel == TRUE );
00452   CU_ASSERT( obsArray[10].trackingStatus.isHalfCycleAdded == FALSE );
00453   CU_ASSERT( obsArray[10].trackingStatus.isForcedAssignment == FALSE );
00454 
00455 
00456   //23,0,24013488.540,0.897,117821.123,0.005,2451.672,36.5,33.500,00b03d6b
00457   CU_ASSERT( obsArray[11].prn == 23 );
00458   CU_ASSERT_DOUBLE_EQUAL( obsArray[11].psr,    24013488.540, 1E-03  );
00459   CU_ASSERT_DOUBLE_EQUAL( obsArray[11].psrstd,        0.897, 1E-03  );
00460   CU_ASSERT_DOUBLE_EQUAL( obsArray[11].adr,      117821.123, 1E-03  );
00461   CU_ASSERT_DOUBLE_EQUAL( obsArray[11].adrstd,        0.005, 1E-03  );
00462   CU_ASSERT_DOUBLE_EQUAL( obsArray[11].doppler,    2451.672, 1E-03  );
00463   CU_ASSERT_DOUBLE_EQUAL( obsArray[11].cno,            36.5, 1E-01  );
00464   CU_ASSERT_DOUBLE_EQUAL( obsArray[11].locktime,     33.500, 1E-03  );
00465   CU_ASSERT( obsArray[11].rawTrackingStatus == 0x00b03d6b );
00466   CU_ASSERT( obsArray[11].trackingStatus.eTrackingState == NOVATELOEM4_L2PhaseLockLoop );
00467   CU_ASSERT( obsArray[11].trackingStatus.channelNumber == 11 );
00468   CU_ASSERT( obsArray[11].trackingStatus.isPhaseLocked == TRUE );
00469   CU_ASSERT( obsArray[11].trackingStatus.isParityKnown == TRUE );
00470   CU_ASSERT( obsArray[11].trackingStatus.isCodeLocked == TRUE );
00471   CU_ASSERT( obsArray[11].trackingStatus.eCorrelatorSpacing == NOVATELOEM4_OneChipSpacing );
00472   CU_ASSERT( obsArray[11].trackingStatus.eSatelliteSystem == NOVATELOEM4_GPSSystem );
00473   CU_ASSERT( obsArray[11].trackingStatus.isGrouped == TRUE );
00474   CU_ASSERT( obsArray[11].trackingStatus.eFrequency == NOVATELOEM4_L2 );
00475   CU_ASSERT( obsArray[11].trackingStatus.eCodeType == NOVATELOEM4_PCode );
00476   CU_ASSERT( obsArray[11].trackingStatus.isFECEnabled == FALSE );
00477   CU_ASSERT( obsArray[11].trackingStatus.isPrimaryL1Channel == FALSE );
00478   CU_ASSERT( obsArray[11].trackingStatus.isHalfCycleAdded == FALSE );
00479   CU_ASSERT( obsArray[11].trackingStatus.isForcedAssignment == FALSE );
00480 }
00481 
00482 
00483 
00484 void test_NOVATELOEM4_DecodeRANGECMPB(void)
00485 {
00486   unsigned char rangecmpb[324] = {
00487     0xaa,0x44,0x12,0x1c,0x8c,0x00,0x02,0x20,0x24,0x01,0x00,0x00,0x6a,0x78,0x8a,0x04,
00488     0x78,0xbb,0xce,0x0c,0x08,0x00,0x04,0x00,0xa7,0xdd,0xa7,0x00,0x0c,0x00,0x00,0x00,
00489     0x24,0x3c,0x10,0x08,0x38,0x45,0xf6,0x8f,0xeb,0x75,0x85,0x0b,0xe7,0xff,0xde,0x67,
00490     0x23,0x03,0x53,0x05,0x20,0x03,0x00,0x00,0x2b,0x3c,0xb0,0x00,0x24,0x6b,0xf8,0x0f,
00491     0x32,0x76,0x85,0x0b,0x95,0x18,0xe4,0x7f,0x4b,0x03,0x7f,0x00,0xc0,0x01,0x00,0x00,
00492     0x84,0x3c,0x10,0x08,0x80,0x57,0x0b,0x10,0x43,0x19,0xa0,0x0b,0x4c,0x74,0x9e,0x81,
00493     0x25,0x05,0x50,0x03,0x20,0x03,0x00,0x00,0x8b,0x3c,0x30,0x01,0x77,0xd6,0x08,0x90,
00494     0x40,0x19,0xa0,0x0b,0xba,0x85,0x55,0x80,0xba,0x05,0x3f,0x01,0xc0,0x01,0x00,0x00,
00495     0xa4,0x3c,0x10,0x08,0xb8,0xb4,0xfa,0xbf,0xe9,0x49,0xa8,0x0a,0x11,0x11,0x19,0xe9,
00496     0x22,0x11,0xd4,0x08,0x40,0x03,0x00,0x00,0xab,0x3c,0xb0,0x00,0xf0,0xdf,0xfb,0x6f,
00497     0xda,0x49,0xa8,0x0a,0x14,0xab,0xff,0xff,0x18,0x11,0x00,0x04,0x20,0x02,0x00,0x00,
00498     0xc4,0x3c,0x10,0x08,0xf0,0xcf,0x05,0x20,0x30,0x72,0x85,0x0a,0x68,0x31,0xb9,0x6a,
00499     0x23,0x18,0xe4,0x05,0x40,0x03,0x00,0x00,0xcb,0x3c,0xb0,0x00,0x6e,0x87,0x04,0x50,
00500     0x2c,0x72,0x85,0x0a,0x36,0xbe,0xab,0x00,0x08,0x18,0xfc,0x02,0x20,0x02,0x00,0x00,
00501     0xe4,0x3c,0x10,0x08,0x08,0xb5,0x04,0xb0,0x6f,0xdb,0xc9,0x0b,0x07,0xfd,0xbb,0x6a,
00502     0x33,0x0e,0x58,0x06,0x20,0x03,0x00,0x00,0xeb,0x3c,0xb0,0x00,0xfc,0xaa,0x03,0xc0,
00503     0x69,0xdb,0xc9,0x0b,0x21,0x0a,0x99,0x00,0x08,0x0e,0xfc,0x02,0x00,0x02,0x00,0x00,
00504     0x64,0x3d,0x10,0x08,0x50,0x4a,0x0c,0x50,0x97,0x55,0x73,0x0b,0xaf,0xa3,0x07,0x6e,
00505     0x22,0x17,0xf9,0x08,0x20,0x03,0x00,0x00,0x6b,0x3d,0xb0,0x00,0xab,0x93,0x09,0x50,
00506     0x84,0x55,0x73,0x0b,0x1f,0x3d,0xcc,0x81,0x18,0x17,0x30,0x04,0x00,0x02,0x00,0x00,
00507     0xc6,0x36,0x8c,0x99 };
00508 
00509   /* The ASCII equivalent of above message
00510   #RANGEA,COM1,0,53.0,COARSESTEERING,1162,214875.000,00040008,dda7,167;
00511   12,
00512   3,0,24161981.438,0.169,-127410432.098,0.006,-2490.781,45.0,42.594,08103c24,
00513   3,0,24161990.250,9.500,-100670439.418,0.010,-1940.859,34.0,3.969,00b03c2b,
00514   5,0,24380200.383,0.380,-125723019.703,0.006,2903.500,45.0,26.500,08103c84,
00515   5,0,24380200.070,4.750,-100641402.273,0.023,2262.465,34.0,9.969,01303c8b,
00516   17,0,22350141.211,0.113,-118941422.934,0.006,-1355.281,46.0,70.625,08103ca4,
00517   17,0,22350139.297,1.281,-92274772.922,0.004,-1056.062,37.0,32.000,00b03cab,
00518   24,0,22064710.016,0.169,-118834894.594,0.006,1487.938,46.0,47.125,08103cc4,
00519   24,0,22064709.539,1.281,-92230721.789,0.002,1159.430,37.0,23.875,00b03ccb,
00520   14,0,24722285.961,0.169,-127222786.973,0.008,1205.031,45.0,50.750,08103ce4,
00521   14,0,24722285.219,1.281,-100624117.871,0.002,938.984,36.0,23.875,00b03ceb,
00522   23,0,24013490.914,0.113,-127006812.316,0.006,3146.312,45.0,71.781,08103d64,
00523   23,0,24013488.539,1.281,-100545474.879,0.004,2451.668,36.0,33.500,00b03d6b*cf846d48
00524 
00525   #RANGECMPA,COM1,0,53.0,COARSESTEERING,1162,214875.000,00040008,dda7,167;12,
00526   243c10083845f68feb75850be7ffde672303530520030000,
00527   2b3cb000246bf80f3276850b9518e47f4b037f00c0010000,
00528   843c100880570b104319a00b4c749e812505500320030000,
00529   8b3c300177d608904019a00bba855580ba053f01c0010000,
00530   a43c1008b8b4fabfe949a80a111119e92211d40840030000,
00531   ab3cb000f0dffb6fda49a80a14abffff1811000420020000,
00532   c43c1008f0cf05203072850a6831b96a2318e40540030000,
00533   cb3cb0006e8704502c72850a36beab000818fc0220020000,
00534   e43c100808b504b06fdbc90b07fdbb6a330e580620030000,
00535   eb3cb000fcaa03c069dbc90b210a9900080efc0200020000,
00536   643d1008504a0c509755730bafa3076e2217f90820030000,
00537   6b3db000ab9309508455730b1f3dcc811817300400020000*5779f4c5
00538   */
00539   BOOL result;
00540   unsigned nrObs = 0;
00541   unsigned i = 0;
00542 
00543   NOVATELOEM4_structBinaryHeader header;
00544   NOVATELOEM4_structObservation obsArray[24];
00545 
00546   result = NOVATELOEM4_DecodeRANGECMPB(
00547     rangecmpb, 
00548     324,
00549     &header,
00550     obsArray,
00551     24,
00552     &nrObs );
00553   CU_ASSERT( result );
00554   CU_ASSERT( nrObs == 12 );
00555 
00556   CU_ASSERT( header.gpsWeek == 1162 );
00557   CU_ASSERT( header.gpsMilliSeconds == 214875000 );
00558   CU_ASSERT( header.eTimeStatus == NOVATELOEM4_TIMESTATUS_COARSESTEERING );
00559   CU_ASSERT( header.receiverStatus.isErrorIndicated == 0 );
00560   
00561 
00562   for( i = 0; i < nrObs; i++ )
00563     CU_ASSERT( obsArray[i].reserved == 0 );
00564 
00565   // 3,0,24161981.438,0.169,-127410432.098,0.006,-2490.781,45.0,42.594,08103c24,
00566   CU_ASSERT( obsArray[0].prn == 3 );
00567   CU_ASSERT_DOUBLE_EQUAL( obsArray[0].psr,    24161981.438, 1E-03  );
00568   CU_ASSERT_DOUBLE_EQUAL( obsArray[0].psrstd,        0.169, 1E-03  );
00569   CU_ASSERT_DOUBLE_EQUAL( obsArray[0].adr,  -127410432.098, 1E-03  );
00570   CU_ASSERT_DOUBLE_EQUAL( obsArray[0].adrstd,        0.006, 1E-03  );
00571   CU_ASSERT_DOUBLE_EQUAL( obsArray[0].doppler,   -2490.781, 1E-03  );
00572   CU_ASSERT_DOUBLE_EQUAL( obsArray[0].cno,            45.0, 1E-01  );
00573   CU_ASSERT_DOUBLE_EQUAL( obsArray[0].locktime,     42.594, 1E-03  );
00574   CU_ASSERT( obsArray[0].rawTrackingStatus == 0x08103c24 );
00575   CU_ASSERT( obsArray[0].trackingStatus.eTrackingState == NOVATELOEM4_L1PhaseLockLoop );
00576   CU_ASSERT( obsArray[0].trackingStatus.channelNumber == 1 );
00577   CU_ASSERT( obsArray[0].trackingStatus.isPhaseLocked == TRUE );
00578   CU_ASSERT( obsArray[0].trackingStatus.isParityKnown == TRUE );
00579   CU_ASSERT( obsArray[0].trackingStatus.isCodeLocked == TRUE );
00580   CU_ASSERT( obsArray[0].trackingStatus.eCorrelatorSpacing == NOVATELOEM4_OneChipSpacing );
00581   CU_ASSERT( obsArray[0].trackingStatus.eSatelliteSystem == NOVATELOEM4_GPSSystem );
00582   CU_ASSERT( obsArray[0].trackingStatus.isGrouped == TRUE );
00583   CU_ASSERT( obsArray[0].trackingStatus.eFrequency == NOVATELOEM4_L1 );
00584   CU_ASSERT( obsArray[0].trackingStatus.eCodeType == NOVATELOEM4_CACode );
00585   CU_ASSERT( obsArray[0].trackingStatus.isFECEnabled == FALSE );
00586   CU_ASSERT( obsArray[0].trackingStatus.isPrimaryL1Channel == TRUE );
00587   CU_ASSERT( obsArray[0].trackingStatus.isHalfCycleAdded == FALSE );
00588   CU_ASSERT( obsArray[0].trackingStatus.isForcedAssignment == FALSE );
00589 
00590 
00591   // 3,0,24161990.250,9.500,-100670439.418,0.010,-1940.859,34.0,3.969,00b03c2b,
00592   CU_ASSERT( obsArray[1].prn == 3 );
00593   CU_ASSERT_DOUBLE_EQUAL( obsArray[1].psr,    24161990.250, 1E-03  );
00594   CU_ASSERT_DOUBLE_EQUAL( obsArray[1].psrstd,        9.500, 1E-03  );
00595   CU_ASSERT_DOUBLE_EQUAL( obsArray[1].adr,  -100670439.418, 1E-03  );
00596   CU_ASSERT_DOUBLE_EQUAL( obsArray[1].adrstd,        0.010, 1E-03  );
00597   CU_ASSERT_DOUBLE_EQUAL( obsArray[1].doppler,   -1940.859, 1E-03  );
00598   CU_ASSERT_DOUBLE_EQUAL( obsArray[1].cno,            34.0, 1E-01  );
00599   CU_ASSERT_DOUBLE_EQUAL( obsArray[1].locktime,      3.969, 1E-03  );
00600   CU_ASSERT( obsArray[1].rawTrackingStatus == 0x00b03c2b );
00601   CU_ASSERT( obsArray[1].trackingStatus.eTrackingState == NOVATELOEM4_L2PhaseLockLoop );
00602   CU_ASSERT( obsArray[1].trackingStatus.channelNumber == 1 );
00603   CU_ASSERT( obsArray[1].trackingStatus.isPhaseLocked == TRUE );
00604   CU_ASSERT( obsArray[1].trackingStatus.isParityKnown == TRUE );
00605   CU_ASSERT( obsArray[1].trackingStatus.isCodeLocked == TRUE );
00606   CU_ASSERT( obsArray[1].trackingStatus.eCorrelatorSpacing == NOVATELOEM4_OneChipSpacing );
00607   CU_ASSERT( obsArray[1].trackingStatus.eSatelliteSystem == NOVATELOEM4_GPSSystem );
00608   CU_ASSERT( obsArray[1].trackingStatus.isGrouped == TRUE );
00609   CU_ASSERT( obsArray[1].trackingStatus.eFrequency == NOVATELOEM4_L2 );
00610   CU_ASSERT( obsArray[1].trackingStatus.eCodeType == NOVATELOEM4_PCode );
00611   CU_ASSERT( obsArray[1].trackingStatus.isFECEnabled == FALSE );
00612   CU_ASSERT( obsArray[1].trackingStatus.isPrimaryL1Channel == FALSE );
00613   CU_ASSERT( obsArray[1].trackingStatus.isHalfCycleAdded == FALSE );
00614   CU_ASSERT( obsArray[1].trackingStatus.isForcedAssignment == FALSE );
00615 
00616   //5,0,24380200.383,0.380,-125723019.703,0.006,2903.500,45.0,26.500,08103c84,
00617   CU_ASSERT( obsArray[2].prn == 5 );
00618   CU_ASSERT_DOUBLE_EQUAL( obsArray[2].psr,    24380200.383, 1E-03  );
00619   CU_ASSERT_DOUBLE_EQUAL( obsArray[2].psrstd,        0.380, 1E-03  );
00620   CU_ASSERT_DOUBLE_EQUAL( obsArray[2].adr,  -125723019.703, 1E-03  );
00621   CU_ASSERT_DOUBLE_EQUAL( obsArray[2].adrstd,        0.006, 1E-03  );
00622   CU_ASSERT_DOUBLE_EQUAL( obsArray[2].doppler,    2903.500, 1E-03  );
00623   CU_ASSERT_DOUBLE_EQUAL( obsArray[2].cno,            45.0, 1E-01  );
00624   CU_ASSERT_DOUBLE_EQUAL( obsArray[2].locktime,     26.500, 1E-03  );
00625   CU_ASSERT( obsArray[2].rawTrackingStatus == 0x08103c84 );
00626 
00627   //5,0,24380200.070,4.750,-100641402.273,0.023,2262.465,34.0,9.969,01303c8b,
00628   CU_ASSERT( obsArray[3].prn == 5 );
00629   CU_ASSERT_DOUBLE_EQUAL( obsArray[3].psr,    24380200.070, 1E-03  );
00630   CU_ASSERT_DOUBLE_EQUAL( obsArray[3].psrstd,        4.750, 1E-03  );
00631   CU_ASSERT_DOUBLE_EQUAL( obsArray[3].adr,  -100641402.273, 1E-03  );
00632   CU_ASSERT_DOUBLE_EQUAL( obsArray[3].adrstd,        0.023, 1E-03  );
00633   CU_ASSERT_DOUBLE_EQUAL( obsArray[3].doppler,    2262.465, 1E-03  );
00634   CU_ASSERT_DOUBLE_EQUAL( obsArray[3].cno,            34.0, 1E-01  );
00635   CU_ASSERT_DOUBLE_EQUAL( obsArray[3].locktime,      9.969, 1E-03  );
00636   CU_ASSERT( obsArray[3].rawTrackingStatus == 0x01303c8b );
00637 
00638   //17,0,22350141.211,0.113,-118941422.934,0.006,-1355.281,46.0,70.625,08103ca4,
00639   CU_ASSERT( obsArray[4].prn == 17 );
00640   CU_ASSERT_DOUBLE_EQUAL( obsArray[4].psr,    22350141.211, 1E-03  );
00641   CU_ASSERT_DOUBLE_EQUAL( obsArray[4].psrstd,        0.113, 1E-03  );
00642   CU_ASSERT_DOUBLE_EQUAL( obsArray[4].adr,  -118941422.934, 1E-03  );
00643   CU_ASSERT_DOUBLE_EQUAL( obsArray[4].adrstd,        0.006, 1E-03  );
00644   CU_ASSERT_DOUBLE_EQUAL( obsArray[4].doppler,   -1355.281, 1E-03  );
00645   CU_ASSERT_DOUBLE_EQUAL( obsArray[4].cno,            46.0, 1E-01  );
00646   CU_ASSERT_DOUBLE_EQUAL( obsArray[4].locktime,     70.625, 1E-03  );
00647   CU_ASSERT( obsArray[4].rawTrackingStatus == 0x08103ca4 );
00648 
00649   //17,0,22350139.297,1.281,-92274772.922,0.004,-1056.062,37.0,32.000,00b03cab,
00650   CU_ASSERT( obsArray[5].prn == 17 );
00651   CU_ASSERT_DOUBLE_EQUAL( obsArray[5].psr,    22350139.297, 1E-03  );
00652   CU_ASSERT_DOUBLE_EQUAL( obsArray[5].psrstd,        1.281, 1E-03  );
00653   CU_ASSERT_DOUBLE_EQUAL( obsArray[5].adr,   -92274772.922, 1E-03  );
00654   CU_ASSERT_DOUBLE_EQUAL( obsArray[5].adrstd,        0.004, 1E-03  );
00655   CU_ASSERT_DOUBLE_EQUAL( obsArray[5].doppler,   -1056.062, 1E-03  );
00656   CU_ASSERT_DOUBLE_EQUAL( obsArray[5].cno,            37.0, 1E-01  );
00657   CU_ASSERT_DOUBLE_EQUAL( obsArray[5].locktime,     32.000, 1E-03  );
00658   CU_ASSERT( obsArray[5].rawTrackingStatus == 0x00b03cab );
00659 
00660   //24,0,22064710.016,0.169,-118834894.594,0.006,1487.938,46.0,47.125,08103cc4,
00661   CU_ASSERT( obsArray[6].prn == 24 );
00662   CU_ASSERT_DOUBLE_EQUAL( obsArray[6].psr,    22064710.016, 1E-03  );
00663   CU_ASSERT_DOUBLE_EQUAL( obsArray[6].psrstd,        0.169, 1E-03  );
00664   CU_ASSERT_DOUBLE_EQUAL( obsArray[6].adr,  -118834894.594, 1E-03  );
00665   CU_ASSERT_DOUBLE_EQUAL( obsArray[6].adrstd,        0.006, 1E-03  );
00666   CU_ASSERT_DOUBLE_EQUAL( obsArray[6].doppler,    1487.938, 1E-03  );
00667   CU_ASSERT_DOUBLE_EQUAL( obsArray[6].cno,            46.0, 1E-01  );
00668   CU_ASSERT_DOUBLE_EQUAL( obsArray[6].locktime,     47.125, 1E-03  );
00669   CU_ASSERT( obsArray[6].rawTrackingStatus == 0x08103cc4 );
00670 
00671   //24,0,22064709.539,1.281,-92230721.789,0.002,1159.430,37.0,23.875,00b03ccb,
00672   CU_ASSERT( obsArray[7].prn == 24 );
00673   CU_ASSERT_DOUBLE_EQUAL( obsArray[7].psr,    22064709.539, 1E-03  );
00674   CU_ASSERT_DOUBLE_EQUAL( obsArray[7].psrstd,        1.281, 1E-03  );
00675   CU_ASSERT_DOUBLE_EQUAL( obsArray[7].adr,   -92230721.789, 1E-03  );
00676   CU_ASSERT_DOUBLE_EQUAL( obsArray[7].adrstd,        0.002, 1E-03  );
00677   CU_ASSERT_DOUBLE_EQUAL( obsArray[7].doppler,    1159.430, 1E-03  );
00678   CU_ASSERT_DOUBLE_EQUAL( obsArray[7].cno,            37.0, 1E-01  );
00679   CU_ASSERT_DOUBLE_EQUAL( obsArray[7].locktime,     23.875, 1E-03  );
00680   CU_ASSERT( obsArray[7].rawTrackingStatus == 0x00b03ccb );
00681 
00682   //14,0,24722285.961,0.169,-127222786.973,0.008,1205.031,45.0,50.750,08103ce4,
00683   CU_ASSERT( obsArray[8].prn == 14 );
00684   CU_ASSERT_DOUBLE_EQUAL( obsArray[8].psr,    24722285.961, 1E-03  );
00685   CU_ASSERT_DOUBLE_EQUAL( obsArray[8].psrstd,        0.169, 1E-03  );
00686   CU_ASSERT_DOUBLE_EQUAL( obsArray[8].adr,  -127222786.973, 1E-03  );
00687   CU_ASSERT_DOUBLE_EQUAL( obsArray[8].adrstd,        0.008, 1E-03  );
00688   CU_ASSERT_DOUBLE_EQUAL( obsArray[8].doppler,    1205.031, 1E-03  );
00689   CU_ASSERT_DOUBLE_EQUAL( obsArray[8].cno,            45.0, 1E-01  );
00690   CU_ASSERT_DOUBLE_EQUAL( obsArray[8].locktime,     50.750, 1E-03  );
00691   CU_ASSERT( obsArray[8].rawTrackingStatus == 0x08103ce4 );
00692 
00693   //14,0,24722285.219,1.281,-100624117.871,0.002,938.984,36.0,23.875,00b03ceb,
00694   CU_ASSERT( obsArray[9].prn == 14 );
00695   CU_ASSERT_DOUBLE_EQUAL( obsArray[9].psr,    24722285.219, 1E-03  );
00696   CU_ASSERT_DOUBLE_EQUAL( obsArray[9].psrstd,        1.281, 1E-03  );
00697   CU_ASSERT_DOUBLE_EQUAL( obsArray[9].adr,  -100624117.871, 1E-03  );
00698   CU_ASSERT_DOUBLE_EQUAL( obsArray[9].adrstd,        0.002, 1E-03  );
00699   CU_ASSERT_DOUBLE_EQUAL( obsArray[9].doppler,     938.984, 1E-03  );
00700   CU_ASSERT_DOUBLE_EQUAL( obsArray[9].cno,            36.0, 1E-01  );
00701   CU_ASSERT_DOUBLE_EQUAL( obsArray[9].locktime,     23.875, 1E-03  );
00702   CU_ASSERT( obsArray[9].rawTrackingStatus == 0x00b03ceb );
00703 
00704   //23,0,24013490.914,0.113,-127006812.316,0.006,3146.312,45.0,71.781,08103d64,
00705   CU_ASSERT( obsArray[10].prn == 23 );
00706   CU_ASSERT_DOUBLE_EQUAL( obsArray[10].psr,    24013490.914, 1E-03  );
00707   CU_ASSERT_DOUBLE_EQUAL( obsArray[10].psrstd,        0.113, 1E-03  );
00708   CU_ASSERT_DOUBLE_EQUAL( obsArray[10].adr,  -127006812.316, 1E-03  );
00709   CU_ASSERT_DOUBLE_EQUAL( obsArray[10].adrstd,        0.006, 1E-03  );
00710   CU_ASSERT_DOUBLE_EQUAL( obsArray[10].doppler,    3146.312, 1E-03  );
00711   CU_ASSERT_DOUBLE_EQUAL( obsArray[10].cno,            45.0, 1E-01  );
00712   CU_ASSERT_DOUBLE_EQUAL( obsArray[10].locktime,     71.781, 1E-03  );
00713   CU_ASSERT( obsArray[10].rawTrackingStatus == 0x08103d64 );
00714   CU_ASSERT( obsArray[10].trackingStatus.eTrackingState == NOVATELOEM4_L1PhaseLockLoop );
00715   CU_ASSERT( obsArray[10].trackingStatus.channelNumber == 11 );
00716   CU_ASSERT( obsArray[10].trackingStatus.isPhaseLocked == TRUE );
00717   CU_ASSERT( obsArray[10].trackingStatus.isParityKnown == TRUE );
00718   CU_ASSERT( obsArray[10].trackingStatus.isCodeLocked == TRUE );
00719   CU_ASSERT( obsArray[10].trackingStatus.eCorrelatorSpacing == NOVATELOEM4_OneChipSpacing );
00720   CU_ASSERT( obsArray[10].trackingStatus.eSatelliteSystem == NOVATELOEM4_GPSSystem );
00721   CU_ASSERT( obsArray[10].trackingStatus.isGrouped == TRUE );
00722   CU_ASSERT( obsArray[10].trackingStatus.eFrequency == NOVATELOEM4_L1 );
00723   CU_ASSERT( obsArray[10].trackingStatus.eCodeType == NOVATELOEM4_CACode );
00724   CU_ASSERT( obsArray[10].trackingStatus.isFECEnabled == FALSE );
00725   CU_ASSERT( obsArray[10].trackingStatus.isPrimaryL1Channel == TRUE );
00726   CU_ASSERT( obsArray[10].trackingStatus.isHalfCycleAdded == FALSE );
00727   CU_ASSERT( obsArray[10].trackingStatus.isForcedAssignment == FALSE );
00728 
00729 
00730   //23,0,24013488.539,1.281,-100545474.879,0.004,2451.668,36.0,33.500,00b03d6b
00731   CU_ASSERT( obsArray[11].prn == 23 );
00732   CU_ASSERT_DOUBLE_EQUAL( obsArray[11].psr,    24013488.539, 1E-03  );
00733   CU_ASSERT_DOUBLE_EQUAL( obsArray[11].psrstd,        1.281, 1E-03  );
00734   CU_ASSERT_DOUBLE_EQUAL( obsArray[11].adr,  -100545474.879, 1E-03  );
00735   CU_ASSERT_DOUBLE_EQUAL( obsArray[11].adrstd,        0.004, 1E-03  );
00736   CU_ASSERT_DOUBLE_EQUAL( obsArray[11].doppler,    2451.668, 1E-03  );
00737   CU_ASSERT_DOUBLE_EQUAL( obsArray[11].cno,            36.0, 1E-01  );
00738   CU_ASSERT_DOUBLE_EQUAL( obsArray[11].locktime,     33.500, 1E-03  );
00739   CU_ASSERT( obsArray[11].rawTrackingStatus == 0x00b03d6b );
00740   CU_ASSERT( obsArray[11].trackingStatus.eTrackingState == NOVATELOEM4_L2PhaseLockLoop );
00741   CU_ASSERT( obsArray[11].trackingStatus.channelNumber == 11 );
00742   CU_ASSERT( obsArray[11].trackingStatus.isPhaseLocked == TRUE );
00743   CU_ASSERT( obsArray[11].trackingStatus.isParityKnown == TRUE );
00744   CU_ASSERT( obsArray[11].trackingStatus.isCodeLocked == TRUE );
00745   CU_ASSERT( obsArray[11].trackingStatus.eCorrelatorSpacing == NOVATELOEM4_OneChipSpacing );
00746   CU_ASSERT( obsArray[11].trackingStatus.eSatelliteSystem == NOVATELOEM4_GPSSystem );
00747   CU_ASSERT( obsArray[11].trackingStatus.isGrouped == TRUE );
00748   CU_ASSERT( obsArray[11].trackingStatus.eFrequency == NOVATELOEM4_L2 );
00749   CU_ASSERT( obsArray[11].trackingStatus.eCodeType == NOVATELOEM4_PCode );
00750   CU_ASSERT( obsArray[11].trackingStatus.isFECEnabled == FALSE );
00751   CU_ASSERT( obsArray[11].trackingStatus.isPrimaryL1Channel == FALSE );
00752   CU_ASSERT( obsArray[11].trackingStatus.isHalfCycleAdded == FALSE );
00753   CU_ASSERT( obsArray[11].trackingStatus.isForcedAssignment == FALSE );
00754 
00755 }
00756 
00757 
00758 
00759 
00760 void test_NOVATELOEM4_DecodeRAWEPHEMB(void)
00761 {
00762   FILE *fid = NULL;
00763   BOOL result = FALSE;
00764   unsigned char message[8192];
00765   BOOL wasMessageFound = FALSE;
00766   BOOL wasEndOfFileReached = FALSE;
00767   unsigned filePosition = 0;
00768   unsigned short messageLength = 0;
00769   unsigned short messageID = 0;
00770   unsigned numberBadCRC = 0;
00771   unsigned reference_week;
00772   unsigned reference_time;
00773   unsigned prn;
00774   unsigned tow;
00775   unsigned i = 0;
00776   GPS_structEphemeris ephArray[128]; // an array of GPS ephemeris
00777   NOVATELOEM4_structBinaryHeader header;  
00778 
00779   result = fopen_s( &fid, "rawephemb.bin", "rb" );
00780   CU_ASSERT_FATAL( result == 0 );
00781 
00782   if( result == 0 )
00783     return;
00784 
00785   while( !wasEndOfFileReached && i < 128 )
00786   {
00787     result = NOVATELOEM4_FindNextMessageInFile(
00788       fid,
00789       message,
00790       8192, 
00791       &wasEndOfFileReached,
00792       &wasMessageFound,
00793       &filePosition,
00794       &messageLength,
00795       &messageID,
00796       &numberBadCRC );
00797     CU_ASSERT( result );
00798 
00799     if( messageID == 41 ) // RAWEPHEMB
00800     {
00801       result = NOVATELOEM4_DecodeRAWEPHEMB(
00802         message,
00803         messageLength,
00804         &header,
00805         &prn,
00806         &reference_week,
00807         &reference_time,
00808         &tow,
00809         &ephArray[i].iodc,
00810         &ephArray[i].iode,  
00811         &ephArray[i].toe,   
00812         &ephArray[i].toc,   
00813         &ephArray[i].week,  
00814         &ephArray[i].health,
00815         &ephArray[i].alert_flag,
00816         &ephArray[i].anti_spoof,
00817         &ephArray[i].code_on_L2,
00818         &ephArray[i].ura,       
00819         &ephArray[i].L2_P_data_flag,
00820         &ephArray[i].fit_interval_flag,
00821         &ephArray[i].age_of_data_offset, 
00822         &ephArray[i].tgd,                
00823         &ephArray[i].af2,                
00824         &ephArray[i].af1,                
00825         &ephArray[i].af0,                
00826         &ephArray[i].m0,                
00827         &ephArray[i].delta_n,           
00828         &ephArray[i].ecc,               
00829         &ephArray[i].sqrta,             
00830         &ephArray[i].omega0,            
00831         &ephArray[i].i0,                
00832         &ephArray[i].w,                 
00833         &ephArray[i].omegadot,          
00834         &ephArray[i].idot,              
00835         &ephArray[i].cuc,               
00836         &ephArray[i].cus,               
00837         &ephArray[i].crc,               
00838         &ephArray[i].crs,               
00839         &ephArray[i].cic,               
00840         &ephArray[i].cis                
00841         );
00842       CU_ASSERT( result );
00843       ephArray[i].prn = (unsigned short)prn;
00844 
00845       if( i == 0 )
00846       {
00847         CU_ASSERT( ephArray[i].prn == 14 );
00848         CU_ASSERT( reference_week == 1186 );
00849         CU_ASSERT( reference_time == 50384 );
00850         CU_ASSERT( ephArray[i].iodc == 160 );
00851         CU_ASSERT( ephArray[i].iode == 160 );
00852         CU_ASSERT( ephArray[i].toe == 50384 );
00853         CU_ASSERT( ephArray[i].toc == 50384 );   
00854         CU_ASSERT( ephArray[i].week == 162 );
00855         CU_ASSERT( ephArray[i].health == 0 );
00856         CU_ASSERT( ephArray[i].alert_flag == 0 );
00857         CU_ASSERT( ephArray[i].anti_spoof == 1 );
00858         CU_ASSERT( ephArray[i].code_on_L2 == 1 );
00859         CU_ASSERT( ephArray[i].ura == 0 );
00860         CU_ASSERT( ephArray[i].L2_P_data_flag == 0 );
00861         CU_ASSERT( ephArray[i].fit_interval_flag == 0 );
00862         CU_ASSERT( ephArray[i].age_of_data_offset == 7200 );
00863         CU_ASSERT_DOUBLE_EQUAL( ephArray[i].tgd, -1.024455e-008, 1E-14 );
00864         CU_ASSERT_DOUBLE_EQUAL( ephArray[i].af2, 0.0, 1E-03 );               
00865         CU_ASSERT_DOUBLE_EQUAL( ephArray[i].af1, 1.591616e-012, 1E-18 );        
00866         CU_ASSERT_DOUBLE_EQUAL( ephArray[i].af0, -4.7015957e-005, 1E-11 ); 
00867         CU_ASSERT_DOUBLE_EQUAL( ephArray[i].m0, 1.251492, 1E-06 );
00868         CU_ASSERT_DOUBLE_EQUAL( ephArray[i].delta_n, 4.296965e-009, 1E-15 );
00869         CU_ASSERT_DOUBLE_EQUAL( ephArray[i].ecc, 1.542772e-003, 1E-09 );
00870         CU_ASSERT_DOUBLE_EQUAL( ephArray[i].sqrta, 5.153621e+003, 1E-03 );
00871         CU_ASSERT_DOUBLE_EQUAL( ephArray[i].omega0, 1.199630, 1E-06 );
00872         CU_ASSERT_DOUBLE_EQUAL( ephArray[i].i0, 9.692661e-001, 1E-07 );
00873         CU_ASSERT_DOUBLE_EQUAL( ephArray[i].w, -7.577131e-001, 1E-07 );
00874         CU_ASSERT_DOUBLE_EQUAL( ephArray[i].omegadot, -7.920330e-009, 1E-15 );
00875         CU_ASSERT_DOUBLE_EQUAL( ephArray[i].idot, 1.221479e-010, 1E-16 );
00876         CU_ASSERT_DOUBLE_EQUAL( ephArray[i].cuc, -4.442409e-006, 1E-12 );
00877         CU_ASSERT_DOUBLE_EQUAL( ephArray[i].cus, 7.834285e-006, 1E-12 );
00878         CU_ASSERT_DOUBLE_EQUAL( ephArray[i].crc, 2.326875e+002, 1E-04 ); 
00879         CU_ASSERT_DOUBLE_EQUAL( ephArray[i].crs, -8.746875e+001, 1E-05 );
00880         CU_ASSERT_DOUBLE_EQUAL( ephArray[i].cic, 3.166497e-008, 1E-14 );
00881         CU_ASSERT_DOUBLE_EQUAL( ephArray[i].cis, -1.303852e-008, 1E-14 );
00882       }
00883       i++;
00884     }
00885   }
00886   if( fid == NULL )
00887     fclose( fid );
00888 }