Changeset 270 in ntrip
- Timestamp:
- Nov 3, 2006, 12:50:11 PM (18 years ago)
- Location:
- trunk/rtcm3torinex
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/rtcm3torinex/rtcm3torinex.c
r269 r270 1 1 /* 2 2 Converter for RTCM3 data to RINEX. 3 $Id: rtcm3torinex.c,v 1. 6 2006/11/02 13:34:00stoecker Exp $3 $Id: rtcm3torinex.c,v 1.7 2006/11/02 13:54:43 stoecker Exp $ 4 4 Copyright (C) 2005-2006 by Dirk Stoecker <stoecker@euronik.eu> 5 5 … … 50 50 51 51 /* CVS revision and version */ 52 static char revisionstr[] = "$Revision: 1. 6$";52 static char revisionstr[] = "$Revision: 1.7 $"; 53 53 54 54 static uint32_t CRC24(long size, const unsigned char *buf) … … 145 145 #define SKIPBITS(b) { LOADBITS(b) numbits -= (b); } 146 146 147 struct leapseconds { /* specify the day of leap second */ 148 int day; /* this is the day, where 23:59:59 exists 2 times */ 149 int month; /* not the next day! */ 150 int year; 151 int taicount; 152 }; 153 static const int months[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; 154 static const struct leapseconds leap[] = { 155 /*{31, 12, 1971, 11},*/ 156 /*{31, 12, 1972, 12},*/ 157 /*{31, 12, 1973, 13},*/ 158 /*{31, 12, 1974, 14},*/ 159 /*{31, 12, 1975, 15},*/ 160 /*{31, 12, 1976, 16},*/ 161 /*{31, 12, 1977, 17},*/ 162 /*{31, 12, 1978, 18},*/ 163 /*{31, 12, 1979, 19},*/ 164 {30, 06, 1981,20}, 165 {30, 06, 1982,21}, 166 {30, 06, 1983,22}, 167 {30, 06, 1985,23}, 168 {31, 12, 1987,24}, 169 {31, 12, 1989,25}, 170 {31, 12, 1990,26}, 171 {30, 06, 1992,27}, 172 {30, 06, 1993,28}, 173 {30, 06, 1994,29}, 174 {31, 12, 1995,30}, 175 {30, 06, 1997,31}, 176 {31, 12, 1998,32}, 177 {31, 12, 2005,33}, 178 {0,0,0,0} /* end marker */ 179 }; 180 #define GPSLEAPSTART 19 /* 19 leap seconds existed at 6.1.1980 */ 181 182 static int longyear(int year, int month) 183 { 184 if(!(year % 4) && (!(year % 400) || (year % 100))) 185 { 186 if(!month || month == 2) 187 return 1; 188 } 189 return 0; 190 } 191 192 static int gnumleap(int year, int month, int day) 193 { 194 int ls = 0; 195 const struct leapseconds *l; 196 197 for(l = leap; l->taicount && year >= l->year; ++l) 198 { 199 if(year > l->year || month > l->month || day > l->day) 200 ls = l->taicount - GPSLEAPSTART; 201 } 202 return ls; 203 } 204 205 static void updatetime(int *week, int *tow, int tk) 206 { 207 int y,m,d,k,l; 208 unsigned int j = *week*(7*24*60*60) + *tow + 5*24*60*60+3*60*60; 209 int glo_daynumber = 0, glo_timeofday; 210 for(y = 1980; j >= (unsigned int)(k = (l = (365+longyear(y,0)))*24*60*60) 211 + gnumleap(y+1,1,1); ++y) 212 { 213 j -= k; glo_daynumber += l; 214 } 215 for(m = 1; j >= (unsigned int)(k = (l = months[m]+longyear(y, m))*24*60*60) 216 + gnumleap(y, m+1, 1); ++m) 217 { 218 j -= k; glo_daynumber += l; 219 } 220 for(d = 1; j >= 24UL*60UL*60UL + gnumleap(y, m, d+1); ++d) 221 j -= 24*60*60; 222 glo_daynumber -= 16*365+4-d; 223 glo_timeofday = j-gnumleap(y, m, d); 224 225 if(tk < 5*60*1000 && glo_timeofday > 23*60*60) 226 *tow += 24*60*60; 227 else if(glo_timeofday < 5*60 && tk > 23*60*60*1000) 228 *tow -= 24*60*60; 229 *tow += tk/1000-glo_timeofday; 230 if(*tow < 0) {*tow += 24*60*60*7; --*week; } 231 if(*tow >= 24*60*60*7) {*tow -= 24*60*60*7; ++*week; } 232 } 233 147 234 int RTCM3Parser(struct RTCM3ParserData *handle) 148 235 { … … 155 242 uint64_t numbits = 0, bitfield = 0; 156 243 int size = handle->size, type; 244 int syncf, old = 0; 157 245 unsigned char *data = handle->Message+3; 158 246 … … 171 259 lastlockl1[i] = lastlockl2[i] = 0; 172 260 173 gnss = &handle->Data; 174 memset(gnss, 0, sizeof(*gnss)); 261 gnss = &handle->DataNew; 175 262 176 263 SKIPBITS(12) /* id */ … … 179 266 ++handle->GPSWeek; 180 267 handle->GPSTOW = i/1000; 268 if(gnss->week && (gnss->timeofweek != i || gnss->week 269 != handle->GPSWeek)) 270 { 271 handle->Data = *gnss; 272 memset(gnss, 0, sizeof(*gnss)); 273 old = 1; 274 } 181 275 gnss->timeofweek = i; 182 276 gnss->week = handle->GPSWeek; 183 277 184 SKIPBITS(1) /* sync */278 GETBITS(syncf,1) /* sync */ 185 279 GETBITS(i,5) 186 280 gnss->numsats = i; … … 299 393 handle->lastlockl2[i] = lastlockl2[i]; 300 394 } 301 if(wasamb) /* not RINEX compatible without */ 302 ret = 1; 303 else 304 ret = 2; 395 if(!syncf && !old) 396 { 397 handle->Data = *gnss; 398 memset(gnss, 0, sizeof(*gnss)); 399 } 400 if(!syncf || old) 401 { 402 if(wasamb) /* not RINEX compatible without */ 403 ret = 1; 404 else 405 ret = 2; 406 } 305 407 } 306 408 break; 409 case 1009: case 1010: case 1011: case 1012: 410 { 411 int lastlockl1[64]; 412 int lastlockl2[64]; 413 struct gnssdata *gnss; 414 int i, num; 415 int wasamb=0; 416 417 for(i = 0; i < 64; ++i) 418 lastlockl1[i] = lastlockl2[i] = 0; 419 420 gnss = &handle->DataNew; 421 422 SKIPBITS(12) /* id */; 423 GETBITS(i,27) /* tk */ 424 425 updatetime(&handle->GPSWeek, &handle->GPSTOW, i); 426 i = handle->GPSTOW*1000; 427 if(gnss->week && (gnss->timeofweek != i || gnss->week 428 != handle->GPSWeek)) 429 { 430 handle->Data = *gnss; 431 memset(gnss, 0, sizeof(*gnss)); 432 old = 1; 433 } 434 435 gnss->timeofweek = i; 436 gnss->week = handle->GPSWeek; 437 438 GETBITS(syncf,1) /* sync */ 439 GETBITS(i,5) 440 gnss->numsats += i; 441 442 SKIPBITS(4) /* smind, smint */ 443 444 for(num = gnss->numsats-i; num < gnss->numsats; ++num) 445 { 446 int sv, code, l1range, c,l,s,ce,le,se,amb=0; 447 448 GETBITS(sv, 6) 449 if(!sv || sv > 24) 450 { 451 --num; --gnss->numsats; 452 } 453 else 454 { 455 int freq; 456 gnss->satellites[num] = sv-1 + PRN_GLONASS_START; 457 /* L1 */ 458 GETBITS(code, 1) 459 GETBITS(freq, 5) 460 if(code) 461 { 462 c = GNSSDF_P1DATA; ce = GNSSENTRY_P1DATA; 463 l = GNSSDF_L1PDATA; le = GNSSENTRY_L1PDATA; 464 s = GNSSDF_S1PDATA; se = GNSSENTRY_S1PDATA; 465 } 466 else 467 { 468 c = GNSSDF_C1DATA; ce = GNSSENTRY_C1DATA; 469 l = GNSSDF_L1CDATA; le = GNSSENTRY_L1CDATA; 470 s = GNSSDF_S1CDATA; se = GNSSENTRY_S1CDATA; 471 } 472 GETBITS(l1range, 25) 473 if(l1range != 0x80000) 474 { 475 gnss->dataflags[num] |= c; 476 gnss->measdata[num][ce] = l1range*0.02; 477 } 478 GETBITSSIGN(i, 20) 479 if(i != 0x80000) 480 { 481 gnss->dataflags[num] |= l; 482 gnss->measdata[num][le] = l1range*0.02+i*0.0005; 483 } 484 GETBITS(i, 7) 485 lastlockl1[sv] = i; 486 if(handle->lastlockl1[sv] > i) 487 gnss->dataflags[num] |= GNSSDF_LOCKLOSSL1; 488 if(type == 1010 || type == 1012) 489 { 490 GETBITS(amb,7) 491 if(amb && (gnss->dataflags[num] & c)) 492 { 493 gnss->measdata[num][ce] += amb*599584.916; 494 gnss->measdata[num][le] += amb*599584.916; 495 ++wasamb; 496 } 497 GETBITS(i, 8) 498 if(i) 499 { 500 gnss->dataflags[num] |= s; 501 gnss->measdata[num][se] = i*0.25; 502 i /= 4*4; 503 if(i > 9) i = 9; 504 else if(i < 1) i = 1; 505 gnss->snrL1[num] = i; 506 } 507 } 508 gnss->measdata[num][le] /= GLO_WAVELENGTH_L1(freq-7); 509 if(type == 1011 || type == 1012) 510 { 511 /* L2 */ 512 GETBITS(code,2) 513 if(code) 514 { 515 c = GNSSDF_P2DATA; ce = GNSSENTRY_P2DATA; 516 l = GNSSDF_L2PDATA; le = GNSSENTRY_L2PDATA; 517 s = GNSSDF_S2PDATA; se = GNSSENTRY_S2PDATA; 518 } 519 else 520 { 521 c = GNSSDF_C2DATA; ce = GNSSENTRY_C2DATA; 522 l = GNSSDF_L2CDATA; le = GNSSENTRY_L2CDATA; 523 s = GNSSDF_S2CDATA; se = GNSSENTRY_S2CDATA; 524 } 525 GETBITSSIGN(i,14) 526 if(i != 0x2000) 527 { 528 gnss->dataflags[num] |= c; 529 gnss->measdata[num][ce] = l1range*0.02+i*0.02 530 +amb*599584.916; 531 } 532 GETBITSSIGN(i,20) 533 if(i != 0x80000) 534 { 535 gnss->dataflags[num] |= l; 536 gnss->measdata[num][le] = l1range*0.02+i*0.0005 537 +amb*599584.915; 538 } 539 GETBITS(i,7) 540 lastlockl2[sv] = i; 541 if(handle->lastlockl2[sv] > i) 542 gnss->dataflags[num] |= GNSSDF_LOCKLOSSL2; 543 if(type == 1012) 544 { 545 GETBITS(i, 8) 546 if(i) 547 { 548 gnss->dataflags[num] |= s; 549 gnss->measdata[num][se] = i*0.25; 550 i /= 4*4; 551 if(i > 9) i = 9; 552 else if(i < 1) i = 1; 553 gnss->snrL2[num] = i; 554 } 555 } 556 gnss->measdata[num][le] /= GLO_WAVELENGTH_L2(freq-7); 557 } 558 } 559 } 560 for(i = 0; i < 64; ++i) 561 { 562 handle->lastlockl1[i] = lastlockl1[i]; 563 handle->lastlockl2[i] = lastlockl2[i]; 564 } 565 if(!syncf && !old) 566 { 567 handle->Data = *gnss; 568 memset(gnss, 0, sizeof(*gnss)); 569 } 570 if(!syncf || old) 571 { 572 if(wasamb) /* not RINEX compatible without */ 573 ret = 1; 574 else 575 ret = 2; 576 } 577 } 578 break; 307 579 } 308 580 } … … 310 582 } 311 583 312 static int longyear(int year, int month) 313 { 314 if(!(year % 4) && (!(year % 400) || (year % 100))) 315 { 316 if(!month || month == 2) 317 return 1; 318 } 319 return 0; 320 } 321 322 void converttime(struct converttimeinfo *c, int week, int tow) 323 { 324 /* static variables */ 325 static const int months[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; 326 584 struct Header 585 { 586 const char *version; 587 const char *pgm; 588 const char *marker; 589 const char *observer; 590 const char *receiver; 591 const char *antenna; 592 const char *position; 593 const char *antennaposition; 594 const char *wavelength; 595 const char *typesofobs; /* should not be modified outside */ 596 const char *timeoffirstobs; /* should not be modified outside */ 597 }; 598 599 #define MAXHEADERLINES 50 600 #define MAXHEADERBUFFERSIZE 4096 601 struct HeaderData 602 { 603 union 604 { 605 struct Header named; 606 const char *unnamed[MAXHEADERLINES]; 607 } data; 608 int numheaders; 609 }; 610 611 struct converttimeinfo { 612 int second; /* seconds of GPS time [0..59] */ 613 int minute; /* minutes of GPS time [0..59] */ 614 int hour; /* hour of GPS time [0..24] */ 615 int day; /* day of GPS time [1..28..30(31)*/ 616 int month; /* month of GPS time [1..12]*/ 617 int year; /* year of GPS time [1980..] */ 618 }; 619 620 static void converttime(struct converttimeinfo *c, int week, int tow) 621 { 327 622 int i, k, doy, j; /* temporary variables */ 328 623 j = week*(7*24*60*60) + tow + 5*24*60*60; … … 342 637 c->day = doy - j; 343 638 } 344 345 struct Header346 {347 const char *version;348 const char *pgm;349 const char *marker;350 const char *observer;351 const char *receiver;352 const char *antenna;353 const char *position;354 const char *antennaposition;355 const char *wavelength;356 const char *typesofobs; /* should not be modified outside */357 const char *timeoffirstobs; /* should not be modified outside */358 };359 360 #define MAXHEADERLINES 50361 #define MAXHEADERBUFFERSIZE 4096362 struct HeaderData363 {364 union365 {366 struct Header named;367 const char *unnamed[MAXHEADERLINES];368 } data;369 int numheaders;370 };371 639 372 640 void HandleHeader(struct RTCM3ParserData *Parser) … … 647 915 && Parser->Data.satellites[i] <= PRN_GLONASS_END) 648 916 printf("R%02d", Parser->Data.satellites[i] - (PRN_GLONASS_START-1)); 917 else if(Parser->Data.satellites[i] >= PRN_WAAS_START 918 && Parser->Data.satellites[i] <= PRN_WAAS_END) 919 printf("S%02d", Parser->Data.satellites[i] - PRN_WAAS_START); 649 920 else 650 921 printf("%3d", Parser->Data.satellites[i]); … … 692 963 693 964 #ifndef NO_RTCM3_MAIN 694 static char datestr[] = "$Date: 2006/11/02 13: 34:00$";965 static char datestr[] = "$Date: 2006/11/02 13:54:43 $"; 695 966 696 967 /* The string, which is send as agent in HTTP request */ … … 775 1046 {0,0,0,0}}; 776 1047 #endif 777 #define ARGOPT "d:hp:r:s:u:f:" 1048 #define ARGOPT "-d:hp:r:s:u:f:" 1049 1050 static const char *geturl(const char *url, struct Args *args) 1051 { 1052 static char buf[1000]; 1053 static char *Buffer = buf; 1054 static char *Bufend = buf+sizeof(buf); 1055 1056 if(strncmp("ntrip:", url, 6)) 1057 return "URL must start with 'ntrip:'."; 1058 url += 6; /* skip ntrip: */ 1059 1060 if(*url != '@' && *url != '/') 1061 { 1062 /* scan for mountpoint */ 1063 args->data = Buffer; 1064 while(*url && *url != '@' && *url != '/' && Buffer != Bufend) 1065 *(Buffer++) = *(url++); 1066 if(Buffer == args->data) 1067 return "Mountpoint required."; 1068 else if(Buffer >= Bufend-1) 1069 return "Parsing buffer too short."; 1070 *(Buffer++) = 0; 1071 } 1072 1073 if(*url == '/') /* username and password */ 1074 { 1075 ++url; 1076 args->user = Buffer; 1077 while(*url && *url != '@' && *url != ':' && Buffer != Bufend) 1078 *(Buffer++) = *(url++); 1079 if(Buffer == args->user) 1080 return "Username cannot be empty."; 1081 else if(Buffer >= Bufend-1) 1082 return "Parsing buffer too short."; 1083 *(Buffer++) = 0; 1084 1085 if(*url == ':') ++url; 1086 1087 args->password = Buffer; 1088 while(*url && *url != '@' && Buffer != Bufend) 1089 *(Buffer++) = *(url++); 1090 if(Buffer == args->password) 1091 return "Password cannot be empty."; 1092 else if(Buffer >= Bufend-1) 1093 return "Parsing buffer too short."; 1094 *(Buffer++) = 0; 1095 } 1096 1097 if(*url == '@') /* server */ 1098 { 1099 ++url; 1100 args->server = Buffer; 1101 while(*url && *url != ':' && Buffer != Bufend) 1102 *(Buffer++) = *(url++); 1103 if(Buffer == args->server) 1104 return "Servername cannot be empty."; 1105 else if(Buffer >= Bufend-1) 1106 return "Parsing buffer too short."; 1107 *(Buffer++) = 0; 1108 1109 if(*url == ':') 1110 { 1111 char *s2 = 0; 1112 args->port = strtol(++url, &s2, 10); 1113 if(*s2 || args->port <= 0 || args->port > 0xFFFF) 1114 return "Illegal port number."; 1115 url = s2; 1116 } 1117 } 1118 1119 return *url ? "Garbage at end of server string." : 0; 1120 } 778 1121 779 1122 static int getargs(int argc, char **argv, struct Args *args) … … 811 1154 res = 0; 812 1155 break; 1156 case 1: 1157 { 1158 const char *err; 1159 if((err = geturl(optarg, args))) 1160 { 1161 fprintf(stderr, "%s\n\n", err); 1162 res = 0; 1163 } 1164 } 1165 break; 813 1166 case -1: break; 814 1167 } … … 835 1188 " -r " LONG_OPT("--port ") "the server port number (default 80)\n" 836 1189 " -u " LONG_OPT("--user ") "the user name\n" 837 , revisionstr, datestr, argv[0]); 1190 "or using an URL:\n%s ntrip:mountpoint[/username[:password]][@server[:port]]\n" 1191 , revisionstr, datestr, argv[0], argv[0]); 838 1192 exit(1); 839 1193 } -
trunk/rtcm3torinex/rtcm3torinex.h
r268 r270 4 4 /* 5 5 Converter for RTCM3 data to RINEX. 6 $Id: rtcm3torinex. c,v 1.5 2006/08/29 15:42:36stoecker Exp $6 $Id: rtcm3torinex.h,v 1.1 2006/11/02 13:34:00 stoecker Exp $ 7 7 Copyright (C) 2005-2006 by Dirk Stoecker <stoecker@euronik.eu> 8 8 … … 27 27 #define PRN_GLONASS_START 38 28 28 #define PRN_GLONASS_END 61 29 #define PRN_WAAS_START 120 30 #define PRN_WAAS_END 138 29 31 30 32 #define GNSSENTRY_C1DATA 0 … … 77 79 #define RINEXENTRY_NUMBER 10 78 80 79 #define LIGHTSPEED 2.99792458e8 /* m/sec 81 #define LIGHTSPEED 2.99792458e8 /* m/sec */ 80 82 #define GPS_FREQU_L1 1575420000.0 /* Hz */ 81 83 #define GPS_FREQU_L2 1227600000.0 /* Hz */ 82 84 #define GPS_WAVELENGTH_L1 (LIGHTSPEED / GPS_FREQU_L1) /* m */ 83 85 #define GPS_WAVELENGTH_L2 (LIGHTSPEED / GPS_FREQU_L2) /* m */ 86 87 #define GLO_FREQU_L1_BASE 1602000000.0 /* Hz */ 88 #define GLO_FREQU_L2_BASE 1246000000.0 /* Hz */ 89 #define GLO_FREQU_L1_STEP 562500.0 /* Hz */ 90 #define GLO_FREQU_L2_STEP 437500.0 /* Hz */ 91 #define GLO_FREQU_L1(a) (GLO_FREQU_L1_BASE+(a)*GLO_FREQU_L1_STEP) 92 #define GLO_FREQU_L2(a) (GLO_FREQU_L2_BASE+(a)*GLO_FREQU_L2_STEP) 93 #define GLO_WAVELENGTH_L1(a) (LIGHTSPEED / GLO_FREQU_L1(a)) /* m */ 94 #define GLO_WAVELENGTH_L2(a) (LIGHTSPEED / GLO_FREQU_L2(a)) /* m */ 84 95 85 96 /* unimportant, only for approx. time needed */ … … 110 121 int GPSTOW; /* in seconds */ 111 122 struct gnssdata Data; 123 struct gnssdata DataNew; 112 124 int size; 113 125 int lastlockl1[64]; … … 121 133 }; 122 134 123 struct converttimeinfo {124 int second; /* seconds of GPS time [0..59] */125 int minute; /* minutes of GPS time [0..59] */126 int hour; /* hour of GPS time [0..24] */127 int day; /* day of GPS time [1..28..30(31)*/128 int month; /* month of GPS time [1..12]*/129 int year; /* year of GPS time [1980..] */130 };131 132 135 void HandleHeader(struct RTCM3ParserData *Parser); 133 136 int RTCM3Parser(struct RTCM3ParserData *handle); 134 137 void HandleByte(struct RTCM3ParserData *Parser, unsigned int byte); 135 void converttime(struct converttimeinfo *c, int week, int tow);136 138 137 139 #endif /* RTCM3TORINEX_H */
Note:
See TracChangeset
for help on using the changeset viewer.