Changeset 487 in ntrip
- Timestamp:
- Aug 30, 2007, 4:52:43 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/ntripserver/ntripserver.c
r485 r487 1 1 /* 2 * $Id: NtripLinuxServer.c,v 1.32 2007/06/07 07:47:24stoecker Exp $2 * $Id: ntripserver.c,v 1.33 2007/08/30 07:45:36 stoecker Exp $ 3 3 * 4 4 * Copyright (c) 2003...2007 … … 37 37 38 38 /* CVS revision and version */ 39 static char revisionstr[] = "$Revision: 1.3 2$";40 static char datestr[] = "$Date: 2007/0 6/07 07:47:24$";39 static char revisionstr[] = "$Revision: 1.33 $"; 40 static char datestr[] = "$Date: 2007/08/30 07:45:36 $"; 41 41 42 42 #include <ctype.h> … … 71 71 CASTER = 6, LAST }; 72 72 73 enum OUTMODE { HTTP = 1, RTSP = 2, NTRIP V1 = 3, END };74 75 #define AGENTSTRING "NTRIP NtripLinuxServer"73 enum OUTMODE { HTTP = 1, RTSP = 2, NTRIP1 = 3, END }; 74 75 #define AGENTSTRING "NTRIP ntripserver" 76 76 #define BUFSZ 1024 77 77 #define SZ 64 … … 100 100 static int sisnet = 31; 101 101 static int gpsfd = -1; 102 static int socket_tcp = -1; 103 static int socket_udp = -1; 102 104 static int sigint_received = 0; 105 static int sigalarm_received = 0; 106 static int sigpipe_received = 0; 107 static int reconnect_sec = 1; 108 103 109 104 110 /* Forward references */ … … 109 115 static int encode(char *buf, int size, const char *user, const char *pwd); 110 116 static int send_to_caster(char *input, int socket, int input_size); 111 static void close_session( int sock_udp, int sock_tcp,112 const char *caster_addr, const char *mountpoint, int cseq,113 int session, char *rtsp_ext, int in_fd);117 static void close_session(const char *caster_addr, const char *mountpoint, 118 int cseq, int session, char *rtsp_ext, int fallback); 119 static int reconnect(int rec_sec, int rec_sec_max); 114 120 115 121 /* Signal Handling */ 116 122 static void handle_sigint(int sig); 123 static void handle_alarm(int sig); 124 static void handle_sigpipe(int sig); 117 125 static void setup_signal_handler(int sig, void (*handler)(int)); 118 static int signal_was_caught(void);119 120 #ifdef __GNUC__121 static __attribute__ ((noreturn)) void sighandler_alarm(122 int sig __attribute__((__unused__)))123 #else /* __GNUC__ */124 static void sighandler_alarm(int sig)125 #endif /* __GNUC__ */126 {127 fprintf(stderr, "ERROR: more than %d seconds no activity\n", ALARMTIME);128 exit(1);129 }130 126 131 127 /* … … 192 188 const char * password = ""; 193 189 194 int socket_tcp = 0; 195 int outputmode = NTRIPV1; 190 int outputmode = NTRIP1; 196 191 197 192 struct sockaddr_in casterRTP; 198 193 struct sockaddr_in local; 199 int socket_udp = 0;200 194 int client_port = 0; 201 195 int server_port = 0; … … 211 205 char * token; 212 206 char * tok_buf[BUFSZ]; 207 208 int reconnect_sec_max = 0; 213 209 214 210 setbuf(stdout, 0); … … 235 231 236 232 /* setup signal handler for timeout */ 237 s ignal(SIGALRM,sighandler_alarm);233 setup_signal_handler(SIGALRM, handle_alarm); 238 234 alarm(ALARMTIME); 235 236 /* setup signal handler for CTRL+C */ 237 setup_signal_handler(SIGINT, handle_sigint); 238 239 /* setup signal handler for boken pipe */ 240 setup_signal_handler(SIGPIPE, handle_sigpipe); 239 241 240 242 /* get and check program arguments */ … … 245 247 } 246 248 while((c = getopt(argc, argv, 247 "M:i:h:b:p:s:a:m:c:H:P:f:x:y:l:u:V:D:U:W: B:O:E:F:N:n:")) != EOF)249 "M:i:h:b:p:s:a:m:c:H:P:f:x:y:l:u:V:D:U:W:O:E:F:R:N:n:B")) != EOF) 248 250 { 249 251 switch (c) … … 352 354 proxyport = atoi(optarg); 353 355 break; 356 case 'R': /* maximum delay between reconnect attempts in seconds */ 357 reconnect_sec_max = atoi(optarg); 358 break; 354 359 case 'O': /* OutputMode */ 355 360 outputmode = 0; 356 361 if (!strcmp(optarg,"n") || !strcmp(optarg,"ntrip1")) 357 outputmode = NTRIP V1;362 outputmode = NTRIP1; 358 363 else if(!strcmp(optarg,"h") || !strcmp(optarg,"http")) 359 364 outputmode = HTTP; … … 399 404 } 400 405 401 if(*ntrip_str && (outputmode == NTRIPV1)) 406 if(outputmode != NTRIP1) 407 { 408 fprintf(stderr, "\nWARNING: *** NTRIP VERSION 2 PROTOCOL IS STILL" 409 " BETA AND MAY BE CHANGED ***\n\n"); 410 } 411 412 if(*ntrip_str && (outputmode == NTRIP1)) 402 413 { 403 414 fprintf(stderr, "WARNING: OutputMode is Ntrip version 1.0" 404 415 " - Ntrip-STR will not be considered\n"); 416 } 417 418 if((reconnect_sec_max > 0) && (reconnect_sec_max < 256)) 419 { 420 fprintf(stderr, 421 "WARNING: maximum delay between reconnect attemts changed from %d to 256 seconds\n" 422 , reconnect_sec_max); 423 reconnect_sec_max = 256; 405 424 } 406 425 … … 459 478 if((i > SZ) || (i < 0)) 460 479 { 461 fprintf(stderr, 480 fprintf(stderr,"ERROR: Destination caster name/port to long - length = %d (max: %d)\n", i, SZ); 462 481 exit(0); 463 482 } … … 475 494 } 476 495 477 /*** InputMode handling ***/ 478 switch(inputmode) 479 { 480 case INFILE: 481 { 482 if((gpsfd = open(filepath, O_RDONLY)) < 0) 483 { 484 perror("ERROR: opening input file"); 485 exit(1); 486 } 487 /* set blocking inputmode in case it was not set 488 (seems to be sometimes for fifo's) */ 489 fcntl(gpsfd, F_SETFL, 0); 490 printf("file input: file = %s\n", filepath); 491 } 492 break; 493 case SERIAL: /* open serial port */ 494 { 495 gpsfd = openserial(ttyport, 1, ttybaud); 496 if(gpsfd < 0) 497 { 498 exit(1); 499 } 500 printf("serial input: device = %s, speed = %d\n", ttyport, ttybaud); 501 } 502 break; 503 case TCPSOCKET: case UDPSOCKET: case SISNET: case CASTER: 504 { 496 while(inputmode != LAST) 497 { 498 int input_init = 1; 499 /*** InputMode handling ***/ 500 switch(inputmode) 501 { 502 case INFILE: 503 { 504 if((gpsfd = open(filepath, O_RDONLY)) < 0) 505 { 506 perror("ERROR: opening input file"); 507 exit(1); 508 } 509 /* set blocking inputmode in case it was not set 510 (seems to be sometimes for fifo's) */ 511 fcntl(gpsfd, F_SETFL, 0); 512 printf("file input: file = %s\n", filepath); 513 } 514 break; 515 case SERIAL: /* open serial port */ 516 { 517 gpsfd = openserial(ttyport, 1, ttybaud); 518 if(gpsfd < 0) 519 { 520 exit(1); 521 } 522 printf("serial input: device = %s, speed = %d\n", ttyport, ttybaud); 523 } 524 break; 525 case TCPSOCKET: case UDPSOCKET: case SISNET: case CASTER: 526 { 527 if(inputmode == SISNET) 528 { 529 if(!inhost) inhost = SISNET_SERVER; 530 if(!inport) inport = SISNET_PORT; 531 } 532 else if(inputmode == CASTER) 533 { 534 if(!inport) inport = NTRIP_PORT; 535 if(!inhost) inhost = NTRIP_CASTER; 536 } 537 else if((inputmode == TCPSOCKET) || (inputmode == UDPSOCKET)) 538 { 539 if(!inport) inport = SERV_TCP_PORT; 540 if(!inhost) inhost = SERV_HOST_ADDR; 541 } 542 543 if(!(he = gethostbyname(inhost))) 544 { 545 fprintf(stderr, "ERROR: Input host <%s> unknown\n", inhost); 546 usage(-2, argv[0]); 547 } 548 549 if((gpsfd = socket(AF_INET, inputmode == UDPSOCKET 550 ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0) 551 { 552 fprintf(stderr, 553 "ERROR: can't create socket for incoming data stream\n"); 554 exit(1); 555 } 556 557 memset((char *) &caster, 0x00, sizeof(caster)); 558 if(!bindmode) 559 memcpy(&caster.sin_addr, he->h_addr, (size_t)he->h_length); 560 caster.sin_family = AF_INET; 561 caster.sin_port = htons(inport); 562 563 fprintf(stderr, "%s input: host = %s, port = %d, %s%s%s%s%s\n", 564 inputmode == CASTER ? "caster" : inputmode == SISNET ? "sisnet" : 565 inputmode == TCPSOCKET ? "tcp socket" : "udp socket", 566 bindmode ? "127.0.0.1" : inet_ntoa(caster.sin_addr), 567 inport, stream_name ? "stream = " : "", stream_name ? stream_name : "", 568 initfile ? ", initfile = " : "", initfile ? initfile : "", 569 bindmode ? "binding mode" : ""); 570 571 if(bindmode) 572 { 573 if(bind(gpsfd, (struct sockaddr *) &caster, sizeof(caster)) < 0) 574 { 575 fprintf(stderr, "ERROR: can't bind input to port %d\n", inport); 576 reconnect_sec_max = 0; 577 input_init = 0; 578 break; 579 } 580 } /* connect to input-caster or proxy server*/ 581 else if(connect(gpsfd, (struct sockaddr *)&caster, sizeof(caster)) < 0) 582 { 583 fprintf(stderr, "WARNING: can't connect input to %s at port %d\n", 584 inet_ntoa(caster.sin_addr), inport); 585 input_init = 0; 586 break; 587 } 588 589 if(stream_name) /* input from Ntrip Version 1.0 caster*/ 590 { 591 int init = 0; 592 593 /* set socket buffer size */ 594 setsockopt(gpsfd, SOL_SOCKET, SO_SNDBUF, (const char *) &size, 595 sizeof(const char *)); 596 if(stream_user && stream_password) 597 { 598 /* leave some space for login */ 599 nBufferBytes=snprintf(szSendBuffer, sizeof(szSendBuffer)-40, 600 "GET %s/%s HTTP/1.0\r\n" 601 "User-Agent: %s/%s\r\n" 602 "Authorization: Basic ", get_extension, stream_name, 603 AGENTSTRING, revisionstr); 604 /* second check for old glibc */ 605 if(nBufferBytes > (int)sizeof(szSendBuffer)-40 || nBufferBytes < 0) 606 { 607 fprintf(stderr, "ERROR: Source caster request too long\n"); 608 input_init = 0; 609 reconnect_sec_max =0; 610 break; 611 } 612 nBufferBytes += encode(szSendBuffer+nBufferBytes, 613 sizeof(szSendBuffer)-nBufferBytes-4, stream_user, stream_password); 614 if(nBufferBytes > (int)sizeof(szSendBuffer)-4) 615 { 616 fprintf(stderr, 617 "ERROR: Source caster user ID and/or password too long\n"); 618 input_init = 0; 619 reconnect_sec_max =0; 620 break; 621 } 622 szSendBuffer[nBufferBytes++] = '\r'; 623 szSendBuffer[nBufferBytes++] = '\n'; 624 szSendBuffer[nBufferBytes++] = '\r'; 625 szSendBuffer[nBufferBytes++] = '\n'; 626 } 627 else 628 { 629 nBufferBytes = snprintf(szSendBuffer, sizeof(szSendBuffer), 630 "GET %s/%s HTTP/1.0\r\n" 631 "User-Agent: %s/%s\r\n" 632 "\r\n", get_extension, stream_name, AGENTSTRING, revisionstr); 633 } 634 if((send(gpsfd, szSendBuffer, (size_t)nBufferBytes, 0)) 635 != nBufferBytes) 636 { 637 fprintf(stderr, "WARNING: could not send Source caster request\n"); 638 input_init = 0; 639 break; 640 } 641 nBufferBytes = 0; 642 /* check Source caster's response */ 643 while(!init && nBufferBytes < (int)sizeof(szSendBuffer) 644 && (nBufferBytes += recv(gpsfd, szSendBuffer, 645 sizeof(szSendBuffer)-nBufferBytes, 0)) > 0) 646 { 647 if(strstr(szSendBuffer, "\r\n")) 648 { 649 if(strncmp(szSendBuffer, "ICY 200 OK", 10)) 650 { 651 int k; 652 fprintf(stderr, 653 "ERROR: could not get requested data from Source caster: "); 654 for(k = 0; k < nBufferBytes && szSendBuffer[k] != '\n' 655 && szSendBuffer[k] != '\r'; ++k) 656 { 657 fprintf(stderr, "%c", isprint(szSendBuffer[k]) 658 ? szSendBuffer[k] : '.'); 659 } 660 fprintf(stderr, "\n"); 661 if(strncmp(szSendBuffer, "SOURCETABLE 200 OK",18)) 662 { 663 reconnect_sec_max =0; 664 } 665 input_init = 0; 666 break; 667 } 668 else init = 1; 669 } 670 } 671 } /* end input from Ntrip Version 1.0 caster */ 672 673 if(initfile && inputmode != SISNET) 674 { 675 char buffer[1024]; 676 FILE *fh; 677 int i; 678 679 if((fh = fopen(initfile, "r"))) 680 { 681 while((i = fread(buffer, 1, sizeof(buffer), fh)) > 0) 682 { 683 if((send(gpsfd, buffer, (size_t)i, 0)) != i) 684 { 685 perror("WARNING: sending init file"); 686 input_init = 0; 687 break; 688 } 689 } 690 if(i < 0) 691 { 692 perror("ERROR: reading init file"); 693 reconnect_sec_max = 0; 694 input_init = 0; 695 break; 696 } 697 fclose(fh); 698 } 699 else 700 { 701 fprintf(stderr, "ERROR: can't read init file <%s>\n", initfile); 702 reconnect_sec_max = 0; 703 input_init = 0; 704 break; 705 } 706 } 707 } 505 708 if(inputmode == SISNET) 506 709 { 507 if(!inhost) inhost = SISNET_SERVER; 508 if(!inport) inport = SISNET_PORT; 509 } 510 else if(inputmode == CASTER) 511 { 512 if(!inport) inport = NTRIP_PORT; 513 if(!inhost) inhost = NTRIP_CASTER; 514 } 515 else if((inputmode == TCPSOCKET) || (inputmode == UDPSOCKET)) 516 { 517 if(!inport) inport = SERV_TCP_PORT; 518 if(!inhost) inhost = SERV_HOST_ADDR; 519 } 520 521 if(!(he = gethostbyname(inhost))) 522 { 523 fprintf(stderr, "ERROR: Input host <%s> unknown\n", inhost); 524 usage(-2, argv[0]); 525 } 526 527 if((gpsfd = socket(AF_INET, inputmode == UDPSOCKET 528 ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0) 529 { 530 fprintf(stderr, 531 "ERROR: can't create socket for incoming data stream\n"); 532 exit(1); 710 int i, j; 711 char buffer[1024]; 712 713 i = snprintf(buffer, sizeof(buffer), sisnet >= 30 ? "AUTH,%s,%s\r\n" 714 : "AUTH,%s,%s", sisnetuser, sisnetpassword); 715 if((send(gpsfd, buffer, (size_t)i, 0)) != i) 716 { 717 perror("WARNING: sending authentication for SISNeT data server"); 718 input_init = 0; 719 break; 720 } 721 i = sisnet >= 30 ? 7 : 5; 722 if((j = recv(gpsfd, buffer, i, 0)) != i && strncmp("*AUTH", buffer, 5)) 723 { 724 fprintf(stderr, "WARNING: SISNeT connect failed:"); 725 for(i = 0; i < j; ++i) 726 { 727 if(buffer[i] != '\r' && buffer[i] != '\n') 728 { 729 fprintf(stderr, "%c", isprint(buffer[i]) ? buffer[i] : '.'); 730 } 731 } 732 fprintf(stderr, "\n"); 733 input_init = 0; 734 break; 735 } 736 if(sisnet >= 31) 737 { 738 if((send(gpsfd, "START\r\n", 7, 0)) != i) 739 { 740 perror("WARNING: sending Sisnet start command"); 741 input_init = 0; 742 break; 743 } 744 } 745 } 746 /*** receiver authentication ***/ 747 if (recvrid && recvrpwd && ((inputmode == TCPSOCKET) 748 || (inputmode == UDPSOCKET))) 749 { 750 if (strlen(recvrid) > (BUFSZ-3)) 751 { 752 fprintf(stderr, "ERROR: Receiver ID too long\n"); 753 reconnect_sec_max = 0; 754 input_init = 0; 755 break; 756 } 757 else 758 { 759 fprintf(stderr, "Sending user ID for receiver...\n"); 760 nBufferBytes = read(gpsfd, szSendBuffer, BUFSZ); 761 strcpy(szSendBuffer, recvrid); 762 strcat(szSendBuffer,"\r\n"); 763 if(send(gpsfd,szSendBuffer, strlen(szSendBuffer), MSG_DONTWAIT) < 0) 764 { 765 perror("WARNING: sending user ID for receiver"); 766 input_init = 0; 767 break; 768 } 769 } 770 771 if (strlen(recvrpwd) > (BUFSZ-3)) 772 { 773 fprintf(stderr, "ERROR: Receiver password too long\n"); 774 reconnect_sec_max = 0; 775 input_init = 0; 776 break; 777 } 778 else 779 { 780 fprintf(stderr, "Sending user password for receiver...\n"); 781 nBufferBytes = read(gpsfd, szSendBuffer, BUFSZ); 782 strcpy(szSendBuffer, recvrpwd); 783 strcat(szSendBuffer,"\r\n"); 784 if(send(gpsfd, szSendBuffer, strlen(szSendBuffer), MSG_DONTWAIT) < 0) 785 { 786 perror("WARNING: sending user password for receiver"); 787 input_init = 0; 788 break; 789 } 790 } 791 } 792 break; 793 default: 794 usage(-1, argv[0]); 795 break; 796 } 797 798 /* ----- main part ----- */ 799 int output_init = 1; 800 801 while((input_init) && (output_init)) 802 { 803 if((sigint_received) || (sigalarm_received) || (sigpipe_received)) break; 804 805 if(!(he = gethostbyname(outhost))) 806 { 807 fprintf(stderr, "ERROR: Destination caster or proxy host <%s> unknown\n", 808 outhost); 809 close_session(casterouthost, mountpoint, cseq, session, rtsp_extension, 0); 810 usage(-2, argv[0]); 811 } 812 813 /* create socket */ 814 if((socket_tcp = socket(AF_INET, SOCK_STREAM, 0)) < 0) 815 { 816 perror("ERROR: tcp socket"); 817 reconnect_sec_max = 0; 818 break; 533 819 } 534 820 535 821 memset((char *) &caster, 0x00, sizeof(caster)); 536 if(!bindmode) 537 memcpy(&caster.sin_addr, he->h_addr, (size_t)he->h_length); 822 memcpy(&caster.sin_addr, he->h_addr, (size_t)he->h_length); 538 823 caster.sin_family = AF_INET; 539 caster.sin_port = htons(inport); 540 541 fprintf(stderr, "%s input: host = %s, port = %d, %s%s%s%s%s\n", 542 inputmode == CASTER ? "caster" : inputmode == SISNET ? "sisnet" : 543 inputmode == TCPSOCKET ? "tcp socket" : "udp socket", 544 bindmode ? "127.0.0.1" : inet_ntoa(caster.sin_addr), 545 inport, stream_name ? "stream = " : "", stream_name ? stream_name : "", 546 initfile ? ", initfile = " : "", initfile ? initfile : "", 547 bindmode ? "binding mode" : ""); 548 549 if(bindmode) 550 { 551 if(bind(gpsfd, (struct sockaddr *) &caster, sizeof(caster)) < 0) 552 { 553 fprintf(stderr, "ERROR: can't bind input to port %d\n", inport); 554 exit(1); 555 } 556 } /* connect to input-caster or proxy server*/ 557 else if(connect(gpsfd, (struct sockaddr *)&caster, sizeof(caster)) < 0) 558 { 559 fprintf(stderr, "ERROR: can't connect input to %s at port %d\n", 560 inet_ntoa(caster.sin_addr), inport); 561 exit(1); 562 } 563 564 if(stream_name) /* input from Ntrip Version 1.0 caster*/ 565 { 566 int init = 0; 567 568 /* set socket buffer size */ 569 setsockopt(gpsfd, SOL_SOCKET, SO_SNDBUF, (const char *) &size, 570 sizeof(const char *)); 571 if(stream_user && stream_password) 572 { 573 /* leave some space for login */ 574 nBufferBytes=snprintf(szSendBuffer, sizeof(szSendBuffer)-40, 575 "GET %s/%s HTTP/1.0\r\n" 576 "User-Agent: %s/%s\r\n" 577 "Authorization: Basic ", get_extension, stream_name, 578 AGENTSTRING, revisionstr); 579 /* second check for old glibc */ 580 if(nBufferBytes > (int)sizeof(szSendBuffer)-40 || nBufferBytes < 0) 581 { 582 fprintf(stderr, "ERROR: Source caster request too long\n"); 583 exit(1); 584 } 585 nBufferBytes += encode(szSendBuffer+nBufferBytes, 586 sizeof(szSendBuffer)-nBufferBytes-4, stream_user, stream_password); 587 if(nBufferBytes > (int)sizeof(szSendBuffer)-4) 588 { 824 caster.sin_port = htons(outport); 825 826 /* connect to Destination caster or Proxy server*/ 827 fprintf(stderr, "caster output: host = %s, port = %d, mountpoint = %s" 828 ", mode = %s\n\n", inet_ntoa(caster.sin_addr), outport, mountpoint, 829 outputmode == NTRIP1 ? "ntrip1" : outputmode == HTTP ? "http" : "rtsp"); 830 831 if(connect(socket_tcp, (struct sockaddr *) &caster, sizeof(caster)) < 0) 832 { 833 fprintf(stderr, "WARNING: can't connect output to %s at port %d\n", 834 inet_ntoa(caster.sin_addr), outport); 835 break; 836 } 837 838 /*** OutputMode handling ***/ 839 switch(outputmode) 840 { 841 case NTRIP1: /*** OutputMode Ntrip Version 1.0 ***/ 842 nBufferBytes = snprintf(szSendBuffer, sizeof(szSendBuffer), 843 "SOURCE %s %s/%s\r\n" 844 "Source-Agent: %s/%s\r\n\r\n", 845 password, post_extension, mountpoint, AGENTSTRING, revisionstr); 846 if((nBufferBytes > (int)sizeof(szSendBuffer)) || (nBufferBytes < 0)) 847 { 848 fprintf(stderr, "ERROR: Destination caster request to long\n"); 849 reconnect_sec_max = 0; 850 output_init = 0; 851 break; 852 } 853 if(!send_to_caster(szSendBuffer, socket_tcp, nBufferBytes)) 854 { 855 output_init = 0; 856 break; 857 } 858 /* check Destination caster's response */ 859 nBufferBytes = recv(socket_tcp, szSendBuffer, sizeof(szSendBuffer), 0); 860 szSendBuffer[nBufferBytes] = '\0'; 861 if(!strstr(szSendBuffer, "OK")) 862 { 863 char *a; 589 864 fprintf(stderr, 590 "ERROR: Source caster user ID and/or password too long\n"); 591 exit(1); 592 } 593 szSendBuffer[nBufferBytes++] = '\r'; 594 szSendBuffer[nBufferBytes++] = '\n'; 595 szSendBuffer[nBufferBytes++] = '\r'; 596 szSendBuffer[nBufferBytes++] = '\n'; 597 } 598 else 599 { 865 "ERROR: Destination caster's or Proxy's reply is not OK: "); 866 for(a = szSendBuffer; *a && *a != '\n' && *a != '\r'; ++a) 867 { 868 fprintf(stderr, "%.1s", isprint(*a) ? a : "."); 869 } 870 fprintf(stderr, "\n"); 871 if((strstr(szSendBuffer,"ERROR - Bad Password")) 872 || (strstr(szSendBuffer,"400 Bad Request"))) 873 reconnect_sec_max = 0; 874 output_init = 0; 875 break; 876 } 877 #ifndef NDEBUG 878 else 879 { 880 fprintf(stderr, "Destination caster response:\n%s\n", 881 szSendBuffer); 882 } 883 #endif 884 send_receive_loop(socket_tcp, gpsfd, outputmode, NULL, 0); 885 break; 886 case HTTP: /*** Ntrip-Version 2.0 HTTP/1.1 ***/ 600 887 nBufferBytes = snprintf(szSendBuffer, sizeof(szSendBuffer), 601 "GET %s/%s HTTP/1.0\r\n" 602 "User-Agent: %s/%s\r\n" 603 "\r\n", get_extension, stream_name, AGENTSTRING, revisionstr); 604 } 605 if((send(gpsfd, szSendBuffer, (size_t)nBufferBytes, 0)) 606 != nBufferBytes) 607 { 608 fprintf(stderr, "ERROR: could not send Source caster request\n"); 609 exit(1); 610 } 611 nBufferBytes = 0; 612 /* check Source caster's response */ 613 while(!init && nBufferBytes < (int)sizeof(szSendBuffer) 614 && (nBufferBytes += recv(gpsfd, szSendBuffer, 615 sizeof(szSendBuffer)-nBufferBytes, 0)) > 0) 616 { 617 if(strstr(szSendBuffer, "\r\n")) 618 { 619 if(!strncmp(szSendBuffer, "ICY 200 OK\r\n", 10)) 620 init = 1; 621 else 622 { 623 int k; 624 fprintf(stderr, 625 "ERROR: could not get requested data from Source caster: "); 626 for(k = 0; k < nBufferBytes && szSendBuffer[k] != '\n' 627 && szSendBuffer[k] != '\r'; ++k) 628 { 629 fprintf(stderr, "%c", isprint(szSendBuffer[k]) 630 ? szSendBuffer[k] : '.'); 631 } 632 fprintf(stderr, "\n"); 633 exit(1); 634 } 635 } 636 } 637 if(!init) 638 { 639 fprintf(stderr, "ERROR: could not init Source caster download\n"); 640 exit(1); 641 } 642 } /* end input from Ntrip Version 1.0 caster */ 643 644 if(initfile && inputmode != SISNET) 645 { 646 char buffer[1024]; 647 FILE *fh; 648 int i; 649 650 if((fh = fopen(initfile, "r"))) 651 { 652 while((i = fread(buffer, 1, sizeof(buffer), fh)) > 0) 653 { 654 if((send(gpsfd, buffer, (size_t)i, 0)) != i) 655 { 656 perror("ERROR: sending init file"); 657 exit(1); 658 } 659 } 660 if(i < 0) 661 { 662 perror("ERROR: reading init file"); 663 exit(1); 664 } 665 fclose(fh); 666 } 667 else 668 { 669 fprintf(stderr, "ERROR: can't read init file <%s>\n", initfile); 670 exit(1); 671 } 672 } 673 } 674 if(inputmode == SISNET) 675 { 676 int i, j; 677 char buffer[1024]; 678 679 i = snprintf(buffer, sizeof(buffer), sisnet >= 30 ? "AUTH,%s,%s\r\n" 680 : "AUTH,%s,%s", sisnetuser, sisnetpassword); 681 if((send(gpsfd, buffer, (size_t)i, 0)) != i) 682 { 683 perror("ERROR: sending authentication for SISNeT data server"); 684 exit(1); 685 } 686 i = sisnet >= 30 ? 7 : 5; 687 if((j = recv(gpsfd, buffer, i, 0)) != i && strncmp("*AUTH", buffer, 5)) 688 { 689 fprintf(stderr, "ERROR: SISNeT connect failed:"); 690 for(i = 0; i < j; ++i) 691 { 692 if(buffer[i] != '\r' && buffer[i] != '\n') 693 { 694 fprintf(stderr, "%c", isprint(buffer[i]) ? buffer[i] : '.'); 695 } 696 } 697 fprintf(stderr, "\n"); 698 exit(1); 699 } 700 if(sisnet >= 31) 701 { 702 if((send(gpsfd, "START\r\n", 7, 0)) != i) 703 { 704 perror("ERROR: sending Sisnet start command"); 705 exit(1); 706 } 707 } 708 } 709 /*** receiver authentication ***/ 710 if (recvrid && recvrpwd && ((inputmode == TCPSOCKET) 711 || (inputmode == UDPSOCKET))) 712 { 713 if (strlen(recvrid) > (BUFSZ-3)) 714 { 715 fprintf(stderr, "ERROR: Receiver ID too long\n"); 716 exit(0); 717 } 718 else 719 { 720 fprintf(stderr, "Sending user ID for receiver...\n"); 721 nBufferBytes = read(gpsfd, szSendBuffer, BUFSZ); 722 strcpy(szSendBuffer, recvrid); 723 strcat(szSendBuffer,"\r\n"); 724 send(gpsfd,szSendBuffer, strlen(szSendBuffer), MSG_DONTWAIT); 725 } 726 727 if (strlen(recvrpwd) > (BUFSZ-3)) 728 { 729 fprintf(stderr, "ERROR: Receiver password too long\n"); 730 exit(0); 731 } 732 else 733 { 734 fprintf(stderr, "Sending user password for receiver...\n"); 735 nBufferBytes = read(gpsfd, szSendBuffer, BUFSZ); 736 strcpy(szSendBuffer, recvrpwd); 737 strcat(szSendBuffer,"\r\n"); 738 send(gpsfd, szSendBuffer, strlen(szSendBuffer), MSG_DONTWAIT); 739 } 740 } 741 break; 742 default: 743 usage(-1, argv[0]); 744 break; 745 } 746 747 /* ----- main part ----- */ 748 /* setup signal handler for CTRL+C */ 749 setup_signal_handler(SIGINT, handle_sigint); 750 751 while(outputmode != END) 752 { 753 if(signal_was_caught()) 754 { 755 fprintf(stderr, "NtripLinuxServer terminates\n"); 756 break; 757 } 758 759 if(!(he = gethostbyname(outhost))) 760 { 761 fprintf(stderr, "ERROR: Destination caster or proxy host <%s> unknown\n", 762 outhost); 763 usage(-2, argv[0]); 764 } 765 766 /* create socket */ 767 if((socket_tcp = socket(AF_INET, SOCK_STREAM, 0)) < 0) 768 { 769 perror("ERROR: tcp socket"); 770 exit(2); 771 } 772 773 memset((char *) &caster, 0x00, sizeof(caster)); 774 memcpy(&caster.sin_addr, he->h_addr, (size_t)he->h_length); 775 caster.sin_family = AF_INET; 776 caster.sin_port = htons(outport); 777 778 /* connect to Destination caster or Proxy server*/ 779 fprintf(stderr, "caster output: host = %s, port = %d, mountpoint = %s" 780 ", mode = %s\n", inet_ntoa(caster.sin_addr), outport, mountpoint, 781 outputmode == NTRIPV1 ? "ntrip1" : outputmode == HTTP ? "http" : "rtsp"); 782 783 if(connect(socket_tcp, (struct sockaddr *) &caster, sizeof(caster)) < 0) 784 { 785 fprintf(stderr, "ERROR: can't connect output to %s at port %d\n", 786 inet_ntoa(caster.sin_addr), outport); 787 if(close(socket_tcp)==-1) perror("ERROR: close tcp socket"); 788 exit(3); 789 } 790 791 /*** OutputMode handling ***/ 792 switch(outputmode){ 793 case NTRIPV1: /*** OutputMode Ntrip Version 1.0 ***/ 794 nBufferBytes = snprintf(szSendBuffer, sizeof(szSendBuffer), 795 "SOURCE %s %s/%s\r\n" 796 "Source-Agent: %s\r\n\r\n", 797 password, post_extension, mountpoint, AGENTSTRING); 798 if((nBufferBytes > (int)sizeof(szSendBuffer)) || (nBufferBytes < 0)) 799 { 800 fprintf(stderr, "ERROR: Destination caster request to long\n"); 801 outputmode = END; 802 break; 803 } 804 if(!send_to_caster(szSendBuffer, socket_tcp, nBufferBytes)) 805 { 806 outputmode = END; 807 break; 808 } 809 /* check Destination caster's response */ 810 nBufferBytes = recv(socket_tcp, szSendBuffer, sizeof(szSendBuffer), 0); 811 szSendBuffer[nBufferBytes] = '\0'; 812 if(!strstr(szSendBuffer, "OK")) 813 { 814 char *a; 815 fprintf(stderr, 816 "ERROR: Destination caster's or Proxy's reply is not OK: "); 817 for(a = szSendBuffer; *a && *a != '\n' && *a != '\r'; ++a) 818 { 819 fprintf(stderr, "%.1s", isprint(*a) ? a : "."); 820 } 821 fprintf(stderr, "\n"); 822 outputmode = END; 823 break; 824 } 825 #ifndef NDEBUG 826 else 827 { 828 fprintf(stderr, 829 "Destination caster response:\n%s\nconnection successfull\n", 830 szSendBuffer); 831 } 832 #endif 833 send_receive_loop(socket_tcp, gpsfd, outputmode, NULL, 0); 834 break; 835 case HTTP: /*** Ntrip-Version 2.0 HTTP/1.1 ***/ 836 nBufferBytes = snprintf(szSendBuffer, sizeof(szSendBuffer), 837 "POST %s/%s HTTP/1.1\r\n" 838 "Host: %s\r\n" 839 "Ntrip-Version: Ntrip/2.0\r\n" 840 "User-Agent: %s/%s\r\n" 841 "Authorization: Basic %s\r\n" 842 "Ntrip-STR: %s\r\n" 843 "Transfer-Encoding: chunked\r\n\r\n", 844 post_extension, mountpoint, casterouthost, AGENTSTRING, 845 revisionstr, authorization, ntrip_str); 846 if((nBufferBytes > (int)sizeof(szSendBuffer)) || (nBufferBytes < 0)) 847 { 848 fprintf(stderr, "ERROR: Destination caster request to long\n"); 849 outputmode = END; 850 break; 851 } 852 if (!send_to_caster(szSendBuffer, socket_tcp, nBufferBytes)) 853 { 854 outputmode = END; 855 break; 856 } 857 /* check Destination caster's response */ 858 nBufferBytes = recv(socket_tcp, szSendBuffer, sizeof(szSendBuffer), 0); 859 szSendBuffer[nBufferBytes] = '\0'; 860 if(!strstr(szSendBuffer, "HTTP/1.1 200 OK")) 861 { 862 char *a; 863 fprintf(stderr, 864 "ERROR: Destination caster's%s reply is not OK: ", 865 *proxyhost ? " or Proxy's" : ""); 866 for(a = szSendBuffer; *a && *a != '\n' && *a != '\r'; ++a) 867 { 868 fprintf(stderr, "%.1s", isprint(*a) ? a : "."); 869 } 870 fprintf(stderr, "\n"); 871 /* fallback if necessary */ 872 if(!strstr(szSendBuffer,"Ntrip-Version: Ntrip/2.0\r\n")) 873 { 874 fprintf(stderr, 875 " Ntrip Version 2.0 not implemented at Destination caster" 876 " <%s>%s%s%s\n%s\n" 877 "caster fallback: Fallback to Ntrip Version 1.0\n", 878 casterouthost, 879 *proxyhost ? " or Proxy <" : "", proxyhost, *proxyhost ? ">" : "", 880 *proxyhost ? " or HTTP/1.1 not implemented at Proxy\n" : ""); 881 outputmode = NTRIPV1; 888 "POST %s/%s HTTP/1.1\r\n" 889 "Host: %s\r\n" 890 "Ntrip-Version: Ntrip/2.0\r\n" 891 "User-Agent: %s/%s\r\n" 892 "Authorization: Basic %s\r\n" 893 "Ntrip-STR: %s\r\n" 894 "Transfer-Encoding: chunked\r\n\r\n", 895 post_extension, mountpoint, casterouthost, AGENTSTRING, 896 revisionstr, authorization, ntrip_str); 897 if((nBufferBytes > (int)sizeof(szSendBuffer)) || (nBufferBytes < 0)) 898 { 899 fprintf(stderr, "ERROR: Destination caster request to long\n"); 900 reconnect_sec_max = 0; 901 output_init = 0; 882 902 break; 883 903 } 884 outputmode = END; 885 break; 886 } 887 #ifndef NDEBUG 888 else 889 { 890 fprintf(stderr, "Destination caster response:\n%s\n" 891 "connection successfull\n",szSendBuffer); 892 } 893 #endif 894 send_receive_loop(socket_tcp, gpsfd, outputmode, NULL, 0); 895 break; 896 case RTSP: /*** Ntrip-Version 2.0 RTSP / RTP ***/ 897 if((socket_udp = socket(AF_INET, SOCK_DGRAM,0)) < 0) 898 { 899 perror("ERROR: udp socket"); 900 exit(4); 901 } 902 /* fill structure with local address information for UDP */ 903 memset(&local, 0, sizeof(local)); 904 local.sin_family = AF_INET; 905 local.sin_port = htons(0); 906 local.sin_addr.s_addr = htonl(INADDR_ANY); 907 len = (socklen_t)sizeof(local); 908 /* bind() in order to get a random RTP client_port */ 909 if((bind(socket_udp,(struct sockaddr *)&local, len)) < 0) 910 { 911 perror("ERROR: udp bind"); 912 if(close(socket_udp)==-1) perror("ERROR: close udp socket"); 913 if(close(socket_tcp)==-1) perror("ERROR: close tcp socket"); 914 exit(4); 915 } 916 if((getsockname(socket_udp, (struct sockaddr*)&local, &len)) != -1) 917 { 918 client_port = (unsigned int)ntohs(local.sin_port); 919 }else{ 920 perror("ERROR: getsockname(localhost)"); 921 if(close(socket_udp)==-1) perror("ERROR: close udp socket"); 922 if(close(socket_tcp)==-1) perror("ERROR: close tcp socket"); 923 exit(4); 924 } 925 nBufferBytes = snprintf(szSendBuffer, sizeof(szSendBuffer), 926 "SETUP rtsp://%s%s/%s RTSP/1.0\r\n" 927 "CSeq: 1\r\n" 928 "Ntrip-Version: Ntrip/2.0\r\n" 929 "Ntrip-Component: Ntripserver\r\n" 930 "User-Agent: %s/%s\r\n" 931 "Transport: RTP/GNSS;unicast;client_port=%u\r\n" 932 "Authorization: Basic %s\r\n" 933 "Ntrip-STR: %s\r\n\r\n", 934 casterouthost, rtsp_extension, mountpoint, AGENTSTRING, revisionstr, 935 client_port, authorization, ntrip_str); 936 if((nBufferBytes > (int)sizeof(szSendBuffer)) || (nBufferBytes < 0)) 937 { 938 fprintf(stderr, "ERROR: Destination caster request to long\n"); 939 outputmode = END; 940 break; 941 } 942 if (!send_to_caster(szSendBuffer, socket_tcp, nBufferBytes)) 943 { 944 outputmode = END; 945 break; 946 } 947 while((nBufferBytes = recv(socket_tcp, szSendBuffer, 948 sizeof(szSendBuffer), 0)) > 0) 949 { 904 if(!send_to_caster(szSendBuffer, socket_tcp, nBufferBytes)) 905 { 906 output_init = 0; 907 break; 908 } 950 909 /* check Destination caster's response */ 910 nBufferBytes = recv(socket_tcp, szSendBuffer, sizeof(szSendBuffer), 0); 951 911 szSendBuffer[nBufferBytes] = '\0'; 952 if(!strstr(szSendBuffer, " RTSP/1.0200 OK"))912 if(!strstr(szSendBuffer, "HTTP/1.1 200 OK")) 953 913 { 954 914 char *a; … … 958 918 for(a = szSendBuffer; *a && *a != '\n' && *a != '\r'; ++a) 959 919 { 960 fprintf(stderr, "% c", isprint(*a) ? *a : '.');920 fprintf(stderr, "%.1s", isprint(*a) ? a : "."); 961 921 } 962 922 fprintf(stderr, "\n"); 963 923 /* fallback if necessary */ 964 if( strncmp(szSendBuffer, "RTSP",4) != 0)924 if(!strstr(szSendBuffer,"Ntrip-Version: Ntrip/2.0\r\n")) 965 925 { 966 if(strstr(szSendBuffer,"Ntrip-Version: Ntrip/2.0\r\n")) 926 fprintf(stderr, 927 " Ntrip Version 2.0 not implemented at Destination caster" 928 " <%s>%s%s%s\n%s\n" 929 "ntripserver falls back to Ntrip Version 1.0\n\n", 930 casterouthost, 931 *proxyhost ? " or Proxy <" : "", proxyhost, *proxyhost ? ">" : "", 932 *proxyhost ? " or HTTP/1.1 not implemented at Proxy\n" : ""); 933 close_session(casterouthost, mountpoint, cseq, session, rtsp_extension, 1); 934 outputmode = NTRIP1; 935 break; 936 } 937 else if((strstr(szSendBuffer,"HTTP/1.1 401 Unauthorized")) 938 || (strstr(szSendBuffer,"501 Not Implemented"))) 939 { 940 reconnect_sec_max = 0; 941 } 942 output_init = 0; 943 break; 944 } 945 #ifndef NDEBUG 946 else 947 { 948 fprintf(stderr, "Destination caster response:\n%s\n",szSendBuffer); 949 } 950 #endif 951 send_receive_loop(socket_tcp, gpsfd, outputmode, NULL, 0); 952 break; 953 case RTSP: /*** Ntrip-Version 2.0 RTSP / RTP ***/ 954 if((socket_udp = socket(AF_INET, SOCK_DGRAM,0)) < 0) 955 { 956 perror("ERROR: udp socket"); 957 exit(4); 958 } 959 /* fill structure with local address information for UDP */ 960 memset(&local, 0, sizeof(local)); 961 local.sin_family = AF_INET; 962 local.sin_port = htons(0); 963 local.sin_addr.s_addr = htonl(INADDR_ANY); 964 len = (socklen_t)sizeof(local); 965 /* bind() in order to get a random RTP client_port */ 966 if((bind(socket_udp,(struct sockaddr *)&local, len)) < 0) 967 { 968 perror("ERROR: udp bind"); 969 reconnect_sec_max = 0; 970 output_init = 0; 971 break; 972 } 973 if((getsockname(socket_udp, (struct sockaddr*)&local, &len)) != -1) 974 { 975 client_port = (unsigned int)ntohs(local.sin_port); 976 } 977 else 978 { 979 perror("ERROR: getsockname(localhost)"); 980 reconnect_sec_max = 0; 981 output_init = 0; 982 break; 983 } 984 nBufferBytes = snprintf(szSendBuffer, sizeof(szSendBuffer), 985 "SETUP rtsp://%s%s/%s RTSP/1.0\r\n" 986 "CSeq: 1\r\n" 987 "Ntrip-Version: Ntrip/2.0\r\n" 988 "Ntrip-Component: Ntripserver\r\n" 989 "User-Agent: %s/%s\r\n" 990 "Transport: RTP/GNSS;unicast;client_port=%u\r\n" 991 "Authorization: Basic %s\r\n" 992 "Ntrip-STR: %s\r\n\r\n", 993 casterouthost, rtsp_extension, mountpoint, AGENTSTRING, revisionstr, 994 client_port, authorization, ntrip_str); 995 if((nBufferBytes > (int)sizeof(szSendBuffer)) || (nBufferBytes < 0)) 996 { 997 fprintf(stderr, "ERROR: Destination caster request to long\n"); 998 reconnect_sec_max = 0; 999 output_init = 0; 1000 break; 1001 } 1002 if(!send_to_caster(szSendBuffer, socket_tcp, nBufferBytes)) 1003 { 1004 output_init = 0; 1005 break; 1006 } 1007 while((nBufferBytes = recv(socket_tcp, szSendBuffer, 1008 sizeof(szSendBuffer), 0)) > 0) 1009 { 1010 /* check Destination caster's response */ 1011 szSendBuffer[nBufferBytes] = '\0'; 1012 if(!strstr(szSendBuffer, "RTSP/1.0 200 OK")) 1013 { 1014 char *a; 1015 fprintf(stderr, 1016 "ERROR: Destination caster's%s reply is not OK: ", 1017 *proxyhost ? " or Proxy's" : ""); 1018 for(a = szSendBuffer; *a && *a != '\n' && *a != '\r'; ++a) 967 1019 { 968 fprintf(stderr, 969 " - RTSP not implemented at Destination caster <%s>%s%s%s\n\n" 970 "caster fallback: Fallback to Ntrip Version 2.0 in TCP/IP" 971 " mode\n\n", casterouthost, 972 *proxyhost ? " or Proxy <" :"", proxyhost, *proxyhost ? ">":""); 973 outputmode = HTTP; 1020 fprintf(stderr, "%c", isprint(*a) ? *a : '.'); 1021 } 1022 fprintf(stderr, "\n"); 1023 /* fallback if necessary */ 1024 if(strncmp(szSendBuffer, "RTSP",4) != 0) 1025 { 1026 if(strstr(szSendBuffer,"Ntrip-Version: Ntrip/2.0\r\n")) 1027 { 1028 fprintf(stderr, 1029 " RTSP not implemented at Destination caster <%s>%s%s%s\n\n" 1030 "ntripserver falls back to Ntrip Version 2.0 in TCP/IP" 1031 " mode\n\n", casterouthost, 1032 *proxyhost ? " or Proxy <" :"", proxyhost, *proxyhost ? ">":""); 1033 close_session(casterouthost, mountpoint, cseq, session, rtsp_extension, 1); 1034 outputmode = HTTP; 1035 break; 1036 } 1037 else 1038 { 1039 fprintf(stderr, 1040 " Ntrip-Version 2.0 not implemented at Destination caster" 1041 "<%s>%s%s%s\n%s" 1042 " or RTSP/1.0 not implemented at Destination caster%s\n\n" 1043 "ntripserver falls back to Ntrip Version 1.0\n\n", 1044 casterouthost, *proxyhost ? " or Proxy <" :"", proxyhost, 1045 *proxyhost ? ">":"", 1046 *proxyhost ? " or HTTP/1.1 not implemented at Proxy\n" : "", 1047 *proxyhost ? " or Proxy" :""); 1048 close_session(casterouthost, mountpoint, cseq, session, rtsp_extension, 1); 1049 outputmode = NTRIP1; 1050 break; 1051 } 1052 } 1053 else if((strstr(szSendBuffer, "RTSP/1.0 401 Unauthorized")) 1054 || (strstr(szSendBuffer, "RTSP/1.0 501 Not Implemented"))) 1055 { 1056 reconnect_sec_max = 0; 1057 } 1058 output_init = 0; 1059 break; 1060 } 1061 #ifndef NDEBUG 1062 else 1063 { 1064 fprintf(stderr, "Destination caster response:\n%s\n",szSendBuffer); 1065 } 1066 #endif 1067 if((strstr(szSendBuffer,"RTSP/1.0 200 OK\r\n")) 1068 && (strstr(szSendBuffer,"CSeq: 1\r\n"))) 1069 { 1070 for(token = strtok(szSendBuffer, dlim); token != NULL; 1071 token = strtok(NULL, dlim)) 1072 { 1073 tok_buf[i] = token; i++; 1074 } 1075 session = atoi(tok_buf[6]); 1076 server_port = atoi(tok_buf[10]); 1077 nBufferBytes = snprintf(szSendBuffer, sizeof(szSendBuffer), 1078 "POST rtsp://%s%s/%s RTSP/1.0\r\n" 1079 "CSeq: 2\r\n" 1080 "Session: %d\r\n" 1081 "\r\n", 1082 casterouthost, rtsp_extension, mountpoint, session); 1083 if((nBufferBytes >= (int)sizeof(szSendBuffer)) 1084 || (nBufferBytes < 0)) 1085 { 1086 fprintf(stderr, "ERROR: Destination caster request to long\n"); 1087 reconnect_sec_max = 0; 1088 output_init = 0; 1089 break; 1090 } 1091 if(!send_to_caster(szSendBuffer, socket_tcp, nBufferBytes)) 1092 { 1093 output_init = 0; 1094 break; 1095 } 1096 } 1097 else if((strstr(szSendBuffer,"RTSP/1.0 200 OK\r\n")) && (strstr(szSendBuffer, 1098 "CSeq: 2\r\n"))) 1099 { 1100 /* fill structure with caster address information for UDP */ 1101 memset(&casterRTP, 0, sizeof(casterRTP)); 1102 casterRTP.sin_family = AF_INET; 1103 casterRTP.sin_port = htons(((uint16_t)server_port)); 1104 if((he = gethostbyname(outhost))== NULL) 1105 { 1106 fprintf(stderr, "ERROR: Destination caster unknown\n"); 1107 reconnect_sec_max = 0; 1108 output_init = 0; 974 1109 break; 975 1110 } 976 1111 else 977 1112 { 978 fprintf(stderr, 979 " Ntrip-Version 2.0 not implemented at Destination caster" 980 "<%s>%s%s%s\n%s" 981 " or RTSP/1.0 not implemented at Destination caster%s\n\n" 982 "caster fallback: Fallback to Ntrip Version 1.0\n", 983 casterouthost, *proxyhost ? " or Proxy <" :"", proxyhost, 984 *proxyhost ? ">":"", 985 *proxyhost ? " or HTTP/1.1 not implemented at Proxy\n" : "", 986 *proxyhost ? " or Proxy" :""); 987 outputmode = NTRIPV1; 988 break; 1113 memcpy((char *)&casterRTP.sin_addr.s_addr, 1114 he->h_addr_list[0], (size_t)he->h_length); 989 1115 } 990 }991 else992 {993 outputmode = END;1116 cseq = 2; 1117 len = (socklen_t)sizeof(casterRTP); 1118 send_receive_loop(socket_udp, gpsfd, outputmode, (struct sockaddr *)&casterRTP, 1119 (socklen_t)len); 994 1120 break; 995 1121 } 996 } 997 #ifndef NDEBUG 998 else 999 { 1000 fprintf(stderr, "Destination caster response:\n%s\n",szSendBuffer); 1001 } 1002 #endif 1003 if((strstr(szSendBuffer,"RTSP/1.0 200 OK\r\n")) 1004 && (strstr(szSendBuffer,"CSeq: 1\r\n"))) 1005 { 1006 for(token = strtok(szSendBuffer, dlim); token != NULL; 1007 token = strtok(NULL, dlim)) 1008 { 1009 tok_buf[i] = token; i++; 1010 } 1011 session = atoi(tok_buf[6]); 1012 server_port = atoi(tok_buf[10]); 1013 nBufferBytes = snprintf(szSendBuffer, sizeof(szSendBuffer), 1014 "POST rtsp://%s%s/%s RTSP/1.0\r\n" 1015 "CSeq: 2\r\n" 1016 "Session: %d\r\n" 1017 "\r\n", 1018 casterouthost, rtsp_extension, mountpoint, session); 1019 if((nBufferBytes >= (int)sizeof(szSendBuffer)) 1020 || (nBufferBytes < 0)) 1021 { 1022 fprintf(stderr, "ERROR: Destination caster request to long\n"); 1023 outputmode = END; 1024 break; 1025 } 1026 if(!send_to_caster(szSendBuffer, socket_tcp, nBufferBytes)) 1027 { 1028 outputmode = END; 1029 break; 1030 } 1031 }else if((strstr(szSendBuffer,"RTSP/1.0 200 OK\r\n")) && (strstr(szSendBuffer,"CSeq: 2\r\n"))) { 1032 /* fill structure with caster address information for UDP */ 1033 memset(&casterRTP, 0, sizeof(casterRTP)); 1034 casterRTP.sin_family = AF_INET; 1035 casterRTP.sin_port = htons(((uint16_t)server_port)); 1036 if((he = gethostbyname(outhost))== NULL) { 1037 fprintf(stderr, "ERROR: Destination caster unknown\n"); 1038 if(close(socket_udp)==-1) perror("ERROR: close udp socket"); 1039 if(close(socket_tcp)==-1) perror("ERROR: close tcp socket"); 1040 exit(4); 1041 }else{ 1042 memcpy((char *)&casterRTP.sin_addr.s_addr, 1043 he->h_addr_list[0], (size_t)he->h_length); 1044 } 1045 cseq = 2; 1046 len = (socklen_t)sizeof(casterRTP); 1047 send_receive_loop(socket_udp, gpsfd, outputmode, (struct sockaddr *)&casterRTP, (socklen_t)len); 1048 break; 1049 }else{break;} 1050 } 1051 break; 1052 } 1053 } 1054 close_session(socket_udp, socket_tcp, casterouthost, mountpoint, cseq, session, rtsp_extension, gpsfd); 1122 else{break;} 1123 } 1124 break; 1125 } 1126 } 1127 close_session(casterouthost, mountpoint, cseq, session, rtsp_extension, 0); 1128 if((!sigint_received) && (reconnect_sec_max)) 1129 { 1130 reconnect_sec = reconnect(reconnect_sec, reconnect_sec_max); 1131 } 1132 else inputmode = LAST; 1133 } 1055 1134 return 0; 1056 1135 } … … 1076 1155 /* data transmission */ 1077 1156 fprintf(stderr,"transfering data ...\n"); 1078 1157 int send_recv_success = 0; 1079 1158 while(1) 1080 1159 { 1160 if(send_recv_success < 3) send_recv_success++; 1161 if(!nodata) alarm(ALARMTIME); 1162 else nodata = 0; 1163 1081 1164 /* signal handling*/ 1082 if(signal_was_caught()) 1083 { 1084 fprintf(stderr, "NtripLinuxServer exits send-receive mode\n"); 1085 break; 1086 } 1087 if(!nodata) alarm(ALARMTIME); 1088 else nodata = 0; 1089 1165 if((sigint_received) || (sigpipe_received) || (sigalarm_received)) break; 1166 1090 1167 if(!nBufferBytes) 1091 1168 { … … 1101 1178 if((send(gpsfd, "MSG\r\n", i, 0)) != i) 1102 1179 { 1103 perror(" ERROR: sending SISNeT data request");1104 exit(1);1180 perror("WARNING: sending SISNeT data request failed"); 1181 return; 1105 1182 } 1106 1183 } … … 1114 1191 continue; 1115 1192 } 1116 else if( nBufferBytes < 0)1117 { 1118 perror(" ERROR: reading input failed");1119 exit(1);1193 else if((nBufferBytes < 0) && (!sigint_received)) 1194 { 1195 perror("WARNING: reading input failed"); 1196 return; 1120 1197 } 1121 1198 /* we can compare the whole buffer, as the additional bytes … … 1128 1205 } 1129 1206 /** send data ***/ 1130 if((nBufferBytes) && (outmode == NTRIP V1)) /*** Ntrip-Version 1.0 ***/1207 if((nBufferBytes) && (outmode == NTRIP1)) /*** Ntrip-Version 1.0 ***/ 1131 1208 { 1132 1209 int i; … … 1138 1215 if(errno != EAGAIN) 1139 1216 { 1140 perror("WARNING: could not send data to Destination caster" 1141 " - retry connection"); 1142 close(sock); 1143 sleep(5); 1217 perror("WARNING: could not send data to Destination caster"); 1144 1218 return; 1145 1219 } … … 1169 1243 if(errno != EAGAIN) 1170 1244 { 1171 perror("WARNING: could not send data to Destination caster" 1172 " - retry connection"); 1173 close(sock); 1174 sleep(5); 1245 perror("WARNING: could not send data to Destination caster"); 1175 1246 return; 1176 1247 } … … 1195 1266 char rtpbuffer[BUFSZ+12]; 1196 1267 int i, j; 1197 /* Signal Handling */1198 if(signal_was_caught())1199 {1200 fprintf(stderr, "NtripLinuxServer exits send-receive mode\n");1201 break;1202 }1203 1268 gettimeofday(&now, NULL); 1204 1269 /* RTP data packet generation*/ … … 1242 1307 if(errno != EAGAIN) 1243 1308 { 1244 perror("WARNING: could not send data to Destination caster - retry connection"); 1245 close(sock); 1246 sleep(5); 1309 perror("WARNING: could not send data to Destination caster"); 1247 1310 return; 1248 1311 } … … 1259 1322 } 1260 1323 } 1324 if(send_recv_success == 3) reconnect_sec = 1; 1261 1325 } 1262 1326 return; … … 1422 1486 fprintf(stderr, " optional\n"); 1423 1487 fprintf(stderr, " -F <ProxyPort> Proxy server IP port, required i.e. when running\n"); 1424 fprintf(stderr, " the program in a proxy server protected LAN, optional\n\n"); 1488 fprintf(stderr, " the program in a proxy server protected LAN, optional\n"); 1489 fprintf(stderr, " -R <maxDelay> Reconnect mechanism with maximum delay between reconnect\n"); 1490 fprintf(stderr, " attemts in seconds, default: no reconnect activated,\n"); 1491 fprintf(stderr, " optional\n\n"); 1425 1492 fprintf(stderr, " -M <InputMode> Sets the input mode (1 = Serial Port, 2 = IP server,\n"); 1426 1493 fprintf(stderr, " 3 = File, 4 = SISNeT Data Server, 5 = UDP server, 6 = NTRIP Caster),\n"); … … 1464 1531 fprintf(stderr, " for protected streams if <InputMode> = 6\n\n"); 1465 1532 fprintf(stderr, " -O <OutputMode> Sets output mode for communatation with destination caster\n"); 1466 fprintf(stderr, " 0 = h = http: Ntrip Version 2.0 Caster in TCP/IP mode\n"); 1467 fprintf(stderr, " 1 = r = rtsp: NTRIP Version 2.0 Caster in RTSP/RTP mode\n"); 1468 fprintf(stderr, " 2 = n = ntrip1: NTRIP Version 1.0 Caster\n\n"); 1469 fprintf(stderr, " Defaults to NTRIP1.0, but wil change to 2.0 in future versions\n"); 1470 fprintf(stderr, " Note that the program automatically falls back from mode r to mode t and\n"); 1471 fprintf(stderr, " further to mode f if necessary.\n\n"); 1533 fprintf(stderr, " 1 = http: NTRIP Version 2.0 Caster in TCP/IP mode\n"); 1534 fprintf(stderr, " 2 = rtsp: NTRIP Version 2.0 Caster in RTSP/RTP mode\n"); 1535 fprintf(stderr, " 3 = ntrip1: NTRIP Version 1.0 Caster\n"); 1536 fprintf(stderr, " optional\n\n"); 1537 fprintf(stderr, " Defaults to NTRIP1.0, but will change to 2.0 in future versions\n"); 1538 fprintf(stderr, " Note that the program automatically falls back from mode rtsp to mode http and\n"); 1539 fprintf(stderr, " further to mode ntrip1 if necessary.\n\n"); 1472 1540 fprintf(stderr, " -a <DestHost> Destination caster name or address, default: 127.0.0.1,\n"); 1473 1541 fprintf(stderr, " mandatory\n"); … … 1481 1549 fprintf(stderr, " mountpoint, mandatory\n"); 1482 1550 fprintf(stderr, " -N <STR-record> Sourcetable STR-record\n"); 1483 fprintf(stderr, " optional for N tripVersion 2.0 in RTSP/RTP and TCP/IP mode\n\n");1551 fprintf(stderr, " optional for NTRIP Version 2.0 in RTSP/RTP and TCP/IP mode\n\n"); 1484 1552 exit(rc); 1485 1553 } /* usage */ … … 1494 1562 static void handle_sigint(int sig) 1495 1563 #endif /* __GNUC__ */ 1496 {sigint_received = 1;} 1564 { 1565 sigint_received = 1; 1566 fprintf(stderr, "WARNING: SIGINT received - ntripserver terminates\n"); 1567 } 1568 1569 #ifdef __GNUC__ 1570 static void handle_alarm(int sig __attribute__((__unused__))) 1571 #else /* __GNUC__ */ 1572 static void handle_alarm(int sig) 1573 #endif /* __GNUC__ */ 1574 { 1575 sigalarm_received = 1; 1576 fprintf(stderr, "ERROR: more than %d seconds no activity\n", ALARMTIME); 1577 } 1578 1579 #ifdef __GNUC__ 1580 static void handle_sigpipe(int sig __attribute__((__unused__))) 1581 #else /* __GNUC__ */ 1582 static void handle_sigpipe(int sig) 1583 #endif /* __GNUC__ */ 1584 {sigpipe_received = 1;} 1497 1585 1498 1586 static void setup_signal_handler(int sig, void (*handler)(int)) … … 1511 1599 return; 1512 1600 } /* setupsignal_handler */ 1513 1514 static int signal_was_caught(void)1515 {1516 fflush(stdout);1517 if(sigint_received)1518 fprintf(stderr, "SIGINT received: ");1519 1520 return (sigint_received);1521 } /* signal_was_caught */1522 1601 1523 1602 /******************************************************************** … … 1584 1663 if((send(socket, input, (size_t)input_size, 0)) != input_size) 1585 1664 { 1586 fprintf(stderr, " ERROR: could not send full header to Destination caster\n");1665 fprintf(stderr, "WARNING: could not send full header to Destination caster\n"); 1587 1666 send_error = 0; 1588 1667 } … … 1599 1678 1600 1679 /******************************************************************** 1680 * reconnect * 1681 *********************************************************************/ 1682 int reconnect(int rec_sec, int rec_sec_max) 1683 { 1684 fprintf(stderr,"reconnect in <%d> seconds\n\n", rec_sec); 1685 rec_sec *= 2; 1686 if (rec_sec > rec_sec_max) rec_sec = rec_sec_max; 1687 sleep(rec_sec); 1688 sigalarm_received = 0; 1689 sigpipe_received = 0; 1690 return rec_sec; 1691 } /* reconnect */ 1692 1693 1694 /******************************************************************** 1601 1695 * close session * 1602 1696 *********************************************************************/ 1603 static void close_session(int sock_udp, int sock_tcp, 1604 const char *caster_addr, const char *mountpoint, int cseq, 1605 int session, char *rtsp_ext, int in_fd) 1697 static void close_session(const char *caster_addr, const char *mountpoint, 1698 int cseq, int session, char *rtsp_ext, int fallback) 1606 1699 { 1607 1700 int size_send_buf; 1608 1701 char send_buf[BUFSZ]; 1609 1702 1610 if( in_fd)1611 { 1612 if(close( in_fd)==-1)1703 if((gpsfd != -1) && (!fallback)) 1704 { 1705 if(close(gpsfd) == -1) 1613 1706 { 1614 1707 perror("ERROR: close input device "); 1615 1708 exit(0); 1616 1709 } 1617 #ifndef NDEBUG1618 1710 else 1619 1711 { 1620 fprintf(stderr, "\nclose input device: successful\n"); 1621 } 1712 gpsfd = -1; 1713 #ifndef NDEBUG 1714 fprintf(stderr, "close input device: successful\n"); 1622 1715 #endif 1623 } 1624 1625 if(sock_udp != 0) 1716 } 1717 } 1718 1719 if(socket_udp != -1) 1626 1720 { 1627 1721 if(cseq == 2) … … 1638 1732 exit(0); 1639 1733 } 1640 send_to_caster(send_buf, sock _tcp, size_send_buf); strcpy(send_buf,"");1641 size_send_buf = recv(sock _tcp, send_buf, sizeof(send_buf), 0);1734 send_to_caster(send_buf, socket_tcp, size_send_buf); strcpy(send_buf,""); 1735 size_send_buf = recv(socket_tcp, send_buf, sizeof(send_buf), 0); 1642 1736 send_buf[size_send_buf] = '\0'; 1643 1737 #ifndef NDEBUG … … 1645 1739 #endif 1646 1740 } 1647 if(close(sock _udp)==-1)1741 if(close(socket_udp)==-1) 1648 1742 { 1649 1743 perror("ERROR: close udp socket"); 1650 1744 exit(0); 1651 1745 } 1746 else 1747 { 1748 socket_udp = -1; 1652 1749 #ifndef NDEBUG 1750 fprintf(stderr, "close udp socket: successful\n"); 1751 #endif 1752 } 1753 } 1754 1755 if(socket_tcp != -1) 1756 { 1757 if(close(socket_tcp) == -1) 1758 { 1759 perror("ERROR: close tcp socket"); 1760 exit(0); 1761 } 1653 1762 else 1654 1763 { 1655 fprintf(stderr, "close udp socket: successful\n"); 1656 } 1764 socket_tcp = -1; 1765 #ifndef NDEBUG 1766 fprintf(stderr, "close tcp socket: successful\n"); 1657 1767 #endif 1658 } 1659 1660 if(close(sock_tcp)==-1) 1661 { 1662 perror("ERROR: close tcp socket"); 1663 exit(0); 1664 } 1665 #ifndef NDEBUG 1666 else 1667 { 1668 fprintf(stderr, "close tcp socket: successful\n\n"); 1669 } 1670 #endif 1768 } 1769 } 1671 1770 } /* close_session */
Note:
See TracChangeset
for help on using the changeset viewer.