00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 #include <stdio.h>
00040 #include <string.h>
00041 #include <ctype.h>
00042 #include <memory.h>
00043 #include <math.h>
00044 #include "rinex.h"
00045 #include "time_conversion.h"
00046 #include "constants.h"
00047 
00048 #define RINEX_HEADER_SIZE (32768) 
00049 #define RINEX_LINEBUF_SIZE (8192) 
00050 #define RINEX_MAX_NR_SATS    (64) 
00051 #define RINEX_MAX_NR_OBS     (64) 
00052 
00053 
00054 
00055 static const double RINEX_MIN_URA[16] = {0.00, 2.40, 3.40, 4.85, 6.85,  9.65, 13.65, 24.00, 48.00, 96.00, 192.00, 384.00,  768.00, 1536.00, 3072.00, 6144.00};
00056 static const double RINEX_MAX_URA[16] = {2.40, 3.40, 4.85, 6.85, 9.65, 13.65, 24.00, 48.00, 96.00, 192.0, 384.00, 768.00, 1536.00, 3072.00, 6144.00, 1.0e100};
00057 
00058 
00059 
00060 
00061 typedef struct
00062 {
00063   unsigned char loss_of_lock_indicator; 
00064   unsigned char signal_strength;        
00065   double value;                         
00066   RINEX_enumObservationType type;       
00067   GNSS_enumSystem system;               
00068   unsigned short id;                    
00069   BOOL isValid;                         
00070 } struct_RINEX_obs;
00071 
00072 
00073 typedef struct
00074 {
00075   RINEX_enumSatelliteSystemType type;
00076   unsigned short id;
00077 } struct_RINEX_satellite;
00078 
00079 
00080 
00081 static BOOL RINEX_trim_left_right(
00082   char* str,            
00083   unsigned max_length,  
00084   unsigned *str_length  
00085   );
00086 
00087 
00088 static BOOL RINEX_get_header_lines(
00089   const char* header,              
00090   const unsigned header_size,      
00091   const char* record_desciptor,    
00092   char* lines_buffer,              
00093   const unsigned max_lines_buffer, 
00094   unsigned* nr_lines               
00095   );
00096 
00097 
00098 static BOOL RINEX_erase(
00099   char *erase_me, 
00100   char* str       
00101   ); 
00102  
00103 
00104 static BOOL RINEX_GetObservationTypes(
00105   const char* header_buffer,          
00106   const unsigned header_buffer_size,  
00107   RINEX_structDecodedHeader* header   
00108   );
00109 
00110 
00111 
00112 
00113 
00114 static BOOL RINEX_DealWithSpecialRecords(
00115   FILE* fid,                               
00116   RINEX_structDecodedHeader* RINEX_header, 
00117   BOOL *wasEndOfFileReached,               
00118   unsigned *filePosition,                  
00119   const unsigned nr_special_records        
00120   );
00121 
00122 
00123 static BOOL RINEX_GetNextObserationSetForOneSatellite(
00124   FILE* fid,                                   
00125   RINEX_structDecodedHeader* RINEX_header,     
00126   BOOL *wasEndOfFileReached,                   
00127   unsigned *filePosition,                      
00128   struct_RINEX_obs* RINEX_obs,                 
00129   const unsigned RINEX_max_nr_obs,             
00130   unsigned *RINEX_nr_obs,                      
00131   const RINEX_enumSatelliteSystemType sattype, 
00132   const unsigned short id                      
00133   );
00134 
00135 
00136 static BOOL RINEX_ReplaceDwithE( char *str, const unsigned length );
00137 
00138 
00139 
00140 
00141 
00142 
00143 
00144 
00145 
00146 static BOOL RINEX_ConvertURA_meters_to_URA_index( 
00147   double ura_m,         
00148   unsigned char *ura    
00149   );
00150 
00151 
00152 
00153 
00154 
00155 
00156 
00157 
00158 
00159 
00160 
00161 
00162 
00163 
00164 
00165 static BOOL RINEX_ConvertSignalStrengthToUsableCNo(
00166   float *cno,  
00167   const unsigned char signal_strength
00168   );
00169   
00170 
00171 
00172 BOOL RINEX_trim_left_right(
00173   char* str,            
00174   unsigned max_length,  
00175   unsigned *str_length  
00176   )
00177 {
00178   int i = 0;
00179   int j = 0;
00180   int start = 0;
00181   size_t length = 0;
00182   if( str == NULL )
00183     return FALSE;
00184   if( str_length == NULL )
00185     return FALSE;
00186 
00187   
00188   length = strlen( str );
00189   if( length > max_length )
00190     return FALSE;
00191   if( length == 0 )
00192     return TRUE;
00193 
00194   for( i = 0; i < (int)length; i++ )
00195   {
00196     if( isspace(str[i]) )
00197       continue;
00198     else
00199       break;
00200   }
00201   start = i;
00202   i = 0;
00203   for( j = start; j < (int)length; j++ )
00204   {
00205     str[i] = str[j];
00206     i++;
00207   }
00208   str[i] = '\0';
00209 
00210   
00211   length = strlen( str );
00212   for( i = (int)(length-1); i > 0; i-- )
00213   {
00214     if( isspace(str[i]) )
00215     {
00216       str[i] = '\0';
00217     }      
00218     else
00219     {
00220       break;
00221     }
00222   }
00223 
00224   length = strlen( str );
00225   *str_length = (unsigned)length;
00226   
00227   return TRUE;
00228 }
00229 
00230 
00231 BOOL RINEX_get_header_lines(
00232   const char* header_buffer,       
00233   const unsigned header_size,      
00234   const char* record_desciptor,    
00235   char* lines_buffer,              
00236   const unsigned max_lines_buffer, 
00237   unsigned* nr_lines               
00238   )
00239 {
00240   char *pch = NULL;
00241   char *strptr = NULL;
00242   unsigned i = 0;
00243   int j = 0;
00244   int record_descriptor_index = 0;
00245   int scount = 0;
00246   unsigned nr_valid_header_lines = 0;
00247   size_t length_record_desciptor = 0;
00248   
00249   typedef struct
00250   {
00251     char str[128]; 
00252     size_t length;
00253   } struct_header_line_token;
00254 
00255   struct_header_line_token token[256];
00256   char buffer[RINEX_HEADER_SIZE];
00257 
00258   if( header_buffer == NULL )
00259     return FALSE;
00260   if( header_size == 0 )
00261     return FALSE;
00262   if( record_desciptor == NULL )
00263     return FALSE;
00264   if( lines_buffer == NULL )
00265     return FALSE;
00266   if( nr_lines == NULL )
00267     return FALSE;
00268 
00269   if( header_size+1 > RINEX_HEADER_SIZE )
00270     return FALSE;
00271 
00272   memcpy( buffer, header_buffer, header_size );
00273   buffer[header_size] = '\0';
00274 
00275   *nr_lines = 0;
00276 
00277   length_record_desciptor = strlen( record_desciptor );
00278   if( length_record_desciptor == 0 )
00279     return FALSE;
00280 
00281   strptr = strstr( header_buffer, record_desciptor );
00282   if( strptr == NULL )
00283     return TRUE; 
00284 
00285   
00286   pch = strtok( buffer,"\r\n");
00287   while( pch != NULL )
00288   {
00289     strptr = strstr( pch, record_desciptor );
00290     if( strptr != NULL )
00291     {
00292       token[i].length = strlen( pch );
00293       if( token[i].length < 128 )
00294       {
00295         strcpy( token[i].str, pch );
00296         i++;
00297       }
00298     }
00299     pch = strtok (NULL, "\r\n");
00300   }
00301   nr_valid_header_lines = i;
00302 
00303   if( nr_valid_header_lines == 0 )
00304     return FALSE;
00305 
00306   
00307   for( i = 0; i < nr_valid_header_lines; i++ )
00308   {
00309     strptr = strstr( token[i].str, record_desciptor );
00310     if( strptr != NULL )
00311     {
00312       
00313       record_descriptor_index = (int)(strptr - token[i].str);
00314 
00315       if( record_descriptor_index != 60 )
00316       {
00317         
00318         
00319         
00320 
00321         if( strcmp( record_desciptor, "COMMENT" ) == 0 )
00322         {
00323           
00324           
00325         }
00326         else
00327         {
00328           
00329           strptr = strstr( token[i].str, "COMMENT" );
00330           if( strptr != NULL )
00331           {
00332             j = (int)(strptr - token[i].str);
00333             if( j == 60 )
00334             {
00335               
00336               continue;
00337             }
00338             else
00339             {
00340               
00341               continue;
00342             }
00343           }
00344           else
00345           {
00346             
00347             if( record_descriptor_index > 55 && record_descriptor_index < 65 )
00348             {
00349               
00350             }
00351             else
00352             {
00353               
00354               continue;
00355             }
00356           }
00357         }
00358       }
00359 
00360       
00361       if( (scount + token[i].length + 1) >= max_lines_buffer )
00362         return FALSE;
00363 
00364       scount += sprintf( lines_buffer+scount, "%s\n", token[i].str );
00365       *nr_lines += 1;
00366     }
00367   }  
00368   return TRUE;
00369 }
00370 
00371 
00372 BOOL RINEX_erase(
00373   char *erase_me, 
00374   char* str       
00375   )
00376 {
00377   int i = 0;
00378   int j = 0;
00379   char *strptr = NULL;
00380   size_t len = 0;
00381   size_t len_erase_me = 0;
00382 
00383   if( erase_me == NULL )
00384     return FALSE;
00385   if( str == NULL )
00386     return FALSE;
00387   
00388   len_erase_me = strlen( erase_me );
00389   if( len_erase_me == 0 )
00390     return TRUE;
00391 
00392   len = strlen(str);
00393   if( len == 0 )
00394     return TRUE;
00395 
00396   if( len_erase_me > len )
00397     return TRUE;
00398 
00399   strptr = strstr( str, erase_me );
00400   
00401   while( strptr != NULL )
00402   {
00403     j = (int)(strptr - str);   
00404     i = j + (int)len_erase_me; 
00405 
00406     for( i; i < (int)len; i++ )
00407     {
00408       str[j] = str[i];
00409       if( str[j] == '\0' )
00410         break;
00411       j++;
00412     }
00413     str[j] = '\0';
00414     len = strlen(str);  
00415 
00416     strptr = strstr( str, erase_me );
00417   }
00418   return TRUE;
00419 }
00420 
00421 
00422 
00423 BOOL RINEX_GetObservationTypes(
00424   const char* header_buffer,          
00425   const unsigned header_buffer_size,  
00426   RINEX_structDecodedHeader* header   
00427   )
00428 {
00429   char lines_buffer[RINEX_LINEBUF_SIZE];
00430   unsigned nr_lines = 0;
00431   BOOL result;
00432   char *pch = NULL;
00433   unsigned count = 0;
00434   char token[128];
00435   unsigned len=0;
00436   BOOL isFirst = TRUE;
00437   
00438   result = RINEX_get_header_lines(
00439     header_buffer,
00440     header_buffer_size,
00441     "# / TYPES OF OBSERV",
00442     lines_buffer,
00443     RINEX_LINEBUF_SIZE,
00444     &nr_lines
00445     );
00446   if( result == FALSE )
00447     return FALSE;  
00448   
00449   result = RINEX_erase( "# / TYPES OF OBSERV", lines_buffer );
00450   if( result == FALSE )
00451     return FALSE;
00452   
00453   
00454   if( sscanf( lines_buffer, "%u", &(header->nr_obs_types) ) != 1 )
00455     return FALSE;
00456   
00457   
00458   result = RINEX_trim_left_right( lines_buffer, RINEX_LINEBUF_SIZE, &len );
00459   if( result == FALSE )
00460     return FALSE;
00461 
00462   
00463   pch = strtok( lines_buffer, " \t\r\n\f" );
00464   while( pch != NULL && count < header->nr_obs_types )
00465   {
00466     if( !isFirst )
00467     {
00468       strcpy( token, pch );
00469       result = RINEX_trim_left_right( token, 128, &len );
00470       if( result == FALSE )
00471         return FALSE;
00472       if( strlen(token) > 0 )
00473       {
00474         if( strcmp( token, "L1" ) == 0 )
00475           header->obs_types[count] =  RINEX_OBS_TYPE_L1;
00476         else if( strcmp( token, "L2" ) == 0 )
00477           header->obs_types[count] =  RINEX_OBS_TYPE_L2;
00478         else if( strcmp( token, "C1" ) == 0 )
00479           header->obs_types[count] =  RINEX_OBS_TYPE_C1;
00480         else if( strcmp( token, "P1" ) == 0 )
00481           header->obs_types[count] =  RINEX_OBS_TYPE_P1;
00482         else if( strcmp( token, "P2" ) == 0 )
00483           header->obs_types[count] =  RINEX_OBS_TYPE_P2;
00484         else if( strcmp( token, "D1" ) == 0 )
00485           header->obs_types[count] =  RINEX_OBS_TYPE_D1;
00486         else if( strcmp( token, "D2" ) == 0 )
00487           header->obs_types[count] =  RINEX_OBS_TYPE_D2;
00488         else if( strcmp( token, "T1" ) == 0 )
00489           header->obs_types[count] =  RINEX_OBS_TYPE_T1;
00490         else if( strcmp( token, "T2" ) == 0 )
00491           header->obs_types[count] =  RINEX_OBS_TYPE_T2;
00492         else if( strcmp( token, "S1" ) == 0 )
00493           header->obs_types[count] =  RINEX_OBS_TYPE_S1;
00494         else if( strcmp( token, "S2" ) == 0 )
00495           header->obs_types[count] =  RINEX_OBS_TYPE_S2;
00496         else
00497           header->obs_types[count] =  RINEX_OBS_TYPE_UNKNOWN;
00498 
00499         count++;
00500       }
00501     }
00502     pch = strtok (NULL, " ,.-");    
00503     isFirst = FALSE;
00504   }
00505 
00506   if( count != header->nr_obs_types )
00507     return FALSE;
00508 
00509   return TRUE;
00510 }
00511 
00512 
00513 BOOL RINEX_DealWithSpecialRecords(
00514   FILE* fid,                               
00515   RINEX_structDecodedHeader* RINEX_header, 
00516   BOOL *wasEndOfFileReached,               
00517   unsigned *filePosition,                  
00518   const unsigned nr_special_records        
00519   )
00520 {
00521   char line_buffer[RINEX_LINEBUF_SIZE];
00522   BOOL result = FALSE;
00523   size_t length = 0;
00524   unsigned i = 0;
00525 
00526   if( fid == NULL )
00527     return FALSE;
00528   if( RINEX_header == NULL )
00529     return FALSE;
00530   if( wasEndOfFileReached == NULL )
00531     return FALSE;
00532   if( filePosition == NULL )
00533     return FALSE;
00534 
00535   
00536   if( nr_special_records == 0 )
00537     return TRUE;
00538 
00539   for( i = 0; i < nr_special_records; i++ )
00540   {
00541 
00542     if( fgets( line_buffer, RINEX_LINEBUF_SIZE, fid ) == NULL )
00543     {
00544       if( feof(fid) )
00545       {
00546         *wasEndOfFileReached = TRUE;
00547         return TRUE;
00548       }
00549       else
00550       {
00551         return FALSE;
00552       }
00553     }
00554     *filePosition = ftell(fid);
00555 
00556     if( strstr(line_buffer, "COMMENT") != NULL )
00557     {
00558       
00559     }
00560     else if( strstr(line_buffer, "WAVELENGTH FACT L1/2") != NULL )
00561     {
00562       
00563 
00564       
00565     }
00566     else if( strstr(line_buffer, "MARKER NAME") != NULL )
00567     {
00568       
00569       result = RINEX_erase("MARKER NAME", line_buffer);
00570       if( result == FALSE )
00571         return FALSE;
00572       result = RINEX_trim_left_right(line_buffer, RINEX_LINEBUF_SIZE, &length );
00573       if( result == FALSE )
00574         return FALSE;
00575       if( length < 64 )
00576       {
00577         strcpy(RINEX_header->marker_name, line_buffer);
00578       }
00579       else
00580       {
00581         return FALSE;
00582       }
00583     }
00584     else if( strstr(line_buffer, "MARKER NUMBER") != NULL )
00585     {
00586       
00587     }
00588     else if( strstr(line_buffer, "ANTENNA: DELTA H/E/N") != NULL )
00589     {
00590       if( sscanf( line_buffer, "%Lf %Lf %Lf", 
00591         &(RINEX_header->antenna_delta_h), 
00592         &(RINEX_header->antenna_ecc_e), 
00593         &(RINEX_header->antenna_ecc_n) ) != 3 )
00594       {
00595         return FALSE;
00596       }
00597     }
00598     else if( strstr(line_buffer, "APPROX POSITION XYZ") != NULL )
00599     {
00600       if( sscanf( line_buffer, "%Lf %Lf %Lf", 
00601         &(RINEX_header->x), 
00602         &(RINEX_header->y), 
00603         &(RINEX_header->z) ) != 3 )
00604       {
00605         return FALSE;
00606       }
00607     }
00608     else 
00609     {
00610       
00611     }
00612   }
00613   return TRUE;
00614 }
00615 
00616 
00617 
00618 BOOL RINEX_GetNextObserationSetForOneSatellite(
00619   FILE* fid,                                   
00620   RINEX_structDecodedHeader* RINEX_header,     
00621   BOOL *wasEndOfFileReached,                   
00622   unsigned *filePosition,                      
00623   struct_RINEX_obs* RINEX_obs,                 
00624   const unsigned RINEX_max_nr_obs,             
00625   unsigned *RINEX_nr_obs,                      
00626   const RINEX_enumSatelliteSystemType sattype, 
00627   const unsigned short id                      
00628   )
00629 {
00630   unsigned i = 0;
00631   char line_buffer[RINEX_LINEBUF_SIZE];
00632   unsigned count = 0;
00633   char str_a[15];
00634   char str_b[15];
00635   char str_c[15];
00636   char str_d[15];
00637   char str_e[15];
00638 
00639   memset( str_a, 0, 15 );
00640   memset( str_b, 0, 15 );
00641   memset( str_c, 0, 15 );
00642   memset( str_d, 0, 15 );
00643   memset( str_e, 0, 15 );
00644 
00645   
00646   if( fid == NULL )
00647     return FALSE;
00648   if( RINEX_header == NULL )
00649     return FALSE;
00650   if( wasEndOfFileReached == NULL )
00651     return FALSE;
00652   if( filePosition == NULL )
00653     return FALSE;
00654   if( RINEX_obs == NULL )
00655     return FALSE;
00656   if( RINEX_max_nr_obs == 0 )
00657     return FALSE;
00658   if( RINEX_nr_obs == NULL )
00659     return FALSE;
00660   if( RINEX_header->nr_obs_types >= RINEX_max_nr_obs )
00661     return FALSE;
00662 
00663 
00664   
00665   if( fgets(line_buffer, RINEX_LINEBUF_SIZE, fid) == NULL )
00666   {
00667     if( feof(fid) )
00668     {
00669       *wasEndOfFileReached = TRUE;
00670       return TRUE;
00671     }
00672     else
00673     {
00674       return FALSE;
00675     }
00676   }
00677   *filePosition = ftell(fid);
00678 
00679   
00680   memset( RINEX_obs, 0, sizeof(struct_RINEX_obs)*RINEX_header->nr_obs_types );
00681 
00682   switch( RINEX_header->nr_obs_types )
00683   {
00684   case 1:
00685     {
00686       count = sscanf( line_buffer, "%14c%c%c", 
00687         str_a,
00688         &RINEX_obs[0].loss_of_lock_indicator, 
00689         &RINEX_obs[0].signal_strength
00690         );        
00691       sscanf( str_a, "%Lf", &(RINEX_obs[0].value) );
00692       break;
00693     }
00694   case 2:
00695     {
00696       count = sscanf( line_buffer, "%14c%c%c%14c%c%c", 
00697         str_a,
00698         &RINEX_obs[0].loss_of_lock_indicator, 
00699         &RINEX_obs[0].signal_strength,
00700         str_b,
00701         &RINEX_obs[1].loss_of_lock_indicator, 
00702         &RINEX_obs[1].signal_strength 
00703         );
00704       sscanf( str_a, "%Lf", &(RINEX_obs[0].value) );
00705       sscanf( str_b, "%Lf", &(RINEX_obs[1].value) );
00706       break;
00707     }
00708   case 3:
00709     {
00710       count = sscanf( line_buffer, "%14c%c%c%14c%c%c%14c%c%c", 
00711         str_a,
00712         &RINEX_obs[0].loss_of_lock_indicator, 
00713         &RINEX_obs[0].signal_strength,
00714         str_b,
00715         &RINEX_obs[1].loss_of_lock_indicator, 
00716         &RINEX_obs[1].signal_strength,
00717         str_c,
00718         &RINEX_obs[2].loss_of_lock_indicator, 
00719         &RINEX_obs[2].signal_strength
00720       );
00721       sscanf( str_a, "%Lf", &(RINEX_obs[0].value) );
00722       sscanf( str_b, "%Lf", &(RINEX_obs[1].value) );
00723       sscanf( str_c, "%Lf", &(RINEX_obs[2].value) );      
00724       break;
00725     }
00726   case 4:
00727     {
00728       count = sscanf( line_buffer, "%14c%c%c%14c%c%c%14c%c%c%14c%c%c", 
00729         str_a, 
00730         &RINEX_obs[0].loss_of_lock_indicator, 
00731         &RINEX_obs[0].signal_strength,
00732         str_b, 
00733         &RINEX_obs[1].loss_of_lock_indicator, 
00734         &RINEX_obs[1].signal_strength,
00735         str_c, 
00736         &RINEX_obs[2].loss_of_lock_indicator, 
00737         &RINEX_obs[2].signal_strength,
00738         str_d, 
00739         &RINEX_obs[3].loss_of_lock_indicator, 
00740         &RINEX_obs[3].signal_strength
00741       );
00742       sscanf( str_a, "%Lf", &(RINEX_obs[0].value) );
00743       sscanf( str_b, "%Lf", &(RINEX_obs[1].value) );
00744       sscanf( str_c, "%Lf", &(RINEX_obs[2].value) );
00745       sscanf( str_d ,"%Lf", &(RINEX_obs[3].value) );
00746       break;
00747     }
00748     case 5:
00749     {
00750       count = sscanf( line_buffer, "%14Lf%c%c%14Lf%c%c%14Lf%c%c%14Lf%c%c%14Lf%c%c", 
00751         str_a,
00752         &RINEX_obs[0].loss_of_lock_indicator, 
00753         &RINEX_obs[0].signal_strength,
00754         str_b,
00755         &RINEX_obs[1].loss_of_lock_indicator, 
00756         &RINEX_obs[1].signal_strength,
00757         str_c,
00758         &RINEX_obs[2].loss_of_lock_indicator, 
00759         &RINEX_obs[2].signal_strength,
00760         str_d,
00761         &RINEX_obs[3].loss_of_lock_indicator, 
00762         &RINEX_obs[3].signal_strength,
00763         str_e,
00764         &RINEX_obs[4].loss_of_lock_indicator, 
00765         &RINEX_obs[4].signal_strength
00766       );
00767       sscanf( str_a, "%Lf", &(RINEX_obs[0].value) );
00768       sscanf( str_b, "%Lf", &(RINEX_obs[1].value) );
00769       sscanf( str_c, "%Lf", &(RINEX_obs[2].value) );
00770       sscanf( str_d ,"%Lf", &(RINEX_obs[3].value) );
00771       sscanf( str_e ,"%Lf", &(RINEX_obs[4].value) );      
00772       break;
00773     }
00774     case 6:
00775     case 7:
00776     case 8:
00777     case 9:
00778     case 10: 
00779     {
00780 
00781       count = sscanf( line_buffer, "%14c%c%c%14c%c%c%14c%c%c%14c%c%c%14c%c%c", 
00782         str_a, 
00783         &RINEX_obs[0].loss_of_lock_indicator, 
00784         &RINEX_obs[0].signal_strength,
00785         str_b, 
00786         &RINEX_obs[1].loss_of_lock_indicator, 
00787         &RINEX_obs[1].signal_strength,
00788         str_c, 
00789         &RINEX_obs[2].loss_of_lock_indicator, 
00790         &RINEX_obs[2].signal_strength,
00791         str_d, 
00792         &RINEX_obs[3].loss_of_lock_indicator, 
00793         &RINEX_obs[3].signal_strength,
00794         str_e, 
00795         &RINEX_obs[4].loss_of_lock_indicator, 
00796         &RINEX_obs[4].signal_strength
00797       );
00798       sscanf( str_a, "%Lf", &(RINEX_obs[0].value) );
00799       sscanf( str_b, "%Lf", &(RINEX_obs[1].value) );
00800       sscanf( str_c, "%Lf", &(RINEX_obs[2].value) );
00801       sscanf( str_d ,"%Lf", &(RINEX_obs[3].value) );
00802       sscanf( str_e ,"%Lf", &(RINEX_obs[4].value) );      
00803 
00804       memset( str_a, 0, 15 );
00805       memset( str_b, 0, 15 );
00806       memset( str_c, 0, 15 );
00807       memset( str_d, 0, 15 );
00808       memset( str_e, 0, 15 );
00809       
00810       
00811       if( fgets(line_buffer, RINEX_LINEBUF_SIZE, fid) == NULL )
00812       {
00813         if( feof(fid) )
00814         {
00815           *wasEndOfFileReached = TRUE;
00816           return TRUE;
00817         }
00818         else
00819         {
00820           return FALSE;
00821         }      
00822       }
00823 
00824       switch( RINEX_header->nr_obs_types-5 )
00825       {
00826       case 1:
00827         {
00828           count = sscanf( line_buffer, "%14c%c%c", 
00829             str_a, 
00830             &RINEX_obs[5].loss_of_lock_indicator, 
00831             &RINEX_obs[5].signal_strength
00832             );        
00833           sscanf( str_a, "%Lf", &(RINEX_obs[5].value) );
00834           break;
00835         }
00836       case 2:
00837         {
00838           count = sscanf( line_buffer, "%14c%c%c%14c%c%c", 
00839             str_a, 
00840             &RINEX_obs[5].loss_of_lock_indicator, 
00841             &RINEX_obs[5].signal_strength,
00842             str_b, 
00843             &RINEX_obs[6].loss_of_lock_indicator, 
00844             &RINEX_obs[6].signal_strength 
00845             );
00846           sscanf( str_a, "%Lf", &(RINEX_obs[5].value) );
00847           sscanf( str_b, "%Lf", &(RINEX_obs[6].value) );          
00848           break;
00849         }
00850       case 3:
00851         {
00852           count = sscanf( line_buffer, "%14c%c%c%14c%c%c%14c%c%c", 
00853             str_a, 
00854             &RINEX_obs[5].loss_of_lock_indicator, 
00855             &RINEX_obs[5].signal_strength,
00856             str_b, 
00857             &RINEX_obs[6].loss_of_lock_indicator, 
00858             &RINEX_obs[6].signal_strength,
00859             str_c, 
00860             &RINEX_obs[7].loss_of_lock_indicator, 
00861             &RINEX_obs[7].signal_strength
00862             );
00863           sscanf( str_a, "%Lf", &(RINEX_obs[5].value) );
00864           sscanf( str_b, "%Lf", &(RINEX_obs[6].value) );
00865           sscanf( str_c, "%Lf", &(RINEX_obs[7].value) );          
00866           break;
00867         }
00868       case 4:
00869         {
00870           count = sscanf( line_buffer, "%14c%c%c%14c%c%c%14c%c%c%14c%c%c", 
00871             str_a, 
00872             &RINEX_obs[5].loss_of_lock_indicator, 
00873             &RINEX_obs[5].signal_strength,
00874             str_b, 
00875             &RINEX_obs[6].loss_of_lock_indicator, 
00876             &RINEX_obs[6].signal_strength,
00877             str_c, 
00878             &RINEX_obs[7].loss_of_lock_indicator, 
00879             &RINEX_obs[7].signal_strength,
00880             str_d, 
00881             &RINEX_obs[8].loss_of_lock_indicator, 
00882             &RINEX_obs[8].signal_strength
00883             );
00884           sscanf( str_a, "%Lf", &(RINEX_obs[5].value) );
00885           sscanf( str_b, "%Lf", &(RINEX_obs[6].value) );
00886           sscanf( str_c, "%Lf", &(RINEX_obs[7].value) );
00887           sscanf( str_d ,"%Lf", &(RINEX_obs[8].value) );          
00888           break;
00889         }
00890       case 5:
00891         {
00892           count = sscanf( line_buffer, "%14c%c%c%14c%c%c%14c%c%c%14c%c%c%14c%c%c", 
00893             str_a, 
00894             &RINEX_obs[5].loss_of_lock_indicator, 
00895             &RINEX_obs[5].signal_strength,
00896             str_b, 
00897             &RINEX_obs[6].loss_of_lock_indicator, 
00898             &RINEX_obs[6].signal_strength,
00899             str_c, 
00900             &RINEX_obs[7].loss_of_lock_indicator, 
00901             &RINEX_obs[7].signal_strength,
00902             str_d, 
00903             &RINEX_obs[8].loss_of_lock_indicator, 
00904             &RINEX_obs[8].signal_strength,
00905             str_e, 
00906             &RINEX_obs[9].loss_of_lock_indicator, 
00907             &RINEX_obs[9].signal_strength
00908             );
00909           sscanf( str_a, "%Lf", &(RINEX_obs[5].value) );
00910           sscanf( str_b, "%Lf", &(RINEX_obs[6].value) );
00911           sscanf( str_c, "%Lf", &(RINEX_obs[7].value) );
00912           sscanf( str_d ,"%Lf", &(RINEX_obs[8].value) );
00913           sscanf( str_e ,"%Lf", &(RINEX_obs[9].value) );      
00914           break;
00915         }
00916       default:
00917         {
00918           return FALSE;
00919           break;
00920         }
00921       }
00922       break;
00923     }
00924     case 11:
00925     {
00926       count = sscanf( line_buffer, "%14c%c%c%14c%c%c%14c%c%c%14c%c%c%14c%c%c", 
00927         str_a, 
00928         &RINEX_obs[0].loss_of_lock_indicator, 
00929         &RINEX_obs[0].signal_strength,
00930         str_b, 
00931         &RINEX_obs[1].loss_of_lock_indicator, 
00932         &RINEX_obs[1].signal_strength,
00933         str_c, 
00934         &RINEX_obs[2].loss_of_lock_indicator, 
00935         &RINEX_obs[2].signal_strength,
00936         str_d, 
00937         &RINEX_obs[3].loss_of_lock_indicator, 
00938         &RINEX_obs[3].signal_strength,
00939         str_e, 
00940         &RINEX_obs[4].loss_of_lock_indicator, 
00941         &RINEX_obs[4].signal_strength
00942         );
00943       sscanf( str_a, "%Lf", &(RINEX_obs[0].value) );
00944       sscanf( str_b, "%Lf", &(RINEX_obs[1].value) );
00945       sscanf( str_c, "%Lf", &(RINEX_obs[2].value) );
00946       sscanf( str_d ,"%Lf", &(RINEX_obs[3].value) );
00947       sscanf( str_e ,"%Lf", &(RINEX_obs[4].value) );      
00948 
00949       memset( str_a, 0, 15 );
00950       memset( str_b, 0, 15 );
00951       memset( str_c, 0, 15 );
00952       memset( str_d, 0, 15 );
00953       memset( str_e, 0, 15 );
00954 
00955       
00956       if( fgets(line_buffer, RINEX_LINEBUF_SIZE, fid) == NULL )
00957       {
00958         if( feof(fid) )
00959         {
00960           *wasEndOfFileReached = TRUE;
00961           return TRUE;
00962         }
00963         else
00964         {
00965           return FALSE;
00966         }            
00967       }
00968 
00969       count = sscanf( line_buffer, "%14c%c%c%14c%c%c%14c%c%c%14c%c%c%14c%c%c", 
00970         str_a,
00971         &RINEX_obs[5].loss_of_lock_indicator, 
00972         &RINEX_obs[5].signal_strength,
00973         str_b,
00974         &RINEX_obs[6].loss_of_lock_indicator, 
00975         &RINEX_obs[6].signal_strength,
00976         str_c,
00977         &RINEX_obs[7].loss_of_lock_indicator, 
00978         &RINEX_obs[7].signal_strength,
00979         str_d,
00980         &RINEX_obs[8].loss_of_lock_indicator, 
00981         &RINEX_obs[8].signal_strength,
00982         str_e,
00983         &RINEX_obs[9].loss_of_lock_indicator, 
00984         &RINEX_obs[9].signal_strength
00985         );
00986       sscanf( str_a, "%Lf", &(RINEX_obs[5].value) );
00987       sscanf( str_b, "%Lf", &(RINEX_obs[6].value) );
00988       sscanf( str_c, "%Lf", &(RINEX_obs[7].value) );
00989       sscanf( str_d ,"%Lf", &(RINEX_obs[8].value) );
00990       sscanf( str_e ,"%Lf", &(RINEX_obs[9].value) );
00991     
00992       memset( str_a, 0, 15 );
00993 
00994       
00995       if( fgets(line_buffer, RINEX_LINEBUF_SIZE, fid) == NULL )
00996       {
00997         if( feof(fid) )
00998         {
00999           *wasEndOfFileReached = TRUE;
01000           return TRUE;
01001         }
01002         else
01003         {
01004           return FALSE;
01005         }            
01006       }
01007 
01008       count = sscanf( line_buffer, "%14c%c%c", 
01009         str_a,
01010         &RINEX_obs[10].loss_of_lock_indicator, 
01011         &RINEX_obs[10].signal_strength
01012         );  
01013       sscanf( str_a, "%Lf", &(RINEX_obs[10].value) );
01014       break;
01015     }
01016   default:
01017     {
01018       return FALSE;
01019       break;
01020     }
01021   }
01022 
01023   for( i = 0; i < RINEX_header->nr_obs_types; i++ )
01024   {
01025     
01026     if( RINEX_obs[i].value == 0 )
01027     {
01028       RINEX_obs[i].isValid = FALSE;
01029     }
01030     else
01031     {
01032       RINEX_obs[i].isValid = TRUE;
01033     }
01034 
01035     switch( RINEX_obs[i].loss_of_lock_indicator )
01036     {
01037     case '0': RINEX_obs[i].loss_of_lock_indicator = 0; break;
01038     case '1': RINEX_obs[i].loss_of_lock_indicator = 1; break;
01039     case '2': RINEX_obs[i].loss_of_lock_indicator = 2; break;
01040     case '3': RINEX_obs[i].loss_of_lock_indicator = 3; break;
01041     case '4': RINEX_obs[i].loss_of_lock_indicator = 4; break;
01042     case '5': RINEX_obs[i].loss_of_lock_indicator = 5; break;
01043     case '6': RINEX_obs[i].loss_of_lock_indicator = 6; break;
01044     case '7': RINEX_obs[i].loss_of_lock_indicator = 7; break;
01045     default:  RINEX_obs[i].loss_of_lock_indicator = 0; break;
01046     }
01047 
01048     switch( RINEX_obs[i].signal_strength )
01049     {
01050     case '0': RINEX_obs[i].signal_strength = 0; break;
01051     case '1': RINEX_obs[i].signal_strength = 1; break;
01052     case '2': RINEX_obs[i].signal_strength = 2; break;
01053     case '3': RINEX_obs[i].signal_strength = 3; break;
01054     case '4': RINEX_obs[i].signal_strength = 4; break;
01055     case '5': RINEX_obs[i].signal_strength = 5; break;
01056     case '6': RINEX_obs[i].signal_strength = 6; break;
01057     case '7': RINEX_obs[i].signal_strength = 7; break;
01058     case '8': RINEX_obs[i].signal_strength = 8; break;
01059     case '9': RINEX_obs[i].signal_strength = 9; break;
01060     default:  RINEX_obs[i].signal_strength = 0; break;
01061     }
01062 
01063     RINEX_obs[i].type = RINEX_header->obs_types[i];
01064 
01065     switch( sattype )
01066     {
01067     case RINEX_SATELLITE_SYSTEM_GPS:
01068       {
01069         RINEX_obs[i].system = GNSS_GPS;
01070         RINEX_obs[i].id = id;
01071         break;
01072       }
01073     case RINEX_SATELLITE_SYSTEM_GLO:
01074       {
01075         RINEX_obs[i].system = GNSS_GLONASS;
01076         RINEX_obs[i].id = id; 
01077         break;
01078       }
01079     case RINEX_SATELLITE_SYSTEM_GEO:
01080       {
01081         RINEX_obs[i].system = GNSS_WAAS;    
01082         RINEX_obs[i].id = id + 100;
01083         break;
01084       }
01085     case RINEX_SATELLITE_SYSTEM_NSS:
01086       {
01087         continue; break; 
01088       }
01089     default:
01090       {
01091         continue; break; 
01092       }
01093     }
01094   }
01095 
01096   *RINEX_nr_obs = RINEX_header->nr_obs_types;
01097 
01098   return TRUE;
01099 }
01100 
01101 
01102 BOOL RINEX_ConvertSignalStrengthToUsableCNo(
01103   float *cno,                          
01104   const unsigned char signal_strength  
01105   )
01106 {
01107   if( cno == NULL )
01108     return FALSE;
01109 
01110   if( signal_strength > 0 && signal_strength < 10 )
01111   {
01112     *cno = 5.5f*signal_strength + 0.5f;
01113   }
01114   return TRUE;
01115 }
01116 
01117 
01118 BOOL RINEX_GetHeader( 
01119   const char* filepath,           
01120   char* buffer,                   
01121   const unsigned buffer_max_size, 
01122   unsigned *buffer_size,          
01123   double *version,                
01124   RINEX_enumFileType *file_type   
01125   )
01126 {
01127   FILE* fid = NULL;                 
01128   char line_buffer[1024];               
01129   char *strptr = NULL;              
01130   BOOL end_of_header_found = FALSE; 
01131   char type_char;
01132   
01133   size_t line_length = 0; 
01134   unsigned scount = 0;      
01135 
01136   fid = fopen( filepath, "r" );
01137   if( fid == NULL )
01138     return FALSE;
01139 
01140   
01141   if( fgets( line_buffer, 1024, fid ) == NULL )
01142     return FALSE;
01143   strptr = strstr( line_buffer, "RINEX VERSION / TYPE" );
01144   if( strptr == NULL )
01145     return FALSE;
01146 
01147   
01148   line_length = strlen( line_buffer );
01149   if( scount+line_length >= buffer_max_size )    
01150     return FALSE;    
01151   scount += sprintf( buffer+scount, "%s", line_buffer );
01152 
01153   
01154   if( sscanf( line_buffer, "%Lf %c", version, &type_char ) != 2 )
01155     return FALSE;
01156   *file_type = (RINEX_enumFileType)type_char;
01157 
01158   do
01159   {
01160     if( fgets( line_buffer, 1024, fid ) == NULL )
01161       break;
01162 
01163     if( strstr( line_buffer, "END OF HEADER" ) != NULL )
01164     {
01165       end_of_header_found = TRUE;
01166     }
01167 
01168     
01169     line_length = strlen( line_buffer );
01170     if( scount+line_length >= buffer_max_size )   
01171       return FALSE;    
01172     scount += sprintf( buffer+scount, "%s", line_buffer );
01173 
01174   }while( !end_of_header_found );
01175 
01176   if( end_of_header_found )
01177   {
01178     *buffer_size = scount;
01179     return TRUE;
01180   }
01181   else
01182   {
01183     return FALSE;
01184   }
01185 }
01186 
01187 
01188 
01189 BOOL RINEX_DecodeHeader_ObservationFile(
01190   const char* header_buffer,         
01191   const unsigned header_buffer_size, 
01192   RINEX_structDecodedHeader* header  
01193   )
01194 {
01195   BOOL result = FALSE;
01196   char lines_buffer[RINEX_LINEBUF_SIZE];
01197   unsigned nr_lines = 0;
01198   char rinex_type_char = 0;
01199   char time_system_str[128];
01200   unsigned len = 0;
01201   int itmp[5];  
01202   
01203   if( header_buffer == NULL )
01204     return FALSE;
01205   if( header_buffer_size == 0 )
01206     return FALSE;
01207   if( header == NULL )
01208     return FALSE;
01209 
01210   memset( header, 0, sizeof(RINEX_structDecodedHeader) );
01211 
01212   result = RINEX_get_header_lines(
01213     header_buffer,
01214     header_buffer_size,
01215     "RINEX VERSION / TYPE",
01216     lines_buffer,
01217     RINEX_LINEBUF_SIZE,
01218     &nr_lines
01219     );
01220   if( result == FALSE )
01221     return FALSE;
01222   if( nr_lines != 1 )
01223     return FALSE;
01224   if( sscanf( lines_buffer, "%Lf %c", &(header->version), &rinex_type_char ) != 2 )
01225     return FALSE;
01226   header->type = (RINEX_enumFileType)rinex_type_char;
01227 
01228 
01229   result = RINEX_get_header_lines(
01230     header_buffer,
01231     header_buffer_size,
01232     "MARKER NAME",
01233     lines_buffer,
01234     RINEX_LINEBUF_SIZE,
01235     &nr_lines
01236     );
01237   if( result == FALSE )
01238     return FALSE;
01239   if( nr_lines != 1 )
01240     return FALSE;
01241   result = RINEX_erase("MARKER NAME", lines_buffer);
01242   if( result == FALSE )
01243     return FALSE;
01244   result = RINEX_trim_left_right(lines_buffer, RINEX_LINEBUF_SIZE, &len );
01245   if( result == FALSE )
01246     return FALSE;
01247   if( len < 64 )
01248   {
01249     strcpy(header->marker_name, lines_buffer);
01250   }
01251   else
01252   {
01253     return FALSE;
01254   }
01255 
01256   result = RINEX_get_header_lines(
01257     header_buffer,
01258     header_buffer_size,
01259     "APPROX POSITION XYZ",
01260     lines_buffer,
01261     RINEX_LINEBUF_SIZE,
01262     &nr_lines
01263     );
01264   if( result == FALSE )
01265     return FALSE;  
01266   if( nr_lines == 1 )
01267   {    
01268     if( sscanf( lines_buffer, "%Lf %Lf %Lf", &(header->x), &(header->y), &(header->z) ) != 3 )
01269       return FALSE;
01270   }
01271 
01272   result = RINEX_get_header_lines(
01273     header_buffer,
01274     header_buffer_size,
01275     "ANTENNA: DELTA H/E/N",
01276     lines_buffer,
01277     RINEX_LINEBUF_SIZE,
01278     &nr_lines
01279     );
01280   if( result == FALSE )
01281     return FALSE;
01282   if( nr_lines != 1 )
01283     return FALSE;
01284   if( sscanf( lines_buffer, "%Lf %Lf %Lf", &(header->antenna_delta_h), &(header->antenna_ecc_e), &(header->antenna_ecc_n) ) != 3 )
01285     return FALSE;
01286 
01287   
01288   result = RINEX_get_header_lines(
01289     header_buffer,
01290     header_buffer_size,
01291     "WAVELENGTH FACT L1/2",
01292     lines_buffer,
01293     RINEX_LINEBUF_SIZE,
01294     &nr_lines
01295     );
01296   if( result == FALSE )
01297     return FALSE;  
01298   if( nr_lines == 1 )
01299   {
01300     
01301     if( sscanf( lines_buffer, "%d %d", &(header->default_wavefactor_L1), &(header->default_wavefactor_L2) ) != 2 )
01302       return FALSE;
01303   }
01304   else
01305   {
01306     
01307     if( sscanf( lines_buffer, "%d %d", &(header->default_wavefactor_L1), &(header->default_wavefactor_L2) ) != 2 )
01308       return FALSE;
01309 
01310     
01311   }
01312 
01313   result = RINEX_GetObservationTypes( header_buffer, header_buffer_size, header );
01314   if( result == FALSE )
01315     return FALSE;
01316 
01317 
01318 
01319   result = RINEX_get_header_lines(
01320     header_buffer,
01321     header_buffer_size,
01322     "INTERVAL",
01323     lines_buffer,
01324     RINEX_LINEBUF_SIZE,
01325     &nr_lines
01326     );
01327   if( result == FALSE )
01328     return FALSE;
01329   if( nr_lines == 1 )
01330   {    
01331     if( sscanf( lines_buffer, "%Lf", &(header->interval) ) != 1 )
01332       return FALSE;
01333 
01334     if( header->interval <= 0 )
01335       header->interval = -1;  
01336 
01337   }
01338   else
01339   {
01340     header->interval = -1; 
01341   }
01342 
01343 
01344 
01345   result = RINEX_get_header_lines(
01346     header_buffer,
01347     header_buffer_size,
01348     "TIME OF FIRST OBS",
01349     lines_buffer,
01350     RINEX_LINEBUF_SIZE,
01351     &nr_lines
01352     );
01353   if( result == FALSE )
01354     return FALSE; 
01355 
01356   if( sscanf( lines_buffer, "%d %d %d %d %d %f %s", 
01357     &(itmp[0]),
01358     &(itmp[1]),
01359     &(itmp[2]),
01360     &(itmp[3]),
01361     &(itmp[4]),
01362     &(header->time_of_first_obs.seconds),
01363     time_system_str ) != 7 )
01364   {
01365     return FALSE;
01366   }  
01367   header->time_of_first_obs.year   = (unsigned short)itmp[0];
01368   header->time_of_first_obs.month  = (unsigned char)itmp[1];
01369   header->time_of_first_obs.day    = (unsigned char)itmp[2];
01370   header->time_of_first_obs.hour   = (unsigned char)itmp[3];
01371   header->time_of_first_obs.minute = (unsigned char)itmp[4];
01372    
01373     
01374   result = RINEX_trim_left_right( time_system_str, 128, &len );
01375   if( result == FALSE )
01376     return FALSE; 
01377   if( strcmp( time_system_str, "TIME") == 0  ) 
01378     header->time_of_first_obs.time_system = RINEX_TIME_SYSTEM_GPS;
01379   else if( strcmp( time_system_str, "GPS" ) == 0 )
01380     header->time_of_first_obs.time_system = RINEX_TIME_SYSTEM_GPS;
01381   else if( strcmp( time_system_str, "GLO" ) == 0 )
01382     header->time_of_first_obs.time_system = RINEX_TIME_SYSTEM_GLO;
01383   else
01384     header->time_of_first_obs.time_system = RINEX_TIME_SYSTEM_UNKNOWN;
01385 
01386   return TRUE;
01387 }
01388 
01389 
01390 
01391 
01392 BOOL RINEX_GetNextObservationSet(
01393   FILE* fid,                               
01394   RINEX_structDecodedHeader* RINEX_header, 
01395   BOOL *wasEndOfFileReached,               
01396   BOOL *wasObservationFound,               
01397   unsigned *filePosition,                  
01398   GNSS_structMeasurement* obsArray,        
01399   const unsigned char maxNrObs,            
01400   unsigned *nrObs,                         
01401   unsigned short* rx_gps_week,             
01402   double* rx_gps_tow                       
01403   )
01404 {
01405   char line_buffer[RINEX_LINEBUF_SIZE]; 
01406   size_t length = 0;                
01407   RINEX_TIME epoch;                 
01408   RINEX_enumEpochFlag epoch_flag;   
01409   char *pch = NULL;                 
01410   unsigned count = 0;               
01411   int itmp = 0;                     
01412   int i = 0;                        
01413   int j = 0;                        
01414   int obsArray_index = 0;           
01415   char numstr[64];                  
01416   BOOL isL1data_present = FALSE;
01417   BOOL isL2data_present = FALSE;
01418   BOOL overwriteCNoL1 = TRUE;
01419   BOOL overwriteCNoL2 = TRUE;
01420   BOOL isEpochValidToDecode = FALSE;
01421   int nr_special_records = 0;
01422   
01423   double tow = 0; 
01424   unsigned short week = 0; 
01425 
01426   RINEX_enumSatelliteSystemType next_sat_type = RINEX_SATELLITE_SYSTEM_UNKNOWN;
01427   
01428 
01429   typedef struct
01430   {
01431     char str[128];
01432     size_t length;
01433     BOOL isValid;
01434   } struct_token;
01435   struct_token token[64]; 
01436   unsigned nr_tokens = 0; 
01437 
01438   struct_RINEX_satellite RINEX_sat[RINEX_MAX_NR_SATS];
01439   unsigned RINEX_sat_index = 0;      
01440   unsigned RINEX_nr_satellites = 0;  
01441   
01442   struct_RINEX_obs RINEX_obs[RINEX_MAX_NR_OBS];
01443   unsigned RINEX_obs_index = 0; 
01444   unsigned RINEX_nr_obs = 0;    
01445 
01446   BOOL result;                       
01447 
01448   numstr[0] = '\0';
01449   numstr[1] = '\0';
01450   numstr[2] = '\0';
01451   numstr[3] = '\0';
01452 
01453   
01454   if( fid == NULL )
01455     return FALSE;
01456   if( wasEndOfFileReached == NULL )
01457     return FALSE;
01458   if( wasObservationFound == NULL )
01459     return FALSE;
01460   if( filePosition == NULL )
01461     return FALSE;
01462   if( obsArray == NULL )
01463     return FALSE;
01464   if( nrObs == NULL )
01465     return FALSE;
01466   if( RINEX_header->type != RINEX_FILE_TYPE_OBS )
01467     return FALSE;
01468 
01469   *wasObservationFound = FALSE;
01470   *wasEndOfFileReached = FALSE; 
01471 
01472   
01473   memset( token, 0, sizeof(struct_token)*RINEX_MAX_NR_SATS );
01474 
01475   
01476   memset( RINEX_obs, 0, sizeof(struct_RINEX_obs)*RINEX_MAX_NR_OBS );
01477   
01478   
01479   epoch.time_system = RINEX_header->time_of_first_obs.time_system;
01480 
01481   if( epoch.time_system != RINEX_TIME_SYSTEM_GPS )
01482   {
01483     
01484     return FALSE;
01485   }
01486 
01487   
01488   do
01489   {
01490     do 
01491     {
01492       if( fgets( line_buffer, RINEX_LINEBUF_SIZE, fid ) == NULL )
01493       {
01494         if( feof(fid) )
01495         {
01496           *wasEndOfFileReached = TRUE;
01497           return TRUE;
01498         }
01499         else
01500         {
01501           return FALSE;
01502         }
01503       }
01504       result = RINEX_trim_left_right( line_buffer, RINEX_LINEBUF_SIZE, &length );
01505       if( result == FALSE )
01506         return FALSE;
01507     }while( length == 0 );
01508   
01509     if( length == 0 )
01510       return FALSE;
01511 
01512     
01513     
01514     
01515     
01516     for( i = 0; i < (int)(length-1); i++ )
01517     {
01518       if( line_buffer[i] == 'G' || line_buffer[i] == 'R' || line_buffer[i] == 'T' || line_buffer[i] == 'S' )
01519       {
01520         if( line_buffer[i+1] == ' ' )
01521         {
01522           line_buffer[i+1] = '_';
01523         }
01524       }
01525     }
01526   
01527     
01528     pch = strtok( line_buffer, " \t\r\n\f" );  
01529     nr_tokens = 0;
01530     while( pch != NULL && count < 64 )
01531     {
01532       token[nr_tokens].length = strlen(pch);
01533       if( token[nr_tokens].length < 128 )
01534       {
01535         strcpy( token[nr_tokens].str, pch );
01536         token[nr_tokens].isValid = TRUE;
01537       }
01538       else
01539       {
01540         return FALSE;
01541       }
01542 
01543       pch = strtok( NULL, " \t\r\n\f" );
01544       nr_tokens++;
01545     }
01546     if( nr_tokens >= 64 )
01547     {
01548       return FALSE;
01549     }
01550 
01551     
01552     
01553     
01554     
01555     
01556     if( nr_tokens == 2 )
01557     {
01558       
01559       
01560       if( sscanf( token[0].str, "%d", &itmp ) != 1 )
01561         return FALSE;
01562       epoch_flag = (RINEX_enumEpochFlag)itmp;        
01563 
01564       if( sscanf( token[1].str, "%d", &nr_special_records ) != 1 )
01565         return FALSE;
01566 
01567       
01568       result = RINEX_DealWithSpecialRecords(
01569         fid,
01570         RINEX_header, 
01571         wasEndOfFileReached,
01572         filePosition,
01573         nr_special_records 
01574         );
01575 
01576       continue;
01577     }
01578     else 
01579     {
01580       
01581       
01582       
01583       if( nr_tokens < 8 )
01584         return FALSE;  
01585 
01586       
01587       i = 0;
01588       if( sscanf( token[i].str, "%d", &itmp ) != 1 ) 
01589         return FALSE; 
01590       epoch.year = (unsigned short)itmp;
01591       i++;
01592       if( sscanf( token[i].str, "%d", &itmp ) != 1 ) 
01593         return FALSE; 
01594       epoch.month = (unsigned char)itmp;
01595       i++;
01596       if( sscanf( token[i].str, "%d", &itmp ) != 1 ) 
01597         return FALSE; 
01598       epoch.day = (unsigned char)itmp;
01599       i++;
01600       if( sscanf( token[i].str, "%d", &itmp ) != 1 ) 
01601         return FALSE; 
01602       epoch.hour = (unsigned char)itmp;
01603       i++;
01604       if( sscanf( token[i].str, "%d", &itmp ) != 1 ) 
01605         return FALSE; 
01606       epoch.minute = (unsigned char)itmp;
01607       i++;
01608       if( sscanf( token[i].str, "%f", &(epoch.seconds) ) != 1 ) 
01609         return FALSE; 
01610       i++;
01611       if( sscanf( token[i].str, "%d", &(itmp) ) != 1 ) 
01612         return FALSE; 
01613       i++;
01614       epoch_flag = (RINEX_enumEpochFlag)itmp;
01615 
01616       if( epoch_flag == 6 )
01617       {
01618         isEpochValidToDecode = TRUE;        
01619         
01620         
01621       }
01622       else if( epoch_flag > 1 )
01623       {
01624         if( sscanf( token[i].str, "%d", &nr_special_records ) != 1 )
01625           return FALSE;       
01626 
01627         
01628         result = RINEX_DealWithSpecialRecords(
01629           fid,
01630           RINEX_header, 
01631           wasEndOfFileReached,
01632           filePosition,
01633           nr_special_records 
01634           );
01635         continue;
01636       }
01637       else
01638       {
01639         isEpochValidToDecode = TRUE;
01640       }
01641     }
01642 
01643   }while( !isEpochValidToDecode );
01644 
01645   if( token[7].length == 0 )
01646     return FALSE;
01647   
01648   
01649   for( i = 0; i < (int)token[7].length; i++ )
01650   {
01651     
01652     
01653     
01654     
01655     
01656     
01657     
01658     
01659     if( token[7].str[i] == '_' )
01660     {
01661       continue;
01662     }  
01663     if( token[7].str[i] == '-' || token[7].str[i] == '+' || token[7].str[i] == '.' || token[7].str[i] == 'E' || token[7].str[i] == 'e' )
01664     {
01665       
01666       return FALSE;
01667     }
01668 
01669     if( isdigit( token[7].str[i] ) )
01670     {
01671       numstr[j] = token[7].str[i];
01672       j++;
01673     }
01674     else
01675     {
01676       if( token[7].str[i] != RINEX_SATELLITE_SYSTEM_GPS && 
01677         token[7].str[i] != RINEX_SATELLITE_SYSTEM_GLO && 
01678         token[7].str[i] != RINEX_SATELLITE_SYSTEM_GEO && 
01679         token[7].str[i] != RINEX_SATELLITE_SYSTEM_NSS )
01680       {
01681         return FALSE;
01682       }
01683 
01684       numstr[j] = '\0';
01685       j = 0;
01686       
01687       if( sscanf( numstr, "%d", &itmp ) != 1 )
01688         return FALSE;
01689       if( count == 0 )
01690       {
01691         
01692         RINEX_nr_satellites = itmp;
01693         if( RINEX_nr_satellites >= 64 )
01694         {
01695           return FALSE; 
01696         }
01697       }
01698       else
01699       {
01700         
01701         RINEX_sat[count-1].id = (unsigned short)itmp;
01702         RINEX_sat[count-1].type = next_sat_type;
01703       }
01704       count++;
01705       if( count > RINEX_nr_satellites+1 )
01706       {
01707         return FALSE; 
01708       }
01709       next_sat_type = (RINEX_enumSatelliteSystemType)token[7].str[i];
01710     }
01711   }
01712   if( count == 0 )
01713   {
01714     return FALSE;
01715   }
01716 
01717   
01718   numstr[j] = '\0';
01719   j = 0;
01720   if( sscanf( numstr, "%d", &itmp ) != 1 )
01721     return FALSE;
01722   RINEX_sat[count-1].id = (unsigned short)itmp;
01723   RINEX_sat[count-1].type = next_sat_type;
01724   count++;
01725 
01726   if( count > RINEX_nr_satellites+1 )
01727   {
01728     
01729     return FALSE;
01730   }
01731 
01732   if( count != RINEX_nr_satellites+1 )
01733   {
01734     if( RINEX_nr_obs <= 12 )
01735     {
01736       return FALSE;
01737     }
01738     else
01739     {
01740       
01741       if( fgets(line_buffer, RINEX_LINEBUF_SIZE, fid) == NULL )
01742       {
01743         if( feof(fid) )
01744         {
01745           *wasEndOfFileReached = TRUE;
01746           return TRUE;
01747         }
01748         else
01749         {
01750           return FALSE;
01751         }
01752       }
01753 
01754       length = strlen(line_buffer);
01755       if( length == 0 )
01756         return FALSE;
01757 
01758       if( RINEX_trim_left_right( line_buffer, RINEX_LINEBUF_SIZE, &length ) == FALSE )
01759         return FALSE;
01760 
01761       for( i = 0; i < (int)length; i++ )
01762       {
01763         if( isspace(line_buffer[i]) )
01764         {
01765           continue;
01766         }  
01767         if( line_buffer[i] == '-' || line_buffer[i] == '+' || line_buffer[i] == '.' || line_buffer[i] == 'E' || line_buffer[i] == 'e' )
01768         {
01769           
01770           return FALSE;
01771         }
01772 
01773         if( !isdigit( line_buffer[i] ) ) 
01774         {
01775           if( line_buffer[i] != RINEX_SATELLITE_SYSTEM_GPS && 
01776             line_buffer[i] != RINEX_SATELLITE_SYSTEM_GLO && 
01777             line_buffer[i] != RINEX_SATELLITE_SYSTEM_GEO && 
01778             line_buffer[i] != RINEX_SATELLITE_SYSTEM_NSS &&
01779             line_buffer[i] != RINEX_SATELLITE_SYSTEM_MIXED )
01780           {
01781             return FALSE;
01782           }
01783 
01784           if( j != 0 )
01785           {
01786             numstr[j] = '\0';
01787             j = 0;
01788             if( sscanf( numstr, "%d", &itmp ) != 1 )
01789             {
01790               return FALSE;
01791             }
01792             RINEX_sat[count-1].id = (unsigned short)itmp;
01793             RINEX_sat[count-1].type = next_sat_type;
01794 
01795             count++;
01796             if( count > RINEX_nr_satellites+1 )
01797             {
01798               return FALSE; 
01799             }
01800           }          
01801           next_sat_type = (RINEX_enumSatelliteSystemType)line_buffer[i];
01802         }
01803         else
01804         {
01805           numstr[j] = line_buffer[i];
01806           j++;
01807         }
01808       }
01809     }
01810     
01811     numstr[j] = '\0';
01812     j = 0;
01813     if( sscanf( numstr, "%d", &itmp ) != 1 )
01814     {
01815       return FALSE;
01816     }
01817     RINEX_sat[count-1].id = (unsigned short)itmp;
01818     RINEX_sat[count-1].type = next_sat_type;
01819     count++;
01820 
01821     if( count != RINEX_nr_satellites+1 )
01822     {
01823       return FALSE;
01824     }
01825   }
01826 
01827   if( RINEX_header->nr_obs_types >= 64 )    
01828     return FALSE; 
01829 
01830 
01831 
01832   
01833   
01834   
01835   
01836   
01837   
01838 
01839   if( epoch.year >= 80 && epoch.year < 2000 )
01840   {
01841     epoch.year += 1900;
01842   }
01843   else if( epoch.year >= 0 && epoch.year < 79 )
01844   {
01845     epoch.year += 2000;
01846   }
01847   else
01848   {
01849     return FALSE;
01850   }
01851   TIMECONV_GetGPSTimeFromRinexTime(
01852     epoch.year,
01853     epoch.month,
01854     epoch.day,
01855     epoch.hour,
01856     epoch.minute,
01857     epoch.seconds,
01858     &week,
01859     &tow 
01860     );
01861 
01862   
01863   *rx_gps_week = week;
01864   *rx_gps_tow = tow;
01865   
01866 
01867   obsArray_index = 0;
01868   for( RINEX_sat_index = 0; RINEX_sat_index < (int)RINEX_nr_satellites; RINEX_sat_index++ )
01869   {
01870     isL1data_present = FALSE;
01871     isL2data_present = FALSE;
01872     overwriteCNoL1 = TRUE;
01873     overwriteCNoL2 = TRUE;  
01874 
01875     
01876     memset( &(obsArray[obsArray_index]), 0, sizeof(GNSS_structMeasurement) );
01877 
01878     result = RINEX_GetNextObserationSetForOneSatellite(
01879       fid,
01880       RINEX_header,
01881       wasEndOfFileReached,
01882       filePosition,      
01883       RINEX_obs,
01884       RINEX_MAX_NR_OBS,
01885       &RINEX_nr_obs,
01886       RINEX_sat[RINEX_sat_index].type,
01887       RINEX_sat[RINEX_sat_index].id
01888       );
01889     if( result == FALSE )
01890       return FALSE;
01891 
01892     if( epoch_flag == 6 ) 
01893     {
01894       
01895 
01896       
01897       continue;
01898     }
01899 
01900     
01901     obsArray[obsArray_index].tow  =  tow;
01902     obsArray[obsArray_index].week = week;
01903 
01904     
01905     obsArray[obsArray_index].channel = (unsigned short)obsArray_index;
01906 
01907     obsArray[obsArray_index].id = RINEX_sat[RINEX_sat_index].id;
01908 
01909     
01910     obsArray[obsArray_index].flags.isEphemerisValid        = 0; 
01911     obsArray[obsArray_index].flags.isAlmanacValid          = 0; 
01912     obsArray[obsArray_index].flags.isAboveElevationMask    = 0; 
01913     obsArray[obsArray_index].flags.isAboveCNoMask          = 0; 
01914     obsArray[obsArray_index].flags.isAboveLockTimeMask     = 0; 
01915     obsArray[obsArray_index].flags.isNotUserRejected       = 1; 
01916     obsArray[obsArray_index].flags.isNotPsrRejected        = 1; 
01917     obsArray[obsArray_index].flags.isNotAdrRejected        = 1; 
01918     obsArray[obsArray_index].flags.isNotDopplerRejected    = 1; 
01919     obsArray[obsArray_index].flags.isNoCycleSlipDetected   = 1; 
01920     obsArray[obsArray_index].flags.isPsrUsedInSolution     = 0; 
01921     obsArray[obsArray_index].flags.isDopplerUsedInSolution = 0; 
01922     obsArray[obsArray_index].flags.isAdrUsedInSolution     = 0; 
01923     obsArray[obsArray_index].flags.useTropoCorrection          = 1; 
01924     obsArray[obsArray_index].flags.useBroadcastIonoCorrection  = 1; 
01925 
01926 
01927 
01928     
01929     
01930     
01931     
01932     
01933     
01934     
01935     for( RINEX_obs_index = 0; RINEX_obs_index < RINEX_nr_obs; RINEX_obs_index++ )
01936     {
01937       if( RINEX_obs[RINEX_obs_index].type == RINEX_OBS_TYPE_S1 && RINEX_obs[RINEX_obs_index].isValid )
01938       {
01939         obsArray[obsArray_index].system   = RINEX_obs[RINEX_obs_index].system;
01940         obsArray[obsArray_index].freqType = GNSS_GPSL1; 
01941         
01942         overwriteCNoL1 = FALSE;
01943 
01944         
01945         
01946         obsArray[obsArray_index].cno = (float)RINEX_obs[RINEX_obs_index].value; 
01947 
01948         isL1data_present = TRUE;
01949       }
01950     }
01951 
01952     for( RINEX_obs_index = 0; RINEX_obs_index < RINEX_nr_obs; RINEX_obs_index++ )
01953     {
01954       if( !RINEX_obs[RINEX_obs_index].isValid )
01955         continue;
01956 
01957       switch(RINEX_obs[RINEX_obs_index].type)
01958       {
01959       case RINEX_OBS_TYPE_L1:
01960         {
01961           obsArray[obsArray_index].system   = RINEX_obs[RINEX_obs_index].system;
01962           obsArray[obsArray_index].freqType = GNSS_GPSL1; 
01963 
01964           obsArray[obsArray_index].adr = RINEX_obs[RINEX_obs_index].value; 
01965 
01966           
01967           obsArray[obsArray_index].flags.isActive       = TRUE;
01968           obsArray[obsArray_index].flags.isCodeLocked   = TRUE;
01969           obsArray[obsArray_index].flags.isPhaseLocked  = TRUE;
01970           obsArray[obsArray_index].flags.isParityValid  = TRUE; 
01971           obsArray[obsArray_index].flags.isAdrValid     = TRUE;
01972           obsArray[obsArray_index].flags.isAutoAssigned = TRUE; 
01973           obsArray[obsArray_index].flags.isNoCycleSlipDetected = TRUE;
01974 
01975           isL1data_present = TRUE;
01976 
01977           
01978           switch( RINEX_obs[RINEX_obs_index].loss_of_lock_indicator )
01979           {
01980           case 0:
01981             {
01982               
01983               break;
01984             }
01985           case 1: 
01986             {
01987               
01988               obsArray[obsArray_index].flags.isNoCycleSlipDetected = FALSE;
01989               break;
01990             }
01991           case 2:
01992             {
01993               
01994               
01995               
01996               
01997               
01998               break;
01999             }
02000           case 3:
02001             { 
02002               
02003               obsArray[obsArray_index].flags.isNoCycleSlipDetected = FALSE;
02004               
02005               break;
02006             }
02007           case 5:
02008             {
02009               
02010               obsArray[obsArray_index].flags.isNoCycleSlipDetected = FALSE;
02011               
02012             }
02013           case 4:
02014             { 
02015               
02016               
02017               break;
02018             }
02019           case 6:
02020             {
02021               
02022               
02023               break;
02024             }
02025           case 7:
02026             {
02027               
02028               obsArray[obsArray_index].flags.isNoCycleSlipDetected = FALSE;
02029               
02030               break;
02031             }
02032           default:
02033             {
02034               
02035               
02036               break;
02037             }
02038           }
02039 
02040           if( overwriteCNoL1 )
02041           {
02042             result = RINEX_ConvertSignalStrengthToUsableCNo( &(obsArray[obsArray_index].cno), RINEX_obs[RINEX_obs_index].signal_strength );
02043             if( result == FALSE )
02044               return FALSE;
02045           }
02046 
02047           break;  
02048         }
02049       case RINEX_OBS_TYPE_C1:
02050         {
02051           obsArray[obsArray_index].system   = RINEX_obs[RINEX_obs_index].system;
02052           obsArray[obsArray_index].freqType = GNSS_GPSL1; 
02053           obsArray[obsArray_index].codeType = GNSS_CACode; 
02054 
02055           obsArray[obsArray_index].psr = RINEX_obs[RINEX_obs_index].value; 
02056 
02057           
02058           obsArray[obsArray_index].tow  =  tow - obsArray[obsArray_index].psr/LIGHTSPEED;
02059 
02060           
02061           obsArray[obsArray_index].flags.isActive       = TRUE;
02062           obsArray[obsArray_index].flags.isCodeLocked   = TRUE;
02063           obsArray[obsArray_index].flags.isPsrValid     = TRUE;
02064           obsArray[obsArray_index].flags.isAutoAssigned = TRUE; 
02065           isL1data_present = TRUE;
02066 
02067           if( overwriteCNoL1 )
02068           {
02069             result = RINEX_ConvertSignalStrengthToUsableCNo( &(obsArray[obsArray_index].cno), RINEX_obs[RINEX_obs_index].signal_strength );
02070             if( result == FALSE )
02071               return FALSE;
02072           }
02073 
02074           break;
02075         }
02076       case RINEX_OBS_TYPE_P1:
02077         {
02078           obsArray[obsArray_index].system   = RINEX_obs[RINEX_obs_index].system;
02079           obsArray[obsArray_index].freqType = GNSS_GPSL1; 
02080           obsArray[obsArray_index].codeType = GNSS_PCode; 
02081 
02082           obsArray[obsArray_index].psr = RINEX_obs[RINEX_obs_index].value; 
02083 
02084           
02085           
02086           obsArray[obsArray_index].tow  =  tow - obsArray[obsArray_index].psr/LIGHTSPEED;
02087 
02088           
02089           obsArray[obsArray_index].flags.isActive       = TRUE;
02090           obsArray[obsArray_index].flags.isCodeLocked   = TRUE;
02091           obsArray[obsArray_index].flags.isPsrValid     = TRUE;
02092           obsArray[obsArray_index].flags.isAutoAssigned = TRUE; 
02093           isL1data_present = TRUE;
02094 
02095           if( overwriteCNoL1 )
02096           {
02097             result = RINEX_ConvertSignalStrengthToUsableCNo( &(obsArray[obsArray_index].cno), RINEX_obs[RINEX_obs_index].signal_strength );
02098             if( result == FALSE )
02099               return FALSE;
02100           }
02101 
02102           break;
02103         }
02104       case RINEX_OBS_TYPE_D1:
02105         {
02106           obsArray[obsArray_index].system   = RINEX_obs[RINEX_obs_index].system;
02107           obsArray[obsArray_index].freqType = GNSS_GPSL1; 
02108           obsArray[obsArray_index].doppler = (float)RINEX_obs[RINEX_obs_index].value; 
02109 
02110           
02111           obsArray[obsArray_index].flags.isDopplerValid = TRUE;
02112           isL1data_present = TRUE;
02113           break;
02114         }
02115       default:
02116         {
02117           break;
02118         }
02119       }
02120     }
02121     if( isL1data_present )
02122     {
02123       
02124       if( obsArray[obsArray_index].cno == 0.0 )
02125       {
02126         obsArray[obsArray_index].cno = 32; 
02127       }
02128 
02129       obsArray_index++;
02130       if( obsArray_index >= maxNrObs )
02131         return FALSE;
02132       
02133       
02134       memset( &(obsArray[obsArray_index]), 0, sizeof(GNSS_structMeasurement) );
02135 
02136       
02137       obsArray[obsArray_index].tow  =  tow;
02138       obsArray[obsArray_index].week = week;
02139 
02140       obsArray[obsArray_index].id = RINEX_sat[RINEX_sat_index].id;
02141 
02142       
02143       obsArray[obsArray_index].channel = (unsigned short)obsArray_index;
02144 
02145       
02146       obsArray[obsArray_index].flags.isEphemerisValid        = 0; 
02147       obsArray[obsArray_index].flags.isAlmanacValid          = 0; 
02148       obsArray[obsArray_index].flags.isAboveElevationMask    = 0; 
02149       obsArray[obsArray_index].flags.isAboveCNoMask          = 0; 
02150       obsArray[obsArray_index].flags.isAboveLockTimeMask     = 0; 
02151       obsArray[obsArray_index].flags.isNotUserRejected       = 1; 
02152       obsArray[obsArray_index].flags.isNotPsrRejected        = 1; 
02153       obsArray[obsArray_index].flags.isNotAdrRejected        = 1; 
02154       obsArray[obsArray_index].flags.isNotDopplerRejected    = 1; 
02155       obsArray[obsArray_index].flags.isNoCycleSlipDetected   = 1; 
02156       obsArray[obsArray_index].flags.isPsrUsedInSolution     = 0; 
02157       obsArray[obsArray_index].flags.isDopplerUsedInSolution = 0; 
02158       obsArray[obsArray_index].flags.isAdrUsedInSolution     = 0; 
02159       obsArray[obsArray_index].flags.useTropoCorrection      = 1; 
02160       obsArray[obsArray_index].flags.useBroadcastIonoCorrection  = 1; 
02161     }
02162 
02163     
02164     
02165     
02166     for( RINEX_obs_index = 0; RINEX_obs_index < RINEX_nr_obs; RINEX_obs_index++ )
02167     {
02168       if( RINEX_obs[RINEX_obs_index].type == RINEX_OBS_TYPE_S2 && RINEX_obs[RINEX_obs_index].isValid )
02169       {
02170         obsArray[obsArray_index].system   = RINEX_obs[RINEX_obs_index].system;
02171         obsArray[obsArray_index].freqType = GNSS_GPSL1; 
02172         obsArray[obsArray_index].id       = RINEX_obs[RINEX_obs_index].id;
02173 
02174         overwriteCNoL2 = FALSE;
02175 
02176         
02177         
02178         obsArray[obsArray_index].cno = (float)RINEX_obs[RINEX_obs_index].value; 
02179 
02180         isL2data_present = TRUE;
02181       }
02182     }
02183 
02184 
02185     
02186     for( RINEX_obs_index = 0; RINEX_obs_index < RINEX_nr_obs; RINEX_obs_index++ )
02187     {
02188       if( !RINEX_obs[RINEX_obs_index].isValid )
02189         continue;
02190 
02191       switch(RINEX_obs[RINEX_obs_index].type)
02192       {
02193       case RINEX_OBS_TYPE_L2:
02194         {
02195           obsArray[obsArray_index].system   = RINEX_obs[RINEX_obs_index].system;
02196           obsArray[obsArray_index].freqType = GNSS_GPSL2; 
02197           obsArray[obsArray_index].adr = RINEX_obs[RINEX_obs_index].value; 
02198 
02199           
02200           obsArray[obsArray_index].flags.isActive       = TRUE;
02201           obsArray[obsArray_index].flags.isCodeLocked   = TRUE;
02202           obsArray[obsArray_index].flags.isPhaseLocked  = TRUE;
02203           obsArray[obsArray_index].flags.isParityValid  = TRUE; 
02204           obsArray[obsArray_index].flags.isAdrValid     = TRUE;
02205           obsArray[obsArray_index].flags.isAutoAssigned = TRUE; 
02206           obsArray[obsArray_index].flags.isNoCycleSlipDetected = TRUE;
02207           isL2data_present = TRUE;
02208 
02209           
02210           switch( RINEX_obs[RINEX_obs_index].loss_of_lock_indicator )
02211           {
02212           case 0: 
02213             {
02214               break; 
02215             }
02216           case 1: 
02217             {
02218               
02219               obsArray[obsArray_index].flags.isNoCycleSlipDetected = FALSE;
02220               break;
02221             }
02222           case 2:
02223             {
02224               
02225               
02226               
02227               
02228               
02229               break;
02230             }
02231           case 3:
02232             { 
02233               
02234               obsArray[obsArray_index].flags.isNoCycleSlipDetected = FALSE;
02235               
02236               break;
02237             }
02238           case 5:
02239             {
02240               
02241               obsArray[obsArray_index].flags.isNoCycleSlipDetected = FALSE;
02242               
02243             }
02244           case 4:
02245             { 
02246               
02247               
02248               break;
02249             }
02250           case 6:
02251             {
02252               
02253               
02254               break;
02255             }
02256           case 7:
02257             {
02258               
02259               obsArray[obsArray_index].flags.isNoCycleSlipDetected = FALSE;
02260               
02261               break;
02262             }
02263           default:
02264             {
02265               
02266               
02267               break;
02268             }
02269           }
02270 
02271           if( overwriteCNoL2 )
02272           {
02273             result = RINEX_ConvertSignalStrengthToUsableCNo( &(obsArray[obsArray_index].cno), RINEX_obs[RINEX_obs_index].signal_strength );
02274             if( result == FALSE )
02275               return FALSE;
02276           }
02277 
02278           break;  
02279         }
02280       case RINEX_OBS_TYPE_P2:
02281         {
02282           obsArray[obsArray_index].system   = RINEX_obs[RINEX_obs_index].system;
02283           obsArray[obsArray_index].freqType = GNSS_GPSL2; 
02284           obsArray[obsArray_index].codeType = GNSS_PCode; 
02285 
02286           obsArray[obsArray_index].psr = RINEX_obs[RINEX_obs_index].value; 
02287 
02288           
02289           obsArray[obsArray_index].tow  =  tow - obsArray[obsArray_index].psr/LIGHTSPEED;
02290 
02291           
02292           obsArray[obsArray_index].flags.isActive       = TRUE;
02293           obsArray[obsArray_index].flags.isCodeLocked   = TRUE;
02294           obsArray[obsArray_index].flags.isPsrValid     = TRUE;
02295           obsArray[obsArray_index].flags.isAutoAssigned = TRUE; 
02296           isL2data_present = TRUE;
02297 
02298           if( overwriteCNoL2 )
02299           {
02300             result = RINEX_ConvertSignalStrengthToUsableCNo( &(obsArray[obsArray_index].cno), RINEX_obs[RINEX_obs_index].signal_strength );
02301             if( result == FALSE )
02302               return FALSE;
02303           }
02304 
02305           break;
02306         }
02307       case RINEX_OBS_TYPE_D2:
02308         {
02309           obsArray[obsArray_index].system   = RINEX_obs[RINEX_obs_index].system;
02310           obsArray[obsArray_index].freqType = GNSS_GPSL2; 
02311           obsArray[obsArray_index].doppler = (float)RINEX_obs[RINEX_obs_index].value; 
02312 
02313           
02314           obsArray[obsArray_index].flags.isDopplerValid = TRUE;
02315           isL2data_present = TRUE;
02316           break;
02317         }
02318       default:
02319         {
02320           break;
02321         }
02322       }
02323     }
02324 
02325     if( isL2data_present )
02326     {
02327       
02328       if( obsArray[obsArray_index].cno == 0.0 )
02329       {
02330         obsArray[obsArray_index].cno = 32; 
02331       }
02332 
02333       obsArray_index++;
02334       if( obsArray_index >= maxNrObs )
02335         return FALSE;
02336     }
02337 
02338     
02339   }
02340 
02341   *nrObs = obsArray_index;
02342   *wasObservationFound = TRUE;
02343 
02344   return TRUE;
02345 }
02346 
02347 
02348 BOOL RINEX_DecodeGPSNavigationFile(
02349   const char *filepath,                          
02350   GNSS_structKlobuchar *iono_model,              
02351   GPS_structEphemeris *ephemeris_array,          
02352   const unsigned int max_length_ephemeris_array, 
02353   unsigned int *length_ephemeris_array           
02354   )
02355 {
02356   char RINEX_header[RINEX_HEADER_SIZE];
02357   unsigned RINEX_header_length = 0;
02358   double version = 0.0;
02359   RINEX_enumFileType file_type = RINEX_FILE_TYPE_UNKNOWN;
02360   char line_buffer[RINEX_LINEBUF_SIZE];
02361   unsigned nr_lines = 0;
02362   BOOL result;
02363   FILE* fid = NULL;
02364   GPS_structEphemeris eph; 
02365   RINEX_TIME epoch;
02366   unsigned i = 0;
02367   unsigned count = 0;
02368   double tow = 0;
02369   int itmp = 0;
02370   int itmp2 = 0;
02371   double dtmp = 0.0;
02372   unsigned short week = 0;
02373   unsigned ephemeris_array_index = 0;
02374   size_t length = 0;
02375 
02376   char station_name[5];
02377   unsigned short dayofyear = 0;
02378   unsigned char file_sequence_nr = 0;
02379   unsigned short year = 0;
02380 
02381   double header_A0; 
02382   double header_A1; 
02383   int header_week;  
02384   int header_tow;   
02385   
02386   char str[10][20]; 
02387 
02388   memset( &eph, 0, sizeof(GPS_structEphemeris) );
02389 
02390   epoch.time_system = RINEX_TIME_SYSTEM_GPS;
02391   
02392   if( filepath == NULL )
02393     return FALSE;
02394   if( iono_model == NULL )
02395     return FALSE;
02396   if( ephemeris_array == NULL )
02397     return FALSE;
02398   if( length_ephemeris_array == NULL )
02399     return FALSE;
02400   if( max_length_ephemeris_array == 0 )
02401     return FALSE;
02402 
02403   iono_model->isValid = FALSE;
02404 
02405   result = RINEX_GetHeader( 
02406     filepath,
02407     RINEX_header,
02408     RINEX_HEADER_SIZE,
02409     &RINEX_header_length,
02410     &version,
02411     &file_type
02412     );
02413   if( result == FALSE )
02414     return FALSE;
02415 
02416   if( file_type != RINEX_FILE_TYPE_GPS_NAV )
02417     return FALSE;
02418 
02419   if( fabs( version - 2.1 ) < 1e-06 || 
02420     fabs( version - 2.0 ) < 1e-06 ||
02421     fabs( version - 2.11 ) < 1e-06 )
02422   {
02423     
02424   }
02425   else
02426   {    
02427     return FALSE;
02428   }
02429 
02430   result = RINEX_get_header_lines(
02431     RINEX_header,
02432     RINEX_header_length,
02433     "ION ALPHA",
02434     line_buffer,
02435     RINEX_LINEBUF_SIZE,
02436     &nr_lines
02437     );
02438   if( result == FALSE )
02439     return FALSE;
02440   if( nr_lines == 1 )
02441   {
02442     result = RINEX_ReplaceDwithE( line_buffer, (unsigned)strlen(line_buffer) );
02443     if( result == FALSE )
02444       return FALSE;
02445 
02446     if( sscanf( line_buffer, "%Lf %Lf %Lf %Lf", 
02447       &(iono_model->alpha0), 
02448       &(iono_model->alpha1),
02449       &(iono_model->alpha2),
02450       &(iono_model->alpha3) ) != 4 )
02451     {
02452       return FALSE; 
02453     }
02454     result = RINEX_get_header_lines(
02455       RINEX_header,
02456       RINEX_header_length,
02457       "ION BETA",
02458       line_buffer,
02459       RINEX_LINEBUF_SIZE,
02460       &nr_lines
02461       );
02462     if( result == FALSE )
02463       return FALSE;
02464     if( nr_lines != 1 )
02465       return FALSE; 
02466 
02467     result = RINEX_ReplaceDwithE( line_buffer, (unsigned)strlen(line_buffer) );
02468     if( result == FALSE )
02469       return FALSE;
02470 
02471     if( sscanf( line_buffer, "%Lf %Lf %Lf %Lf", 
02472       &(iono_model->beta0), 
02473       &(iono_model->beta1),
02474       &(iono_model->beta2),
02475       &(iono_model->beta3) ) != 4 )
02476     {
02477       return FALSE; 
02478     }
02479 
02480     result = RINEX_get_header_lines(
02481       RINEX_header,
02482       RINEX_header_length,
02483       "DELTA-UTC: A0,A1,T,W",
02484       line_buffer,
02485       RINEX_LINEBUF_SIZE,
02486       &nr_lines
02487       );
02488     if( result == FALSE )
02489       return FALSE;
02490     if( nr_lines == 1 )
02491     {
02492       result = RINEX_ReplaceDwithE( line_buffer, (unsigned)strlen(line_buffer) );
02493       if( result == FALSE )
02494         return FALSE;
02495 
02496       if( sscanf( line_buffer, "%Lf %Lf %d %d",
02497         &header_A0,
02498         &header_A1,
02499         &header_tow,
02500         &header_week ) == 4 )
02501       {
02502         iono_model->week = (unsigned short) header_week;
02503         iono_model->tow = header_tow;
02504         iono_model->isValid = TRUE;
02505       }
02506     }
02507 
02508     if( iono_model->isValid == FALSE )
02509     {
02510       
02511       result = RINEX_DecodeFileName( filepath, station_name, &dayofyear, &file_sequence_nr, &year, &file_type );
02512       if( result == TRUE )
02513       {
02514         result = TIMECONV_GetGPSTimeFromYearAndDayOfYear(
02515           year,
02516           dayofyear,
02517           &(iono_model->week),
02518           &dtmp
02519           );
02520         if( result == FALSE )
02521           return FALSE;
02522         iono_model->tow = (unsigned)dtmp;
02523         iono_model->isValid = TRUE;
02524       }
02525       else
02526       {
02527         
02528         iono_model->isValid = FALSE;
02529       }
02530     }
02531   }
02532 
02533   fid = fopen( filepath, "r" );
02534   if( fid == NULL )
02535     return FALSE;
02536 
02537   do
02538   {
02539     
02540     if( fgets(line_buffer, RINEX_LINEBUF_SIZE, fid) == NULL )
02541     {
02542       if( feof(fid) )
02543       {      
02544         return TRUE;
02545       }
02546       else
02547       {
02548         return FALSE;
02549       }
02550     }
02551   }
02552   while( strstr( line_buffer, "END OF HEADER" ) == NULL );
02553 
02554 
02555   while( !feof(fid) && !ferror(fid) && ephemeris_array_index < max_length_ephemeris_array )
02556   {
02557     
02558     if( fgets(line_buffer, RINEX_LINEBUF_SIZE, fid) == NULL )
02559     {
02560       if( feof(fid) )
02561       {      
02562         break;
02563       }
02564       else
02565       {
02566         return FALSE;
02567       }
02568     }
02569     
02570     length = strlen(line_buffer);
02571     for( i = 0; i < length; i++ )
02572     {
02573       if( isalnum(line_buffer[i]) )
02574         break;
02575     }
02576     if( i == length )
02577       continue; 
02578 
02579     result = RINEX_ReplaceDwithE( line_buffer, (unsigned)length );
02580     if( result == FALSE )
02581       return FALSE;
02582 
02583     memset( str, 0, sizeof(char)*10*20 );  
02584     count = sscanf( line_buffer, "%2c%*c%2c%*c%2c%*c%2c%*c%2c%*c%2c%5c%19c%19c%19c",
02585       str[0],
02586       str[1],
02587       str[2],
02588       str[3],
02589       str[4],
02590       str[5],
02591       str[6],
02592       str[7],
02593       str[8],
02594       str[9]
02595       );
02596 
02597     if( count != 10 )
02598       return FALSE; 
02599 
02600     i = 0;
02601     if( sscanf( str[i], "%d", &itmp ) != 1 )
02602       return FALSE;
02603     eph.prn = (unsigned short)itmp;
02604     i++;
02605     if( sscanf( str[i], "%d", &itmp  ) != 1 )
02606       return FALSE;
02607     epoch.year = (unsigned short)itmp;
02608     i++;
02609     if( sscanf( str[i], "%d", &itmp  ) != 1 )
02610       return FALSE;
02611     epoch.month = (unsigned char)itmp;
02612     i++;
02613     if( sscanf( str[i], "%d", &itmp  ) != 1 )
02614       return FALSE;
02615     epoch.day = (unsigned char)itmp;
02616     i++;
02617     if( sscanf( str[i], "%d", &itmp  ) != 1 )
02618       return FALSE;
02619     epoch.hour = (unsigned char)itmp;
02620     i++;
02621     if( sscanf( str[i], "%d", &epoch.minute ) != 1 )
02622       return FALSE;
02623     epoch.minute = (unsigned char)itmp;
02624     i++;
02625     if( sscanf( str[i], "%f", &epoch.seconds ) != 1 )
02626       return FALSE;
02627     i++;
02628     if( sscanf( str[i], "%Lf", &eph.af0 ) != 1 )
02629       return FALSE;
02630     i++;
02631     if( sscanf( str[i], "%Lf", &eph.af1 ) != 1 )
02632       return FALSE;
02633     i++;
02634     if( sscanf( str[i], "%Lf", &eph.af2 ) != 1 )
02635       return FALSE;
02636 
02637     if( epoch.year >= 80 && epoch.year < 2000 )
02638     {
02639       epoch.year += 1900;
02640     }
02641     else if( epoch.year >= 0 && epoch.year < 79 )
02642     {
02643       epoch.year += 2000;
02644     }
02645     else
02646     {
02647       return FALSE;
02648     }
02649     result = TIMECONV_GetGPSTimeFromRinexTime(
02650       epoch.year,
02651       epoch.month,
02652       epoch.day,
02653       epoch.hour,
02654       epoch.minute,
02655       epoch.seconds,
02656       &week,
02657       &tow 
02658       );
02659     if( result == FALSE )
02660       return FALSE;
02661     eph.toc = (unsigned)tow;
02662 
02663 
02664     
02665     
02666 
02667     
02668     if( fgets(line_buffer, RINEX_LINEBUF_SIZE, fid) == NULL )
02669     {
02670       if( feof(fid) )
02671       {      
02672         break;
02673       }
02674       else
02675       {
02676         return FALSE;
02677       }
02678     }
02679     result = RINEX_ReplaceDwithE( line_buffer, (unsigned)strlen(line_buffer) );
02680     if( result == FALSE )
02681       return FALSE;
02682 
02683     memset( str, 0, sizeof(char)*10*20 );  
02684     count = sscanf( line_buffer, "%*3c%19c%19c%19c%19c",
02685       str[0],
02686       str[1],
02687       str[2],
02688       str[3]
02689       );
02690     if( count != 4 )
02691       return FALSE;
02692 
02693     i = 0;
02694     if( sscanf( str[i], "%Lf", &dtmp ) != 1 )
02695       return FALSE;
02696     eph.iode = (unsigned char)dtmp;
02697     i++;
02698     if( sscanf( str[i], "%Lf", &eph.crs ) != 1 )
02699       return FALSE;
02700     i++;
02701     if( sscanf( str[i], "%Lf", &eph.delta_n ) != 1 )
02702       return FALSE;
02703     i++;
02704     if( sscanf( str[i], "%Lf", &eph.m0 ) != 1 )
02705       return FALSE;
02706     i++;
02707 
02708     
02709     
02710 
02711     
02712     if( fgets(line_buffer, RINEX_LINEBUF_SIZE, fid) == NULL )
02713     {
02714       if( feof(fid) )
02715       {      
02716         break;
02717       }
02718       else
02719       {
02720         return FALSE;
02721       }
02722     }
02723     result = RINEX_ReplaceDwithE( line_buffer, (unsigned)strlen(line_buffer) );
02724     if( result == FALSE )
02725       return FALSE;
02726 
02727     memset( str, 0, sizeof(char)*10*20 );  
02728     count = sscanf( line_buffer, "%*3c%19c%19c%19c%19c",
02729       str[0],
02730       str[1],
02731       str[2],
02732       str[3]
02733       );
02734     if( count != 4 )
02735       return FALSE;
02736 
02737     i = 0;
02738     if( sscanf( str[i], "%Lf", &eph.cuc ) != 1 )
02739       return FALSE;    
02740     i++;
02741     if( sscanf( str[i], "%Lf", &eph.ecc ) != 1 )
02742       return FALSE;
02743     i++;
02744     if( sscanf( str[i], "%Lf", &eph.cus ) != 1 )
02745       return FALSE;
02746     i++;
02747     if( sscanf( str[i], "%Lf", &eph.sqrta ) != 1 )
02748       return FALSE;
02749     i++;
02750 
02751 
02752     
02753     
02754 
02755     
02756     if( fgets(line_buffer, RINEX_LINEBUF_SIZE, fid) == NULL )
02757     {
02758       if( feof(fid) )
02759       {      
02760         break;
02761       }
02762       else
02763       {
02764         return FALSE;
02765       }
02766     }
02767     result = RINEX_ReplaceDwithE( line_buffer, (unsigned)strlen(line_buffer) );
02768     if( result == FALSE )
02769       return FALSE;
02770 
02771     memset( str, 0, sizeof(char)*10*20 );  
02772     count = sscanf( line_buffer, "%*3c%19c%19c%19c%19c",
02773       str[0],
02774       str[1],
02775       str[2],
02776       str[3]
02777       );
02778     if( count != 4 )
02779       return FALSE;
02780 
02781     i = 0;
02782     if( sscanf( str[i], "%Lf", &dtmp ) != 1 )
02783       return FALSE;    
02784     eph.toe = (unsigned)dtmp;
02785     i++;
02786     if( sscanf( str[i], "%Lf", &eph.cic ) != 1 )
02787       return FALSE;
02788     i++;
02789     if( sscanf( str[i], "%Lf", &eph.omega0 ) != 1 )
02790       return FALSE;
02791     i++;
02792     if( sscanf( str[i], "%Lf", &eph.cis ) != 1 )
02793       return FALSE;
02794     i++;
02795 
02796 
02797     
02798     
02799 
02800     
02801     if( fgets(line_buffer, RINEX_LINEBUF_SIZE, fid) == NULL )
02802     {
02803       if( feof(fid) )
02804       {      
02805         break;
02806       }
02807       else
02808       {
02809         return FALSE;
02810       }
02811     }
02812     result = RINEX_ReplaceDwithE( line_buffer, (unsigned)strlen(line_buffer) );
02813     if( result == FALSE )
02814       return FALSE;
02815 
02816     memset( str, 0, sizeof(char)*10*20 );  
02817     count = sscanf( line_buffer, "%*3c%19c%19c%19c%19c",
02818       str[0],
02819       str[1],
02820       str[2],
02821       str[3]
02822       );
02823     if( count != 4 )
02824       return FALSE;
02825 
02826     i = 0;
02827     if( sscanf( str[i], "%Lf", &eph.i0 ) != 1 )
02828       return FALSE;    
02829     i++;
02830     if( sscanf( str[i], "%Lf", &eph.crc ) != 1 )
02831       return FALSE;
02832     i++;
02833     if( sscanf( str[i], "%Lf", &eph.w ) != 1 )
02834       return FALSE;
02835     i++;
02836     if( sscanf( str[i], "%Lf", &eph.omegadot ) != 1 )
02837       return FALSE;
02838     i++;
02839 
02840 
02841     
02842     
02843 
02844     
02845     if( fgets(line_buffer, RINEX_LINEBUF_SIZE, fid) == NULL )
02846     {
02847       if( feof(fid) )
02848       {      
02849         break;
02850       }
02851       else
02852       {
02853         return FALSE;
02854       }
02855     }
02856     result = RINEX_ReplaceDwithE( line_buffer, (unsigned)strlen(line_buffer) );
02857     if( result == FALSE )
02858       return FALSE;
02859 
02860     memset( str, 0, sizeof(char)*10*20 );  
02861     count = sscanf( line_buffer, "%*3c%19c%19c%19c%19c",
02862       str[0],
02863       str[1],
02864       str[2],
02865       str[3]
02866       );
02867     if( count != 4 )
02868       return FALSE;
02869 
02870     i = 0;
02871     if( sscanf( str[i], "%Lf", &eph.idot ) != 1 )
02872       return FALSE;    
02873     i++;
02874     if( sscanf( str[i], "%Lf", &dtmp ) != 1 )
02875       return FALSE;
02876     eph.code_on_L2 = (unsigned char)dtmp;
02877     i++;
02878     if( sscanf( str[i], "%Lf", &dtmp ) != 1 )
02879       return FALSE;    
02880     eph.week = (unsigned short)dtmp;
02881     i++;
02882     if( sscanf( str[i], "%Lf", &dtmp ) != 1 )
02883       return FALSE;
02884     eph.L2_P_data_flag = (unsigned char)dtmp;
02885     i++;
02886 
02887     
02888     
02889 
02890     
02891     if( fgets(line_buffer, RINEX_LINEBUF_SIZE, fid) == NULL )
02892     {
02893       if( feof(fid) )
02894       {      
02895         break;
02896       }
02897       else
02898       {
02899         return FALSE;
02900       }
02901     }
02902     result = RINEX_ReplaceDwithE( line_buffer, (unsigned)strlen(line_buffer) );
02903     if( result == FALSE )
02904       return FALSE;
02905 
02906     memset( str, 0, sizeof(char)*10*20 );  
02907     count = sscanf( line_buffer, "%*3c%19c%19c%19c%19c",
02908       str[0],
02909       str[1],
02910       str[2],
02911       str[3]
02912       );
02913     if( count != 4 )
02914       return FALSE;
02915 
02916     i = 0;
02917     if( sscanf( str[i], "%Lf", &dtmp ) != 1 )
02918       return FALSE;    
02919     i++;
02920     
02921     result = RINEX_ConvertURA_meters_to_URA_index( dtmp, &eph.ura ); 
02922     if( result == FALSE )
02923       return FALSE;  
02924 
02925     if( sscanf( str[i], "%Lf", &dtmp ) != 1 )
02926       return FALSE;
02927     eph.health = (unsigned char)dtmp;
02928     i++;
02929     if( sscanf( str[i], "%Lf", &eph.tgd ) != 1 )
02930       return FALSE;    
02931     i++;
02932     if( sscanf( str[i], "%Lf", &dtmp ) != 1 )
02933       return FALSE;
02934     eph.iodc = (unsigned short)dtmp;
02935     i++;
02936 
02937     
02938     
02939 
02940     
02941     if( fgets(line_buffer, RINEX_LINEBUF_SIZE, fid) == NULL )
02942     {
02943       if( feof(fid) )
02944       {      
02945         break;
02946       }
02947       else
02948       {
02949         return FALSE;
02950       }
02951     }
02952     result = RINEX_ReplaceDwithE( line_buffer, (unsigned)strlen(line_buffer) );
02953     if( result == FALSE )
02954       return FALSE;
02955 
02956     memset( str, 0, sizeof(char)*10*20 );  
02957     count = sscanf( line_buffer, "%*3c%19c%19c",
02958       str[0],
02959       str[1]
02960       );
02961     if( count != 2 )
02962       return FALSE;
02963 
02964     i = 0;
02965     if( sscanf( str[i], "%Lf", &dtmp ) != 1 )
02966       return FALSE;    
02967     
02968     eph.tow = (unsigned)dtmp;
02969     itmp  = (int)eph.tow;
02970     itmp2 = (int)eph.toe;
02971     if( (itmp-itmp2) < -4*SECONDS_IN_DAY )
02972     {
02973       eph.tow_week = eph.week+1;
02974     }
02975     else
02976     {
02977       eph.tow_week = eph.week;
02978     }
02979 
02980     i++;
02981     if( sscanf( str[i], "%Lf", &dtmp ) != 1 )
02982       return FALSE;
02983     itmp = (int)dtmp;
02984     if( itmp <= 4 )
02985       eph.fit_interval_flag = 0;
02986     else
02987       eph.fit_interval_flag = 1;
02988     
02989     ephemeris_array[ephemeris_array_index] = eph;
02990     ephemeris_array_index++;    
02991 
02992     if( ephemeris_array_index == 0 && iono_model->isValid == FALSE )
02993     {
02994       
02995       iono_model->week = eph.week;
02996       iono_model->tow = eph.toe;
02997       iono_model->isValid = TRUE;
02998     }    
02999   }
03000 
03001   *length_ephemeris_array = ephemeris_array_index;
03002 
03003   return TRUE;
03004 }
03005 
03006 
03007 
03008 BOOL RINEX_ReplaceDwithE( char *str, const unsigned length )
03009 {
03010   unsigned i = 0;
03011   if( str == NULL )
03012     return FALSE;
03013   if( length == 0 )
03014     return FALSE;
03015 
03016   for( i = 0; i < length; i++ )
03017   {
03018     if( str[i] == 'D' || str[i] == 'd' )
03019       str[i] = 'E';
03020   }
03021   return TRUE;
03022 }
03023 
03024 
03025 BOOL RINEX_ConvertURA_meters_to_URA_index( 
03026   double ura_m,         
03027   unsigned char *ura    
03028   )
03029 {
03030   unsigned char i = 0;
03031 
03032   if( ura == FALSE )
03033     return FALSE;
03034 
03035   *ura = 15; 
03036 
03037   for( i = 0; i < 16; i++ )
03038   {
03039     if( ura_m >= RINEX_MIN_URA[i] && ura_m < RINEX_MAX_URA[i] )
03040     {
03041       *ura = i;
03042       break;
03043     }
03044   }
03045 
03046   return TRUE;
03047 }
03048 
03049 
03050 BOOL RINEX_DecodeFileName(
03051   const char *filepath,            
03052   char *station_name,              
03053   unsigned short *dayofyear,       
03054   unsigned char *file_sequence_nr, 
03055   unsigned short *year,            
03056   RINEX_enumFileType *filetype     
03057   )
03058 {
03059   char str[RINEX_LINEBUF_SIZE];
03060   char filename[RINEX_LINEBUF_SIZE];
03061   size_t length = 0;
03062   char *pch = NULL;
03063   char filetype_char = 0;
03064   unsigned count = 0;
03065   int itmp[3];
03066 
03067   
03068   if( filepath == NULL )
03069     return FALSE;
03070   if( station_name == NULL )
03071     return FALSE;
03072   if( dayofyear == NULL )
03073     return FALSE;
03074   if( file_sequence_nr == NULL )
03075     return FALSE;
03076   if( year == NULL )
03077     return FALSE;
03078   if( filetype == NULL )
03079     return FALSE;
03080 
03081   station_name[0] = station_name[1] = station_name[2] = station_name[3] = station_name[4]  = '\0';
03082 
03083   length = strlen( filepath );
03084   if( length >= RINEX_LINEBUF_SIZE )
03085     return FALSE;
03086 
03087   
03088   strcpy( str, filepath );
03089 
03090   
03091   pch = strtok( str,"\\/" );
03092   while (pch != NULL)
03093   {
03094     strcpy( filename, pch );
03095     pch = strtok( NULL, "\\/" );
03096   }
03097 
03098   length = strlen( filename );
03099   if( length != 12 )
03100     return FALSE;
03101 
03102   
03103   count = sscanf( filename, "%4c%3d%1d%*c%2d%c", 
03104     station_name,
03105     &(itmp[0]),
03106     &(itmp[1]),
03107     &(itmp[2]),
03108     &filetype_char
03109     );
03110   if( count != 5 )
03111     return FALSE;
03112 
03113   filetype_char = (char)toupper(filetype_char);
03114 
03115   *dayofyear = (unsigned short)itmp[0];
03116   *file_sequence_nr = (unsigned char)itmp[1];
03117   *year = (unsigned short)itmp[2];
03118   
03119 
03120   if( *year >= 80 && *year < 2000 )
03121   {
03122     *year += 1900;
03123   }
03124   else if( *year >= 0 && *year < 79 )
03125   {
03126     *year += 2000;
03127   }
03128   else
03129   {
03130     return FALSE;
03131   }
03132 
03133   *filetype = (RINEX_enumFileType)filetype_char;
03134 
03135   switch( *filetype )
03136   {
03137   case RINEX_FILE_TYPE_OBS:
03138   case RINEX_FILE_TYPE_GPS_NAV:
03139   case RINEX_FILE_TYPE_MET:
03140   case RINEX_FILE_TYPE_GLO_NAV:
03141   case RINEX_FILE_TYPE_GEO_NAV:
03142   case RINEX_FILE_TYPE_GAL_NAV:
03143   case RINEX_FILE_TYPE_MIXED_NAV:
03144   case RINEX_FILE_TYPE_SBAS:
03145   case RINEX_FILE_TYPE_CLK:
03146   case RINEX_FILE_TYPE_SUMMARY:
03147     {
03148     return TRUE;
03149     }
03150   default:
03151     {
03152       return FALSE;
03153     }
03154   }
03155 }
03156 
03157 
03158 BOOL RINEX_GetKlobucharIonoParametersFromNavFile(
03159   const char *filepath,             
03160   GNSS_structKlobuchar *iono_model  
03161   )
03162 {
03163   char RINEX_header[RINEX_HEADER_SIZE];
03164   unsigned RINEX_header_length = 0;
03165   double version = 0.0;
03166   RINEX_enumFileType file_type = RINEX_FILE_TYPE_UNKNOWN;
03167   char line_buffer[RINEX_LINEBUF_SIZE];
03168   unsigned nr_lines = 0;
03169   BOOL result;
03170   double dtmp = 0.0;
03171   
03172   char station_name[5];
03173   unsigned short dayofyear = 0;
03174   unsigned char file_sequence_nr = 0;
03175   unsigned short year = 0;
03176 
03177   double header_A0; 
03178   double header_A1; 
03179   int header_week;  
03180   int header_tow;   
03181   
03182   memset( iono_model, 0, sizeof(GNSS_structKlobuchar) );
03183 
03184   if( filepath == NULL )
03185     return FALSE;
03186   if( iono_model == NULL )
03187     return FALSE;
03188 
03189 
03190   result = RINEX_GetHeader( 
03191     filepath,
03192     RINEX_header,
03193     RINEX_HEADER_SIZE,
03194     &RINEX_header_length,
03195     &version,
03196     &file_type
03197     );
03198   if( result == FALSE )
03199     return FALSE;
03200 
03201   if( file_type != RINEX_FILE_TYPE_GPS_NAV )
03202     return FALSE;
03203 
03204   result = RINEX_get_header_lines(
03205     RINEX_header,
03206     RINEX_header_length,
03207     "ION ALPHA",
03208     line_buffer,
03209     RINEX_LINEBUF_SIZE,
03210     &nr_lines
03211     );
03212   if( result == FALSE )
03213     return FALSE;
03214   if( nr_lines == 1 )
03215   {
03216     result = RINEX_ReplaceDwithE( line_buffer, (unsigned)strlen(line_buffer) );
03217     if( result == FALSE )
03218       return FALSE;
03219 
03220     if( sscanf( line_buffer, "%Lf %Lf %Lf %Lf", 
03221       &(iono_model->alpha0), 
03222       &(iono_model->alpha1),
03223       &(iono_model->alpha2),
03224       &(iono_model->alpha3) ) != 4 )
03225     {
03226       return FALSE; 
03227     }
03228     result = RINEX_get_header_lines(
03229       RINEX_header,
03230       RINEX_header_length,
03231       "ION BETA",
03232       line_buffer,
03233       RINEX_LINEBUF_SIZE,
03234       &nr_lines
03235       );
03236     if( result == FALSE )
03237       return FALSE;
03238     if( nr_lines != 1 )
03239       return FALSE; 
03240 
03241     result = RINEX_ReplaceDwithE( line_buffer, (unsigned)strlen(line_buffer) );
03242     if( result == FALSE )
03243       return FALSE;
03244 
03245     if( sscanf( line_buffer, "%Lf %Lf %Lf %Lf", 
03246       &(iono_model->beta0), 
03247       &(iono_model->beta1),
03248       &(iono_model->beta2),
03249       &(iono_model->beta3) ) != 4 )
03250     {
03251       return FALSE; 
03252     }
03253 
03254     result = RINEX_get_header_lines(
03255       RINEX_header,
03256       RINEX_header_length,
03257       "DELTA-UTC: A0,A1,T,W",
03258       line_buffer,
03259       RINEX_LINEBUF_SIZE,
03260       &nr_lines
03261       );
03262     if( result == FALSE )
03263       return FALSE;
03264     if( nr_lines == 1 )
03265     {
03266       result = RINEX_ReplaceDwithE( line_buffer, (unsigned)strlen(line_buffer) );
03267       if( result == FALSE )
03268         return FALSE;
03269 
03270       if( sscanf( line_buffer, "%Lf %Lf %d %d",
03271         &header_A0,
03272         &header_A1,
03273         &header_tow,
03274         &header_week ) == 4 )
03275       {
03276         iono_model->week = (unsigned short) header_week;
03277         iono_model->tow = header_tow;
03278         iono_model->isValid = TRUE;
03279       }
03280     }
03281 
03282     if( iono_model->isValid == FALSE )
03283     {
03284       
03285       result = RINEX_DecodeFileName( filepath, station_name, &dayofyear, &file_sequence_nr, &year, &file_type );
03286       if( result == TRUE )
03287       {
03288         result = TIMECONV_GetGPSTimeFromYearAndDayOfYear(
03289           year,
03290           dayofyear,
03291           &(iono_model->week),
03292           &dtmp
03293           );
03294         if( result == FALSE )
03295           return FALSE;
03296         iono_model->tow = (unsigned)dtmp;
03297         iono_model->isValid = TRUE;
03298       }
03299       else
03300       {
03301         
03302         iono_model->isValid = FALSE;
03303       }
03304     }
03305   }
03306 
03307   return TRUE;
03308 }
03309