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