Changeset 494 in ntrip
- Timestamp:
- Sep 18, 2007, 9:09:07 AM (18 years ago)
- Location:
- trunk/ntripclient
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/ntripclient/README
r484 r494 61 61 Call the program with following arguments: 62 62 63 ntripclient -d mountpoint 64 -s Ntrip Broadcaster IP adress 65 -p password 66 -r Ntrip Broadcaster Port number 67 -u username 68 -n NMEA string for sending to server 69 -b output bitrate 63 ntripclient -s server -u user ... 64 -d --data the requested data set 65 -s --server the server name or address 66 -p --password the login password 67 -r --port the server port number (default 2101) 68 -u --user the user name 69 -n --nmea NMEA string for sending to server 70 -b --bitrate output bitrate 71 -S --proxyhost proxy name or address 72 -R --proxyport proxy port, optional (default 2101) 73 -M --mode mode for data request 74 Valid modes are: 75 1, h, http NTRIP Version 2.0 Caster in TCP/IP mode 76 2, r, rtsp NTRIP Version 2.0 Caster in RTSP/RTP mode 77 3, n, ntrip1 NTRIP Version 1.0 Caster 78 4, a, auto automatic detection (default) 70 79 71 80 or using an URL: 72 ./ntripclient ntrip:mountpoint[/username[:password]][@server[:port]][;nmea]81 ntripclient ntrip:mountpoint[/username[:password]][@[server][:port][@proxy[:port]]][;nmea] 73 82 74 83 … … 96 105 --------------------------------- 97 106 The current Internet address of the Ntrip Broadcaster is 98 www.euref-ip.net. The port number is 80.107 www.euref-ip.net. The port number is 2101. 99 108 100 109 Disclaimer -
trunk/ntripclient/ntripclient.c
r484 r494 1 1 /* 2 2 Easy example NTRIP client for POSIX. 3 $Id: ntripclient.c,v 1. 292007/08/30 07:35:13stoecker Exp $3 $Id: ntripclient.c,v 1.30 2007/08/30 07:38:24 stoecker Exp $ 4 4 Copyright (C) 2003-2005 by Dirk Stoecker <soft@dstoecker.de> 5 5 … … 45 45 46 46 /* CVS revision and version */ 47 static char revisionstr[] = "$Revision: 1.29 $"; 48 static char datestr[] = "$Date: 2007/08/30 07:35:13 $"; 47 static char revisionstr[] = "$Revision: 1.30 $"; 48 static char datestr[] = "$Date: 2007/08/30 07:38:24 $"; 49 50 enum MODE { HTTP = 1, RTSP = 2, NTRIP1 = 3, AUTO = 4, END }; 49 51 50 52 struct Args 51 53 { 52 54 const char *server; 53 intport;55 const char *port; 54 56 const char *user; 57 const char *proxyhost; 58 const char *proxyport; 55 59 const char *password; 56 60 const char *nmea; 57 61 const char *data; 58 62 int bitrate; 63 int mode; 59 64 }; 65 66 60 67 61 68 /* option parsing */ … … 70 77 { "password", required_argument, 0, 'p'}, 71 78 { "port", required_argument, 0, 'r'}, 79 { "proxyport", required_argument, 0, 'R'}, 80 { "proxyhost", required_argument, 0, 'S'}, 72 81 { "user", required_argument, 0, 'u'}, 73 82 { "nmea", required_argument, 0, 'n'}, … … 75 84 {0,0,0,0}}; 76 85 #endif 77 #define ARGOPT "-d:bhp:r:s:u:n:" 86 #define ARGOPT "-d:bhp:r:s:u:n:S:R:M:" 78 87 79 88 #ifdef __GNUC__ … … 86 95 fprintf(stderr, "ERROR: more than %d seconds no activity\n", ALARMTIME); 87 96 exit(1); 97 } 98 99 int stop = 0; 100 #ifdef __GNUC__ 101 static void sighandler_int(int sig __attribute__((__unused__))) 102 #else /* __GNUC__ */ 103 static void sighandler_alarm(int sig) 104 #endif /* __GNUC__ */ 105 { 106 alarm(2); 107 stop = 1; 88 108 } 89 109 … … 138 158 { 139 159 ++url; 140 args->server = Buffer; 141 while(*url && *url != ':' && *url != ';' && Buffer != Bufend) 142 *(Buffer++) = *(url++); 143 if(Buffer == args->server) 144 return "Servername cannot be empty."; 145 else if(Buffer >= Bufend-1) 146 return "Parsing buffer too short."; 147 *(Buffer++) = 0; 160 if(*url != '@' && *url != ':') 161 { 162 args->server = Buffer; 163 while(*url && *url != '@' && *url != ':' && *url != ';' && Buffer != Bufend) 164 *(Buffer++) = *(url++); 165 if(Buffer == args->server) 166 return "Servername cannot be empty."; 167 else if(Buffer >= Bufend-1) 168 return "Parsing buffer too short."; 169 *(Buffer++) = 0; 170 } 148 171 149 172 if(*url == ':') 150 173 { 151 char *s2 = 0; 152 args->port = strtol(++url, &s2, 10); 153 if((*s2 && *s2 != ';') || args->port <= 0 || args->port > 0xFFFF) 154 return "Illegal port number."; 155 url = s2; 174 ++url; 175 args->port = Buffer; 176 while(*url && *url != '@' && *url != ';' && Buffer != Bufend) 177 *(Buffer++) = *(url++); 178 if(Buffer == args->port) 179 return "Port cannot be empty."; 180 else if(Buffer >= Bufend-1) 181 return "Parsing buffer too short."; 182 *(Buffer++) = 0; 183 } 184 185 if(*url == '@') /* proxy */ 186 { 187 ++url; 188 args->proxyhost = Buffer; 189 while(*url && *url != ':' && *url != ';' && Buffer != Bufend) 190 *(Buffer++) = *(url++); 191 if(Buffer == args->proxyhost) 192 return "Proxy servername cannot be empty."; 193 else if(Buffer >= Bufend-1) 194 return "Parsing buffer too short."; 195 *(Buffer++) = 0; 196 197 if(*url == ':') 198 { 199 ++url; 200 args->proxyport = Buffer; 201 while(*url && *url != ';' && Buffer != Bufend) 202 *(Buffer++) = *(url++); 203 if(Buffer == args->proxyport) 204 return "Proxy port cannot be empty."; 205 else if(Buffer >= Bufend-1) 206 return "Parsing buffer too short."; 207 *(Buffer++) = 0; 208 } 156 209 } 157 210 } … … 172 225 char *a; 173 226 int i = 0, help = 0; 174 char *t;175 227 176 228 args->server = "www.euref-ip.net"; 177 args->port = 2101;229 args->port = "2101"; 178 230 args->user = ""; 179 231 args->password = ""; … … 181 233 args->data = 0; 182 234 args->bitrate = 0; 235 args->proxyhost = 0; 236 args->proxyport = "2101"; 237 args->mode = AUTO; 183 238 help = 0; 184 239 … … 198 253 case 'b': args->bitrate = 1; break; 199 254 case 'h': help=1; break; 255 case 'r': args->port = optarg; break; 256 case 'S': args->proxyhost = optarg; break; 257 case 'R': args->proxyport = optarg; break; 258 case 'M': 259 args->mode = 0; 260 if (!strcmp(optarg,"n") || !strcmp(optarg,"ntrip1")) 261 args->mode = NTRIP1; 262 else if(!strcmp(optarg,"h") || !strcmp(optarg,"http")) 263 args->mode = HTTP; 264 else if(!strcmp(optarg,"r") || !strcmp(optarg,"rtsp")) 265 args->mode = RTSP; 266 else if(!strcmp(optarg,"a") || !strcmp(optarg,"auto")) 267 args->mode = AUTO; 268 else args->mode = atoi(optarg); 269 if((args->mode == 0) || (args->mode >= END)) 270 { 271 fprintf(stderr, "Mode %s unknown\n", optarg); 272 res = 0; 273 } 274 break; 200 275 case 1: 201 276 { … … 207 282 } 208 283 } 209 break;210 case 'r':211 args->port = strtoul(optarg, &t, 10);212 if((t && *t) || args->port < 1 || args->port > 65535)213 res = 0;214 284 break; 215 285 case -1: break; … … 234 304 { 235 305 fprintf(stderr, "Version %s (%s) GPL" COMPILEDATE "\nUsage:\n%s -s server -u user ...\n" 236 " -d " LONG_OPT("--data ") "the requested data set\n" 237 " -s " LONG_OPT("--server ") "the server name or address\n" 238 " -p " LONG_OPT("--password ") "the login password\n" 239 " -r " LONG_OPT("--port ") "the server port number (default 2101)\n" 240 " -u " LONG_OPT("--user ") "the user name\n" 241 " -n " LONG_OPT("--nmea ") "NMEA string for sending to server\n" 242 " -b " LONG_OPT("--bitrate ") "output bitrate\n" 243 "or using an URL:\n%s ntrip:mountpoint[/username[:password]][@server[:port]][;nmea]\n" 306 " -d " LONG_OPT("--data ") "the requested data set\n" 307 " -s " LONG_OPT("--server ") "the server name or address\n" 308 " -p " LONG_OPT("--password ") "the login password\n" 309 " -r " LONG_OPT("--port ") "the server port number (default 2101)\n" 310 " -u " LONG_OPT("--user ") "the user name\n" 311 " -n " LONG_OPT("--nmea ") "NMEA string for sending to server\n" 312 " -b " LONG_OPT("--bitrate ") "output bitrate\n" 313 " -S " LONG_OPT("--proxyhost ") "proxy name or address\n" 314 " -R " LONG_OPT("--proxyport ") "proxy port, optional (default 2101)\n" 315 " -M " LONG_OPT("--mode ") "mode for data request\n" 316 " Valid modes are:\n" 317 " 1, h, http NTRIP Version 2.0 Caster in TCP/IP mode\n" 318 " 2, r, rtsp NTRIP Version 2.0 Caster in RTSP/RTP mode\n" 319 " 3, n, ntrip1 NTRIP Version 1.0 Caster\n" 320 " 4, a, auto automatic detection (default)\n" 321 "or using an URL:\n%s ntrip:mountpoint[/username[:password]][@[server][:port][@proxy[:port]]][;nmea]\n" 244 322 , revisionstr, datestr, argv[0], argv[0]); 245 323 exit(1); … … 305 383 setbuf(stderr, 0); 306 384 signal(SIGALRM,sighandler_alarm); 385 signal(SIGINT,sighandler_int); 307 386 alarm(ALARMTIME); 308 387 309 388 if(getargs(argc, argv, &args)) 310 389 { 311 int i, sockfd, numbytes; 312 char buf[MAXDATASIZE]; 313 struct hostent *he; 314 struct sockaddr_in their_addr; /* connector's address information */ 315 316 if(!(he=gethostbyname(args.server))) 390 int sleeptime = 0; 391 392 do 317 393 { 318 fprintf(stderr, "Server name lookup failed for '%s'.\n", args.server); 319 exit(1); 320 } 321 if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) 322 { 323 perror("socket"); 324 exit(1); 325 } 326 their_addr.sin_family = AF_INET; /* host byte order */ 327 their_addr.sin_port = htons(args.port); /* short, network byte order */ 328 their_addr.sin_addr = *((struct in_addr *)he->h_addr); 329 memset(&(their_addr.sin_zero), '\0', 8); 330 if(connect(sockfd, (struct sockaddr *)&their_addr, 331 sizeof(struct sockaddr)) == -1) 332 { 333 perror("connect"); 334 exit(1); 335 } 336 337 if(!args.data) 338 { 339 i = snprintf(buf, MAXDATASIZE, 340 "GET / HTTP/1.0\r\n" 341 "User-Agent: %s/%s\r\n" 342 #ifdef UNUSED 343 "Accept: */*\r\n" 344 "Connection: close\r\n" 345 #endif 346 "\r\n" 347 , AGENTSTRING, revisionstr); 348 } 349 else 350 { 351 i=snprintf(buf, MAXDATASIZE-40, /* leave some space for login */ 352 "GET /%s HTTP/1.0\r\n" 353 "User-Agent: %s/%s\r\n" 354 #ifdef UNUSED 355 "Accept: */*\r\n" 356 "Connection: close\r\n" 357 #endif 358 "Authorization: Basic " 359 , args.data, AGENTSTRING, revisionstr); 360 if(i > MAXDATASIZE-40 || i < 0) /* second check for old glibc */ 361 { 362 fprintf(stderr, "Requested data too long\n"); 394 int sockfd, numbytes; 395 char buf[MAXDATASIZE]; 396 struct sockaddr_in their_addr; /* connector's address information */ 397 struct hostent *he; 398 struct servent *se; 399 const char *server, *port, *proxyserver = 0; 400 char proxyport[6]; 401 char *b; 402 long i; 403 if(sleeptime) 404 { 405 sleep(sleeptime); 406 sleeptime += 2; 407 } 408 else 409 { 410 sleeptime = 1; 411 } 412 alarm(ALARMTIME); 413 if(args.proxyhost) 414 { 415 int p; 416 if((i = strtol(args.port, &b, 10)) && (!b || !*b)) 417 p = i; 418 else if(!(se = getservbyname(args.port, 0))) 419 { 420 fprintf(stderr, "Can't resolve port %s.", args.port); 421 exit(1); 422 } 423 else 424 { 425 p = ntohs(se->s_port); 426 } 427 snprintf(proxyport, sizeof(proxyport), "%d", p); 428 port = args.proxyport; 429 proxyserver = args.server; 430 server = args.proxyhost; 431 } 432 else 433 { 434 server = args.server; 435 port = args.port; 436 } 437 438 memset(&their_addr, 0, sizeof(struct sockaddr_in)); 439 if((i = strtol(port, &b, 10)) && (!b || !*b)) 440 their_addr.sin_port = htons(i); 441 else if(!(se = getservbyname(port, 0))) 442 { 443 fprintf(stderr, "Can't resolve port %s.", port); 363 444 exit(1); 364 445 } 365 i += encode(buf+i, MAXDATASIZE-i-4, args.user, args.password); 366 if(i > MAXDATASIZE-4) 367 { 368 fprintf(stderr, "Username and/or password too long\n"); 446 else 447 { 448 their_addr.sin_port = se->s_port; 449 } 450 if(!(he=gethostbyname(server))) 451 { 452 fprintf(stderr, "Server name lookup failed for '%s'.\n", server); 369 453 exit(1); 370 454 } 371 buf[i++] = '\r'; 372 buf[i++] = '\n'; 373 buf[i++] = '\r'; 374 buf[i++] = '\n'; 375 if(args.nmea) 376 { 377 int j = snprintf(buf+i, MAXDATASIZE-i, "%s\r\n", args.nmea); 378 if(j >= 0 && j < MAXDATASIZE-i) 379 i += j; 455 if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) 456 { 457 perror("socket"); 458 exit(1); 459 } 460 their_addr.sin_family = AF_INET; 461 their_addr.sin_addr = *((struct in_addr *)he->h_addr); 462 463 if(args.data && args.mode == RTSP) 464 { 465 struct sockaddr_in local; 466 int sockudp, localport; 467 int cseq = 1; 468 socklen_t len; 469 470 if((sockudp = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 471 { 472 perror("socket"); 473 exit(1); 474 } 475 /* fill structure with local address information for UDP */ 476 memset(&local, 0, sizeof(local)); 477 local.sin_family = AF_INET; 478 local.sin_port = htons(0); 479 local.sin_addr.s_addr = htonl(INADDR_ANY); 480 len = sizeof(local); 481 /* bind() in order to get a random RTP client_port */ 482 if((bind(sockudp, (struct sockaddr *)&local, len)) < 0) 483 { 484 perror("bind"); 485 exit(1); 486 } 487 if((getsockname(sockudp, (struct sockaddr*)&local, &len)) != -1) 488 { 489 localport = ntohs(local.sin_port); 490 } 380 491 else 381 492 { 382 fprintf(stderr, "NMEA string too long\n"); 383 exit(1); 384 } 385 } 386 } 387 if(send(sockfd, buf, (size_t)i, 0) != i) 388 { 389 perror("send"); 390 exit(1); 391 } 392 if(args.data) 393 { 394 int k = 0; 395 int starttime = time(0); 396 int lastout = starttime; 397 int totalbytes = 0; 398 399 while((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) != -1) 400 { 401 alarm(ALARMTIME); 402 if(!k) 403 { 404 if(numbytes < 12 || strncmp("ICY 200 OK\r\n", buf, 12)) 493 perror("local access failed"); 494 exit(1); 495 } 496 if(connect(sockfd, (struct sockaddr *)&their_addr, 497 sizeof(struct sockaddr)) == -1) 498 { 499 perror("connect"); 500 exit(1); 501 } 502 i=snprintf(buf, MAXDATASIZE-40, /* leave some space for login */ 503 "SETUP rtsp://%s%s%s/%s RTSP/1.0\r\n" 504 "CSeq: %d\r\n" 505 "Ntrip-Version: Ntrip/2.0\r\n" 506 "Ntrip-Component: Ntripclient\r\n" 507 "User-Agent: %s/%s\r\n" 508 "Transport: RTP/GNSS;unicast;client_port=%u\r\n" 509 "Authorization: Basic ", 510 args.server, proxyserver ? ":" : "", proxyserver ? args.port : "", 511 args.data, cseq++, AGENTSTRING, revisionstr, localport); 512 if(i > MAXDATASIZE-40 || i < 0) /* second check for old glibc */ 513 { 514 fprintf(stderr, "Requested data too long\n"); 515 exit(1); 516 } 517 i += encode(buf+i, MAXDATASIZE-i-4, args.user, args.password); 518 if(i > MAXDATASIZE-4) 519 { 520 fprintf(stderr, "Username and/or password too long\n"); 521 exit(1); 522 } 523 buf[i++] = '\r'; 524 buf[i++] = '\n'; 525 buf[i++] = '\r'; 526 buf[i++] = '\n'; 527 if(args.nmea) 528 { 529 int j = snprintf(buf+i, MAXDATASIZE-i, "%s\r\n", args.nmea); 530 if(j >= 0 && j < MAXDATASIZE-i) 531 i += j; 532 else 405 533 { 406 fprintf(stderr, "Could not get the requested data: "); 407 for(k = 0; k < numbytes && buf[k] != '\n' && buf[k] != '\r'; ++k) 408 { 409 fprintf(stderr, "%c", isprint(buf[k]) ? buf[k] : '.'); 410 } 411 fprintf(stderr, "\n"); 534 fprintf(stderr, "NMEA string too long\n"); 412 535 exit(1); 413 536 } 414 ++k; 537 } 538 if(send(sockfd, buf, (size_t)i, 0) != i) 539 { 540 perror("send"); 541 exit(1); 542 } 543 if((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) != -1) 544 { 545 if(numbytes >= 17 && !strncmp(buf, "RTSP/1.0 200 OK\r\n", 17)) 546 { 547 int serverport = 0, session = 0; 548 const char *portcheck = "server_port="; 549 const char *sessioncheck = "session: "; 550 int l = strlen(portcheck)-1; 551 int j=0; 552 for(i = 0; j != l && i < numbytes-l; ++i) 553 { 554 for(j = 0; j < l && tolower(buf[i+j]) == portcheck[j]; ++j) 555 ; 556 } 557 if(i == numbytes-l) 558 { 559 fprintf(stderr, "No server port number found\n"); 560 exit(1); 561 } 562 else 563 { 564 i+=l; 565 while(i < numbytes && buf[i] >= '0' && buf[i] <= '9') 566 serverport = serverport * 10 + buf[i++]-'0'; 567 if(buf[i] != '\r' && buf[i] != ';') 568 { 569 fprintf(stderr, "Could not extract server port\n"); 570 exit(1); 571 } 572 } 573 l = strlen(sessioncheck)-1; 574 j=0; 575 for(i = 0; j != l && i < numbytes-l; ++i) 576 { 577 for(j = 0; j < l && tolower(buf[i+j]) == sessioncheck[j]; ++j) 578 ; 579 } 580 if(i == numbytes-l) 581 { 582 fprintf(stderr, "No session number found\n"); 583 exit(1); 584 } 585 else 586 { 587 i+=l; 588 while(i < numbytes && buf[i] >= '0' && buf[i] <= '9') 589 session = session * 10 + buf[i++]-'0'; 590 if(buf[i] != '\r') 591 { 592 fprintf(stderr, "Could not extract session number\n"); 593 exit(1); 594 } 595 } 596 597 i = snprintf(buf, MAXDATASIZE, 598 "PLAY rtsp://%s%s%s/%s RTSP/1.0\r\n" 599 "CSeq: %d\r\n" 600 "Session: %d\r\n" 601 "\r\n", 602 args.server, proxyserver ? ":" : "", proxyserver ? args.port : "", 603 args.data, cseq++, session); 604 605 if(i > MAXDATASIZE || i < 0) /* second check for old glibc */ 606 { 607 fprintf(stderr, "Requested data too long\n"); 608 exit(1); 609 } 610 if(send(sockfd, buf, (size_t)i, 0) != i) 611 { 612 perror("send"); 613 exit(1); 614 } 615 if((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) != -1) 616 { 617 if(numbytes >= 17 && !strncmp(buf, "RTSP/1.0 200 OK\r\n", 17)) 618 { 619 struct sockaddr_in addrRTP; 620 /* fill structure with caster address information for UDP */ 621 memset(&addrRTP, 0, sizeof(addrRTP)); 622 addrRTP.sin_family = AF_INET; 623 addrRTP.sin_port = htons(serverport); 624 their_addr.sin_addr = *((struct in_addr *)he->h_addr); 625 len = sizeof(addrRTP); 626 int ts = 0; 627 int sn = 0; 628 int ssrc = 0; 629 int init = 0; 630 int u, v, w; 631 while(!stop && (i = recvfrom(sockudp, buf, 1526, 0, 632 (struct sockaddr*) &addrRTP, &len)) > 0) 633 { 634 alarm(ALARMTIME); 635 if(i >= 12+1 && (unsigned char)buf[0] == (2 << 6) && buf[1] == 0x60) 636 { 637 u= ((unsigned char)buf[2]<<8)+(unsigned char)buf[3]; 638 v = ((unsigned char)buf[4]<<24)+((unsigned char)buf[5]<<16) 639 +((unsigned char)buf[6]<<8)+(unsigned char)buf[7]; 640 w = ((unsigned char)buf[8]<<24)+((unsigned char)buf[9]<<16) 641 +((unsigned char)buf[10]<<8)+(unsigned char)buf[11]; 642 643 if(init) 644 { 645 if(u < -30000 && sn > 30000) sn -= 0xFFFF; 646 if(ssrc != w || ts > v) 647 { 648 fprintf(stderr, "Illegal UDP data received.\n"); 649 exit(1); 650 } 651 if(u > sn) /* don't show out-of-order packets */ 652 fwrite(buf+12, (size_t)i-12, 1, stdout); 653 } 654 sn = u; ts = v; ssrc = w; init = 1; 655 } 656 else 657 { 658 fprintf(stderr, "Illegal UDP header.\n"); 659 exit(1); 660 } 661 } 662 } 663 i = snprintf(buf, MAXDATASIZE, 664 "TEARDOWN rtsp://%s%s%s/%s RTSP/1.0\r\n" 665 "CSeq: %d\r\n" 666 "Session: %d\r\n" 667 "\r\n", 668 args.server, proxyserver ? ":" : "", proxyserver ? args.port : "", 669 args.data, cseq++, session); 670 671 if(i > MAXDATASIZE || i < 0) /* second check for old glibc */ 672 { 673 fprintf(stderr, "Requested data too long\n"); 674 exit(1); 675 } 676 if(send(sockfd, buf, (size_t)i, 0) != i) 677 { 678 perror("send"); 679 exit(1); 680 } 681 } 682 else 683 { 684 fprintf(stderr, "Could not start data stream.\n"); 685 exit(1); 686 } 687 } 688 else 689 { 690 fprintf(stderr, "Could not setup initial control connection.\n"); 691 exit(1); 692 } 415 693 } 416 694 else 417 695 { 418 totalbytes += numbytes; 419 if(totalbytes < 0) /* overflow */ 696 perror("recv"); 697 exit(1); 698 } 699 } 700 else 701 { 702 if(connect(sockfd, (struct sockaddr *)&their_addr, 703 sizeof(struct sockaddr)) == -1) 704 { 705 perror("connect"); 706 exit(1); 707 } 708 if(!args.data) 709 { 710 i = snprintf(buf, MAXDATASIZE, 711 "GET %s%s%s%s/ HTTP/1.0\r\n" 712 "Host: %s\r\n%s" 713 "User-Agent: %s/%s\r\n" 714 "\r\n" 715 , proxyserver ? "http://" : "", proxyserver ? proxyserver : "", 716 proxyserver ? ":" : "", proxyserver ? proxyport : "", 717 args.server, args.mode == NTRIP1 ? "" : "Ntrip-Version: Ntrip/2.0\r\n", 718 AGENTSTRING, revisionstr); 719 } 720 else 721 { 722 i=snprintf(buf, MAXDATASIZE-40, /* leave some space for login */ 723 "GET %s%s%s%s/%s HTTP/1.0\r\n" 724 "Host: %s\r\n%s" 725 "User-Agent: %s/%s\r\n" 726 "Authorization: Basic " 727 , proxyserver ? "http://" : "", proxyserver ? proxyserver : "", 728 proxyserver ? ":" : "", proxyserver ? proxyport : "", 729 args.data, args.server, 730 args.mode == NTRIP1 ? "" : "Ntrip-Version: Ntrip/2.0\r\n", 731 AGENTSTRING, revisionstr); 732 if(i > MAXDATASIZE-40 || i < 0) /* second check for old glibc */ 420 733 { 421 totalbytes = 0; 422 starttime = time(0); 423 lastout = starttime; 734 fprintf(stderr, "Requested data too long\n"); 735 exit(1); 424 736 } 425 fwrite(buf, (size_t)numbytes, 1, stdout); 426 fflush(stdout); 427 if(args.bitrate) 737 i += encode(buf+i, MAXDATASIZE-i-4, args.user, args.password); 738 if(i > MAXDATASIZE-4) 428 739 { 429 int t = time(0); 430 if(t > lastout + 60) 431 { 432 lastout = t; 433 fprintf(stderr, "Bitrate is %dbyte/s (%d seconds accumulated).\n", 434 totalbytes/(t-starttime), t-starttime); 435 } 740 fprintf(stderr, "Username and/or password too long\n"); 741 exit(1); 436 742 } 437 } 438 } 439 } 440 else 441 { 442 while((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) > 0) 443 { 444 fwrite(buf, (size_t)numbytes, 1, stdout); 445 } 446 } 447 448 close(sockfd); 743 buf[i++] = '\r'; 744 buf[i++] = '\n'; 745 buf[i++] = '\r'; 746 buf[i++] = '\n'; 747 if(args.nmea) 748 { 749 int j = snprintf(buf+i, MAXDATASIZE-i, "%s\r\n", args.nmea); 750 if(j >= 0 && j < MAXDATASIZE-i) 751 i += j; 752 else 753 { 754 fprintf(stderr, "NMEA string too long\n"); 755 exit(1); 756 } 757 } 758 } 759 if(send(sockfd, buf, (size_t)i, 0) != i) 760 { 761 perror("send"); 762 exit(1); 763 } 764 if(args.data) 765 { 766 int k = 0; 767 int chunkymode = 0; 768 int starttime = time(0); 769 int lastout = starttime; 770 int totalbytes = 0; 771 int chunksize = 0; 772 773 while(!stop && (numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) != -1) 774 { 775 alarm(ALARMTIME); 776 if(!k) 777 { 778 if(numbytes > 17 && (!strncmp(buf, "HTTP/1.1 200 OK\r\n", 17) 779 || !strncmp(buf, "HTTP/1.0 200 OK\r\n", 17))) 780 { 781 const char *datacheck = "Content-Type: gnss/data\r\n"; 782 const char *chunkycheck = "Transfer-Encoding: chunked\r\n"; 783 int l = strlen(datacheck)-1; 784 int j=0; 785 for(i = 0; j != l && i < numbytes-l; ++i) 786 { 787 for(j = 0; j < l && buf[i+j] == datacheck[j]; ++j) 788 ; 789 } 790 if(i == numbytes-l) 791 { 792 fprintf(stderr, "No 'Content-Type: gnss/data' found\n"); 793 exit(1); 794 } 795 l = strlen(chunkycheck)-1; 796 j=0; 797 for(i = 0; j != l && i < numbytes-l; ++i) 798 { 799 for(j = 0; j < l && buf[i+j] == chunkycheck[j]; ++j) 800 ; 801 } 802 if(i < numbytes-l) 803 chunkymode = 1; 804 } 805 else if(numbytes < 12 || strncmp("ICY 200 OK\r\n", buf, 12)) 806 { 807 fprintf(stderr, "Could not get the requested data: "); 808 for(k = 0; k < numbytes && buf[k] != '\n' && buf[k] != '\r'; ++k) 809 { 810 fprintf(stderr, "%c", isprint(buf[k]) ? buf[k] : '.'); 811 } 812 fprintf(stderr, "\n"); 813 exit(1); 814 } 815 else if(args.mode != NTRIP1) 816 { 817 fprintf(stderr, "NTRIP version 2 HTTP connection failed%s.\n", 818 args.mode == AUTO ? ", falling back to NTRIP1" : ""); 819 if(args.mode == HTTP) 820 exit(1); 821 } 822 ++k; 823 } 824 else 825 { 826 sleeptime = 0; 827 if(chunkymode) 828 { 829 int stop = 0; 830 int pos = 0; 831 while(!stop && pos < numbytes) 832 { 833 switch(chunkymode) 834 { 835 case 1: /* reading number starts */ 836 chunksize = 0; 837 ++chunkymode; /* no break */ 838 case 2: /* during reading number */ 839 i = buf[pos++]; 840 if(i >= '0' && i <= '9') chunksize = chunksize*16+i-'0'; 841 else if(i >= 'a' && i <= 'f') chunksize = chunksize*16+i-'a'+10; 842 else if(i >= 'A' && i <= 'F') chunksize = chunksize*16+i-'A'+10; 843 else if(i == '\r') ++chunkymode; 844 else stop = 1; 845 break; 846 case 3: /* scanning for return */ 847 if(buf[pos++] == '\n') chunkymode = chunksize ? 4 : 1; 848 else stop = 1; 849 break; 850 case 4: /* output data */ 851 i = numbytes-pos; 852 if(i > chunksize) i = chunksize; 853 fwrite(buf+pos, (size_t)i, 1, stdout); 854 totalbytes += i; 855 chunksize -= i; 856 pos += i; 857 if(!chunksize) 858 chunkymode = 1; 859 break; 860 } 861 } 862 if(stop) 863 { 864 fprintf(stderr, "Error in chunky transfer encoding\n"); 865 break; 866 } 867 } 868 else 869 { 870 totalbytes += numbytes; 871 fwrite(buf, (size_t)numbytes, 1, stdout); 872 } 873 fflush(stdout); 874 if(totalbytes < 0) /* overflow */ 875 { 876 totalbytes = 0; 877 starttime = time(0); 878 lastout = starttime; 879 } 880 if(args.bitrate) 881 { 882 int t = time(0); 883 if(t > lastout + 60) 884 { 885 lastout = t; 886 fprintf(stderr, "Bitrate is %dbyte/s (%d seconds accumulated).\n", 887 totalbytes/(t-starttime), t-starttime); 888 } 889 } 890 } 891 } 892 } 893 else 894 { 895 sleeptime = 0; 896 while(!stop && (numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) > 0) 897 { 898 alarm(ALARMTIME); 899 fwrite(buf, (size_t)numbytes, 1, stdout); 900 } 901 } 902 close(sockfd); 903 } 904 } while(args.data && !stop); 449 905 } 450 906 return 0;
Note:
See TracChangeset
for help on using the changeset viewer.