Changeset 467 in ntrip
- Timestamp:
- Jun 6, 2007, 2:16:08 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/ntripserver/NtripLinuxServer.c
r466 r467 1 1 /* 2 * $Id: NtripLinux Client.c,v 1.27 2007/05/16 14:16:21stoecker Exp $2 * $Id: NtripLinuxServer.c,v 1.28 2007/06/06 09:44:27 stoecker Exp $ 3 3 * 4 4 * Copyright (c) 2003...2007 … … 11 11 * 12 12 * The BKG disclaims any liability nor responsibility to any person or 13 * entity with respect to any loss or damage caused, or alleged to be 14 * caused, directly or indirectly by the use and application of the NTRIP 13 * entity with respect to any loss or damage caused, or alleged to be 14 * caused, directly or indirectly by the use and application of the NTRIP 15 15 * technology. 16 16 * 17 17 * For latest information and updates, access: 18 * http://igs. ifag.de/index_ntrip.htm18 * http://igs.bkg.bund.de/index_ntrip_down.htm 19 19 * 20 * Georg Weber 21 * BKG, Frankfurt, Germany, June 2003-06-13 20 * BKG, Frankfurt, Germany, February 2007 22 21 * E-mail: euref-ip@bkg.bund.de 23 *24 * Based on the GNU General Public License published nmead25 22 * 26 23 * This program is free software; you can redistribute it and/or … … 36 33 * You should have received a copy of the GNU General Public License 37 34 * along with this program; if not, write to the Free Software 38 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 39 * USA. 35 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 40 36 */ 41 37 42 38 /* CVS revision and version */ 43 static char revisionstr[] = "$Revision: 1.2 7$";44 static char datestr[] = "$Date: 2007/0 5/16 14:16:21$";39 static char revisionstr[] = "$Revision: 1.28 $"; 40 static char datestr[] = "$Date: 2007/06/06 09:44:27 $"; 45 41 46 42 #include <ctype.h> … … 59 55 #include <sys/termios.h> 60 56 #include <sys/types.h> 57 #include <sys/time.h> 61 58 62 59 #ifndef COMPILEDATE … … 72 69 73 70 enum MODE { SERIAL = 1, TCPSOCKET = 2, INFILE = 3, SISNET = 4, UDPSOCKET = 5, 74 CASTER = 6, LAST}; 71 CASTER = 6, LAST }; 72 73 enum OUTMODE { NTRIPV1, HTTP, RTSP, END }; 75 74 76 75 #define AGENTSTRING "NTRIP NtripServerLinux" 77 76 #define BUFSZ 1024 77 #define SZ 64 78 78 79 79 /* default socket source */ … … 91 91 #define ALARMTIME 60 92 92 93 #define RTP_VERSION 2 94 #define TIME_RESOLUTION 125 95 93 96 static int ttybaud = 19200; 94 97 static const char *ttyport = "/dev/gps"; 95 98 static const char *filepath = "/dev/stdin"; 96 static enum MODE mode= INFILE;99 static enum MODE inputmode = INFILE; 97 100 static int sisnet = 31; 98 101 static int gpsfd = -1; 102 static int sigint_received = 0; 99 103 100 104 /* Forward references */ 101 static int openserial(const char * tty, int blocksz, int baud); 102 static void send_receive_loop(int sock, int fd); 103 static void usage(int, char*); 104 static int encode(char *buf, int size, const char *user, const char *pwd); 105 static int openserial(const char * tty, int blocksz, int baud); 106 static void send_receive_loop(int sock, int fd, int outmode, 107 struct sockaddr * pcasterRTP, socklen_t length); 108 static void usage(int, char *); 109 static int encode(char *buf, int size, const char *user, const char *pwd); 110 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); 114 115 /* Signal Handling */ 116 static void handle_sigint(int sig); 117 static void setup_signal_handler(int sig, void (*handler)(int)); 118 static int signal_was_caught(void); 105 119 106 120 #ifdef __GNUC__ … … 135 149 int main(int argc, char **argv) 136 150 { 137 int c; 138 int size = 2048; /* for setting send buffer size */ 139 140 const char *inhost = 0; 141 const char *outhost = 0; 142 unsigned int outport = 0; 143 unsigned int inport = 0; 144 const char *mountpoint = NULL; 145 const char *password = ""; 146 const char *sisnetpassword = ""; 147 const char *sisnetuser = ""; 148 149 const char *stream_name=0; 150 const char *stream_user=0; 151 const char *stream_password=0; 152 153 const char *initfile = NULL; 154 155 const char *recvrid=0; 156 const char *recvrpwd=0; 157 158 int bindmode = 0; 159 int sock_id; 160 char szSendBuffer[BUFSZ]; 161 int nBufferBytes; 162 struct hostent *he; 163 struct sockaddr_in addr; 151 int c; 152 int size = 2048; /* for setting send buffer size */ 153 struct sockaddr_in caster; 154 const char * proxyhost = ""; 155 unsigned int proxyport = 0; 156 /*** INPUT ***/ 157 const char * casterinhost = 0; 158 unsigned int casterinport = 0; 159 const char * inhost = 0; 160 unsigned int inport = 0; 161 162 char get_extension[SZ] = ""; 163 164 struct hostent * he; 165 const char * mountpoint = NULL; 166 167 const char * sisnetpassword = ""; 168 const char * sisnetuser = ""; 169 170 const char * stream_name = 0; 171 const char * stream_user = 0; 172 const char * stream_password = 0; 173 174 const char * recvrid= 0; 175 const char * recvrpwd = 0; 176 177 const char * initfile = NULL; 178 179 int bindmode = 0; 180 181 /*** OUTPUT ***/ 182 const char * casterouthost = 0; 183 unsigned int casteroutport = 0; 184 const char * outhost = 0; 185 unsigned int outport = 0; 186 char post_extension[SZ] = ""; 187 char rtsp_extension[SZ] = ""; 188 189 const char * ntrip_str = ""; 190 191 const char * user = ""; 192 const char * password = ""; 193 194 int socket_tcp = 0; 195 int outputmode = NTRIPV1; 196 197 struct sockaddr_in casterRTP; 198 struct sockaddr_in local; 199 int socket_udp = 0; 200 int client_port = 0; 201 int server_port = 0; 202 int session = 0; 203 int cseq = 0; 204 socklen_t len = 0; 205 int i = 0; 206 207 char szSendBuffer[BUFSZ]; 208 char authorization[SZ]; 209 int nBufferBytes = 0; 210 char * dlim = " \r\n="; 211 char * token; 212 char * tok_buf[BUFSZ]; 164 213 165 214 setbuf(stdout, 0); … … 167 216 setbuf(stderr, 0); 168 217 218 { 169 219 char *a; 170 220 int i = 0; … … 182 232 datestr[4] = datestr[7] = '-'; 183 233 datestr[10] = 0; 184 234 } 235 236 /* setup signal handler for timeout */ 185 237 signal(SIGALRM,sighandler_alarm); 186 238 alarm(ALARMTIME); 239 187 240 /* get and check program arguments */ 188 241 if(argc <= 1) … … 191 244 exit(1); 192 245 } 193 while((c = getopt(argc, argv, "M:i:h:b:p:s:a:m:c:H:P:f:x:y:l:u:V:D:U:W:B"))194 != EOF)246 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) 195 248 { 196 249 switch (c) 197 250 { 198 case 'M': 199 if(!strcmp(optarg, "serial")) mode = SERIAL; 200 else if(!strcmp(optarg, "tcpsocket")) mode = TCPSOCKET; 201 else if(!strcmp(optarg, "file")) mode = INFILE; 202 else if(!strcmp(optarg, "sisnet")) mode = SISNET; 203 else if(!strcmp(optarg, "udpsocket")) mode = UDPSOCKET; 204 else if(!strcmp(optarg, "caster")) mode = CASTER; 205 else mode = atoi(optarg); 206 if((mode == 0) || (mode >= LAST)) 207 { 208 fprintf(stderr, "ERROR: can't convert %s to a valid mode\n", optarg); 251 case 'M': /*** InputMode ***/ 252 if(!strcmp(optarg, "serial")) inputmode = SERIAL; 253 else if(!strcmp(optarg, "tcpsocket")) inputmode = TCPSOCKET; 254 else if(!strcmp(optarg, "file")) inputmode = INFILE; 255 else if(!strcmp(optarg, "sisnet")) inputmode = SISNET; 256 else if(!strcmp(optarg, "udpsocket")) inputmode = UDPSOCKET; 257 else if(!strcmp(optarg, "caster")) inputmode = CASTER; 258 else inputmode = atoi(optarg); 259 if((inputmode == 0) || (inputmode >= LAST)) 260 { 261 fprintf(stderr, "ERROR: can't convert <%s> to a valid InputMode\n", 262 optarg); 209 263 usage(-1, argv[0]); 210 264 } 211 265 break; 212 case 'i': /* gps serial ttyport*/266 case 'i': /* serial input device */ 213 267 ttyport = optarg; 214 268 break; 215 case 'B': 269 case 'B': /* bind to incoming UDP stream */ 216 270 bindmode = 1; 217 271 break; 218 case 'V': 219 if(!strcmp("3.0", optarg)) sisnet = 30;272 case 'V': /* Sisnet data server version number */ 273 if(!strcmp("3.0", optarg)) sisnet = 30; 220 274 else if(!strcmp("3.1", optarg)) sisnet = 31; 221 275 else if(!strcmp("2.1", optarg)) sisnet = 21; 222 276 else 223 277 { 224 fprintf(stderr, "ERROR: unknown SISNeT version %s\n", optarg);278 fprintf(stderr, "ERROR: unknown SISNeT version <%s>\n", optarg); 225 279 usage(-2, argv[0]); 226 280 } 227 281 break; 228 case 'b': /* serial ttyin speed*/282 case 'b': /* serial input baud rate */ 229 283 ttybaud = atoi(optarg); 230 284 if(ttybaud <= 1) 231 285 { 232 fprintf(stderr, "ERROR: can't convert %s to valid serial speed\n",286 fprintf(stderr, "ERROR: can't convert <%s> to valid serial baud rate\n", 233 287 optarg); 234 288 usage(1, argv[0]); 235 289 } 236 290 break; 237 case 'a': /* http server IP address A.B.C.D*/238 outhost = optarg;239 break; 240 case 'p': /* http server port */241 outport = atoi(optarg);242 if( outport <= 1 ||outport > 65535)291 case 'a': /* Destination caster address */ 292 casterouthost = optarg; 293 break; 294 case 'p': /* Destination caster port */ 295 casteroutport = atoi(optarg); 296 if(casteroutport <= 1 || casteroutport > 65535) 243 297 { 244 298 fprintf(stderr, 245 "ERROR: can't convert %sto a valid HTTP server port\n", optarg);299 "ERROR: can't convert <%s> to a valid HTTP server port\n", optarg); 246 300 usage(1, argv[0]); 247 301 } 248 302 break; 249 case 'm': /* http server mountpoint*/303 case 'm': /* Destination caster mountpoint for stream upload */ 250 304 mountpoint = optarg; 251 305 break; 252 case 's': /* datastreamfrom file */306 case 's': /* File name for input data simulation from file */ 253 307 filepath = optarg; 254 308 break; 255 case 'f': 309 case 'f': /* name of an initialization file */ 256 310 initfile = optarg; 257 311 break; 258 case 'x': 259 recvrid = optarg; 260 break; 261 case 'y': 262 recvrpwd = optarg; 263 break; 264 case 'u': 312 case 'x': /* user ID to access incoming stream */ 313 recvrid = optarg; 314 break; 315 case 'y': /* password to access incoming stream */ 316 recvrpwd = optarg; 317 break; 318 case 'u': /* Sisnet data server user ID */ 265 319 sisnetuser = optarg; 266 320 break; 267 case 'l': 321 case 'l': /* Sisnet data server password */ 268 322 sisnetpassword = optarg; 269 323 break; 270 case 'c': /* DestinationCasterPassword*/324 case 'c': /* DestinationCaster password for stream upload to mountpoint */ 271 325 password = optarg; 272 326 break; 273 case 'H': /* SourceCasterHost*/274 inhost = optarg;275 break; 276 case 'P': /* SourceCasterPort */277 inport = atoi(optarg);278 if( inport <= 1 ||inport > 65535)279 { 280 fprintf(stderr, "ERROR: can't convert %sto a valid port number\n",327 case 'H': /* Input host address*/ 328 casterinhost = optarg; 329 break; 330 case 'P': /* Input port */ 331 casterinport = atoi(optarg); 332 if(casterinport <= 1 || casterinport > 65535) 333 { 334 fprintf(stderr, "ERROR: can't convert <%s> to a valid port number\n", 281 335 optarg); 282 336 usage(1, argv[0]); 283 337 } 284 338 break; 285 case 'D': 286 stream_name=optarg; /* desired stream from SourceCaster */ 287 break; 288 case 'U': 289 stream_user=optarg; /* username for desired stream */ 339 case 'D': /* Source caster mountpoint for stream input */ 340 stream_name = optarg; 290 341 break; 291 case ' W':292 stream_ password=optarg; /* passwd for desired stream */342 case 'U': /* Source caster user ID for input stream access */ 343 stream_user = optarg; 293 344 break; 294 case 'h': /* help */ 345 case 'W': /* Source caster password for input stream access */ 346 stream_password = optarg; 347 break; 348 case 'E': /* Proxy Server */ 349 proxyhost = optarg; 350 break; 351 case 'F': /* Proxy port */ 352 proxyport = atoi(optarg); 353 break; 354 case 'O': /* OutputMode - default: Ntrip-Version 2.0 TCP/IP */ 355 if (!strcmp(optarg,"f")) outputmode = NTRIPV1; 356 else if(!strcmp(optarg,"r")) outputmode = RTSP; 357 break; 358 case 'n': /* Destination caster user ID for stream upload to mountpoint */ 359 user = optarg; 360 break; 361 case 'N': /* Ntrip-STR, optional for Ntrip Version 2.0 */ 362 ntrip_str = optarg; 363 break; 364 case 'h': /* print help screen */ 295 365 case '?': 296 366 usage(0, argv[0]); … … 305 375 argv += optind; 306 376 377 /*** argument analysis ***/ 307 378 if(argc > 0) 308 379 { … … 316 387 } 317 388 318 if(mountpoint == NULL) 319 { 320 fprintf(stderr, "ERROR: Missing mountpoint argument\n"); 389 if(*ntrip_str && (outputmode == NTRIPV1)) 390 { 391 fprintf(stderr, "WARNING: OutputMode is Ntrip version 1.0" 392 " - Ntrip-STR will not be considered\n"); 393 } 394 395 if(!mountpoint) 396 { 397 fprintf(stderr, "ERROR: Missing mountpoint argument for stream upload\n"); 321 398 exit(1); 322 399 } 400 323 401 if(!password[0]) 324 402 { 325 fprintf(stderr, 326 "WARNING: Missing password argument - are you really sure?\n"); 403 fprintf(stderr, "WARNING: Missing password argument for stream upload - " 404 "are you really sure?\n"); 405 } 406 else 407 { 408 nBufferBytes += encode(authorization, sizeof(authorization), user, 409 password); 410 if(nBufferBytes > (int)sizeof(authorization)) 411 { 412 fprintf(stderr, "ERROR: user ID and/or password too long: %d (%d)\n" 413 " user ID: %s \npassword: <%s>\n", 414 nBufferBytes, (int)sizeof(authorization), user, password); 415 exit(1); 416 } 327 417 } 328 418 329 419 if(stream_name && stream_user && !stream_password) 330 420 { 331 fprintf(stderr, "WARNING: Missing password argument for download"421 fprintf(stderr, "WARNING: Missing password argument for stream download" 332 422 " - are you really sure?\n"); 333 423 } 334 424 335 if(!outhost) outhost = NTRIP_CASTER; 336 if(!outport) outport = NTRIP_PORT; 337 338 switch(mode) 425 /*** proxy server handling ***/ 426 if(*proxyhost) 427 { 428 outhost = inhost = proxyhost; 429 outport = inport = proxyport; 430 i = snprintf(szSendBuffer, sizeof(szSendBuffer),"http://%s:%d", 431 casterouthost, casteroutport); 432 if((i > SZ) || (i < 0)) 433 { 434 fprintf(stderr, "ERROR: Destination caster name/port to long - " 435 "length = %d (max: %d)\n", i, SZ); 436 exit(0); 437 } 438 else 439 { 440 strncpy(post_extension, szSendBuffer, (size_t)i); 441 strcpy(szSendBuffer, ""); 442 i = snprintf(szSendBuffer, sizeof(szSendBuffer),":%d", casteroutport); 443 strncpy(rtsp_extension, szSendBuffer, SZ); 444 strcpy(szSendBuffer,""); i = 0; 445 } 446 i = snprintf(szSendBuffer, sizeof(szSendBuffer),"http://%s:%d", casterinhost, casterinport); 447 if((i > SZ) || (i < 0)) 448 { 449 fprintf(stderr, "ERROR: Destination caster name/port to long - length = %d (max: %d)\n", i, SZ); 450 exit(0); 451 } 452 else 453 { 454 strncpy(get_extension, szSendBuffer, (size_t)i); 455 strcpy(szSendBuffer, ""); 456 i = 0; 457 } 458 } 459 else 460 { 461 outhost = casterouthost; outport = casteroutport; 462 inhost = casterinhost; inport = casterinport; 463 } 464 465 /*** InputMode handling ***/ 466 switch(inputmode) 339 467 { 340 468 case INFILE: … … 345 473 exit(1); 346 474 } 347 /* set blocking mode in case it was not set475 /* set blocking inputmode in case it was not set 348 476 (seems to be sometimes for fifo's) */ 349 477 fcntl(gpsfd, F_SETFL, 0); … … 351 479 } 352 480 break; 353 case SERIAL: 481 case SERIAL: /* open serial port */ 354 482 { 355 483 gpsfd = openserial(ttyport, 1, ttybaud); … … 363 491 case TCPSOCKET: case UDPSOCKET: case SISNET: case CASTER: 364 492 { 365 if( mode == SISNET)493 if(inputmode == SISNET) 366 494 { 367 495 if(!inhost) inhost = SISNET_SERVER; 368 496 if(!inport) inport = SISNET_PORT; 369 497 } 370 else if( mode == CASTER)498 else if(inputmode == CASTER) 371 499 { 372 500 if(!inport) inport = NTRIP_PORT; 373 501 if(!inhost) inhost = NTRIP_CASTER; 374 502 } 375 else if(( mode == TCPSOCKET) || (mode == UDPSOCKET))503 else if((inputmode == TCPSOCKET) || (inputmode == UDPSOCKET)) 376 504 { 377 505 if(!inport) inport = SERV_TCP_PORT; 378 506 if(!inhost) inhost = "127.0.0.1"; 379 } 507 } 380 508 381 509 if(!(he = gethostbyname(inhost))) 382 510 { 383 fprintf(stderr, "ERROR: host %sunknown\n", inhost);511 fprintf(stderr, "ERROR: Input host <%s> unknown\n", inhost); 384 512 usage(-2, argv[0]); 385 513 } 386 514 387 if((gpsfd = socket(AF_INET, mode == UDPSOCKET515 if((gpsfd = socket(AF_INET, inputmode == UDPSOCKET 388 516 ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0) 389 517 { 390 fprintf(stderr, "ERROR: can't create socket\n"); 518 fprintf(stderr, 519 "ERROR: can't create socket for incoming data stream\n"); 391 520 exit(1); 392 521 } 393 522 394 memset((char *) & addr, 0x00, sizeof(addr));523 memset((char *) &caster, 0x00, sizeof(caster)); 395 524 if(!bindmode) 396 memcpy(& addr.sin_addr, he->h_addr, (size_t)he->h_length);397 addr.sin_family = AF_INET;398 addr.sin_port = htons(inport);399 400 printf("%s input: host = %s, port = %d, %s%s%s%s%s\n",401 mode == CASTER ? "caster" :mode == SISNET ? "sisnet" :402 mode == TCPSOCKET ? "tcp socket" : "udp socket",403 bindmode ? "127.0.0.1" : inet_ntoa( addr.sin_addr),525 memcpy(&caster.sin_addr, he->h_addr, (size_t)he->h_length); 526 caster.sin_family = AF_INET; 527 caster.sin_port = htons(inport); 528 529 fprintf(stderr, "%s input: host = %s, port = %d, %s%s%s%s%s\n", 530 inputmode == CASTER ? "caster" : inputmode == SISNET ? "sisnet" : 531 inputmode == TCPSOCKET ? "tcp socket" : "udp socket", 532 bindmode ? "127.0.0.1" : inet_ntoa(caster.sin_addr), 404 533 inport, stream_name ? "stream = " : "", stream_name ? stream_name : "", 405 534 initfile ? ", initfile = " : "", initfile ? initfile : "", … … 408 537 if(bindmode) 409 538 { 410 if(bind(gpsfd, (struct sockaddr *) & addr, sizeof(addr)) < 0)539 if(bind(gpsfd, (struct sockaddr *) &caster, sizeof(caster)) < 0) 411 540 { 412 541 fprintf(stderr, "ERROR: can't bind input to port %d\n", inport); 413 542 exit(1); 414 543 } 415 } 416 else if(connect(gpsfd, (struct sockaddr *) &addr, sizeof(addr)) < 0)544 } /* connect to input-caster or proxy server*/ 545 else if(connect(gpsfd, (struct sockaddr *)&caster, sizeof(caster)) < 0) 417 546 { 418 547 fprintf(stderr, "ERROR: can't connect input to %s at port %d\n", 419 inet_ntoa(addr.sin_addr), inport);548 inet_ntoa(caster.sin_addr), inport); 420 549 exit(1); 421 550 } 422 423 if(stream_name) /* data stream from caster*/551 552 if(stream_name) /* input from Ntrip Version 1.0 caster*/ 424 553 { 425 554 int init = 0; … … 432 561 /* leave some space for login */ 433 562 nBufferBytes=snprintf(szSendBuffer, sizeof(szSendBuffer)-40, 434 "GET /%s HTTP/1.0\r\n"563 "GET %s/%s HTTP/1.0\r\n" 435 564 "User-Agent: %s/%s\r\n" 436 "Authorization: Basic ", stream_name, AGENTSTRING, revisionstr); 565 "Authorization: Basic ", get_extension, stream_name, 566 AGENTSTRING, revisionstr); 437 567 /* second check for old glibc */ 438 568 if(nBufferBytes > (int)sizeof(szSendBuffer)-40 || nBufferBytes < 0) 439 569 { 440 fprintf(stderr, " Requested datatoo long\n");570 fprintf(stderr, "ERROR: Source caster request too long\n"); 441 571 exit(1); 442 572 } … … 445 575 if(nBufferBytes > (int)sizeof(szSendBuffer)-4) 446 576 { 447 fprintf(stderr, "Username and/or password too long\n"); 577 fprintf(stderr, 578 "ERROR: Source caster user ID and/or password too long\n"); 448 579 exit(1); 449 580 } … … 456 587 { 457 588 nBufferBytes = snprintf(szSendBuffer, sizeof(szSendBuffer), 458 "GET /%s HTTP/1.0\r\n"589 "GET %s/%s HTTP/1.0\r\n" 459 590 "User-Agent: %s/%s\r\n" 460 "\r\n", stream_name, AGENTSTRING, revisionstr);591 "\r\n", get_extension, stream_name, AGENTSTRING, revisionstr); 461 592 } 462 593 if((send(gpsfd, szSendBuffer, (size_t)nBufferBytes, 0)) 463 594 != nBufferBytes) 464 595 { 465 fprintf(stderr, "ERROR: could not send to caster\n");596 fprintf(stderr, "ERROR: could not send Source caster request\n"); 466 597 exit(1); 467 598 } 468 599 nBufferBytes = 0; 469 /* check caster's response */600 /* check Source caster's response */ 470 601 while(!init && nBufferBytes < (int)sizeof(szSendBuffer) 471 602 && (nBufferBytes += recv(gpsfd, szSendBuffer, … … 479 610 { 480 611 int k; 481 fprintf(stderr, "Could not get the requested data: "); 612 fprintf(stderr, 613 "ERROR: could not get requested data from Source caster: "); 482 614 for(k = 0; k < nBufferBytes && szSendBuffer[k] != '\n' 483 615 && szSendBuffer[k] != '\r'; ++k) … … 493 625 if(!init) 494 626 { 495 fprintf(stderr, " Could not init caster download.");627 fprintf(stderr, "ERROR: could not init Source caster download\n"); 496 628 exit(1); 497 629 } 498 } /* end data stream fromcaster */499 500 if(initfile && mode != SISNET)630 } /* end input from Ntrip Version 1.0 caster */ 631 632 if(initfile && inputmode != SISNET) 501 633 { 502 634 char buffer[1024]; … … 523 655 else 524 656 { 525 fprintf(stderr, "ERROR: can't read init file %s\n", initfile);657 fprintf(stderr, "ERROR: can't read init file <%s>\n", initfile); 526 658 exit(1); 527 659 } 528 660 } 529 661 } 530 if( mode == SISNET)662 if(inputmode == SISNET) 531 663 { 532 664 int i, j; … … 537 669 if((send(gpsfd, buffer, (size_t)i, 0)) != i) 538 670 { 539 perror("ERROR: sending authentication ");671 perror("ERROR: sending authentication for SISNeT data server"); 540 672 exit(1); 541 673 } … … 558 690 if((send(gpsfd, "START\r\n", 7, 0)) != i) 559 691 { 560 perror("ERROR: sending start command");692 perror("ERROR: sending Sisnet start command"); 561 693 exit(1); 562 694 } 563 695 } 564 696 } 565 566 if (recvrid && recvrpwd && ((mode == TCPSOCKET) || (mode == UDPSOCKET))) 567 { 568 if (strlen(recvrid) > (BUFSZ-3)){ 569 fprintf(stderr, "Receiver ID too long\n"); exit(0); 570 }else{ 697 /*** receiver authentication ***/ 698 if (recvrid && recvrpwd && ((inputmode == TCPSOCKET) 699 || (inputmode == UDPSOCKET))) 700 { 701 if (strlen(recvrid) > (BUFSZ-3)) 702 { 703 fprintf(stderr, "ERROR: Receiver ID too long\n"); 704 exit(0); 705 } 706 else 707 { 571 708 fprintf(stderr, "Sending user ID for receiver...\n"); 572 nBufferBytes = read(gpsfd, szSendBuffer, BUFSZ); 709 nBufferBytes = read(gpsfd, szSendBuffer, BUFSZ); 573 710 strcpy(szSendBuffer, recvrid); 574 711 strcat(szSendBuffer,"\r\n"); 575 712 send(gpsfd,szSendBuffer, strlen(szSendBuffer), MSG_DONTWAIT); 576 713 } 577 578 if (strlen(recvrpwd) > (BUFSZ-3)){ 579 fprintf(stderr, "Receiver password too long\n"); exit(0); 580 }else{ 714 715 if (strlen(recvrpwd) > (BUFSZ-3)) 716 { 717 fprintf(stderr, "ERROR: Receiver password too long\n"); 718 exit(0); 719 } 720 else 721 { 581 722 fprintf(stderr, "Sending user password for receiver...\n"); 582 723 nBufferBytes = read(gpsfd, szSendBuffer, BUFSZ); 583 724 strcpy(szSendBuffer, recvrpwd); 584 725 strcat(szSendBuffer,"\r\n"); 585 send(gpsfd, szSendBuffer, strlen(szSendBuffer), MSG_DONTWAIT); 586 } 587 } 726 send(gpsfd, szSendBuffer, strlen(szSendBuffer), MSG_DONTWAIT); 727 } 728 } 588 729 break; 589 730 default: … … 593 734 594 735 /* ----- main part ----- */ 595 for(;;) 596 { 736 /* setup signal handler for CTRL+C */ 737 setup_signal_handler(SIGINT, handle_sigint); 738 739 while(outputmode != END) 740 { 741 if(signal_was_caught()) 742 { 743 fprintf(stderr, "NtripLinuxServer terminates\n"); 744 break; 745 } 746 597 747 if(!(he = gethostbyname(outhost))) 598 748 { 599 fprintf(stderr, "ERROR: host %s unknown\n", outhost); 749 fprintf(stderr, "ERROR: Destination caster or proxy host <%s> unknown\n", 750 outhost); 600 751 usage(-2, argv[0]); 601 752 } 602 753 603 754 /* create socket */ 604 if((sock _id= socket(AF_INET, SOCK_STREAM, 0)) < 0)605 { 606 fprintf(stderr, "ERROR: could not create socket\n");755 if((socket_tcp = socket(AF_INET, SOCK_STREAM, 0)) < 0) 756 { 757 perror("ERROR: tcp socket"); 607 758 exit(2); 608 759 } 609 760 610 memset((char *) & addr, 0x00, sizeof(addr));611 memcpy(& addr.sin_addr, he->h_addr, (size_t)he->h_length);612 addr.sin_family = AF_INET;613 addr.sin_port = htons(outport);614 615 /* connect to caster*/761 memset((char *) &caster, 0x00, sizeof(caster)); 762 memcpy(&caster.sin_addr, he->h_addr, (size_t)he->h_length); 763 caster.sin_family = AF_INET; 764 caster.sin_port = htons(outport); 765 766 /* connect to Destination caster or Proxy server*/ 616 767 fprintf(stderr, "caster output: host = %s, port = %d, mountpoint = %s\n", 617 inet_ntoa(addr.sin_addr), outport, mountpoint); 618 if(connect(sock_id, (struct sockaddr *) &addr, sizeof(addr)) < 0) 768 inet_ntoa(caster.sin_addr), outport, mountpoint); 769 770 if(connect(socket_tcp, (struct sockaddr *) &caster, sizeof(caster)) < 0) 619 771 { 620 772 fprintf(stderr, "ERROR: can't connect output to %s at port %d\n", 621 inet_ntoa( addr.sin_addr), outport);622 close(sock_id);773 inet_ntoa(caster.sin_addr), outport); 774 if(close(socket_tcp)==-1) perror("ERROR: close tcp socket"); 623 775 exit(3); 624 776 } 625 777 626 /* set socket buffer size */ 627 setsockopt(sock_id, SOL_SOCKET, SO_SNDBUF, (const char *) &size, 628 sizeof(const char *)); 629 /* send message to caster */ 630 nBufferBytes = sprintf(szSendBuffer, "SOURCE %s /%s\r\nSource-Agent: " 631 "%s/%s\r\n\r\n", password, mountpoint, AGENTSTRING, revisionstr); 632 if((send(sock_id, szSendBuffer, (size_t)nBufferBytes, 0)) != nBufferBytes) 633 { 634 fprintf(stderr, "ERROR: could not send to caster\n"); 635 break; 636 } 637 /* check caster's response */ 638 nBufferBytes = recv(sock_id, szSendBuffer, sizeof(szSendBuffer), 0); 639 szSendBuffer[nBufferBytes] = '\0'; 640 if(!strstr(szSendBuffer, "OK")) 641 { 642 char *a; 643 fprintf(stderr, "ERROR: caster's reply is not OK : "); 644 for(a = szSendBuffer; *a && *a != '\n' && *a != '\r'; ++a) 645 { 646 fprintf(stderr, "%.1s", isprint(*a) ? a : "."); 647 } 648 fprintf(stderr, "\n"); 649 break; 650 } 651 printf("connection successfull\n"); 652 send_receive_loop(sock_id, gpsfd); 653 } 654 close(sock_id); 655 sleep(5); 778 /*** OutputMode handling ***/ 779 switch(outputmode){ 780 case NTRIPV1: /*** OutputMode Ntrip Version 1.0 ***/ 781 nBufferBytes = snprintf(szSendBuffer, sizeof(szSendBuffer), 782 "SOURCE %s %s/%s\r\n" 783 "Source-Agent: %s\r\n\r\n", 784 password, post_extension, mountpoint, AGENTSTRING); 785 if((nBufferBytes > (int)sizeof(szSendBuffer)) || (nBufferBytes < 0)) 786 { 787 fprintf(stderr, "ERROR: Destination caster request to long\n"); 788 outputmode = END; 789 break; 790 } 791 if(!send_to_caster(szSendBuffer, socket_tcp, nBufferBytes)) 792 { 793 outputmode = END; 794 break; 795 } 796 /* check Destination caster's response */ 797 nBufferBytes = recv(socket_tcp, szSendBuffer, sizeof(szSendBuffer), 0); 798 szSendBuffer[nBufferBytes] = '\0'; 799 if(!strstr(szSendBuffer, "OK")) 800 { 801 char *a; 802 fprintf(stderr, 803 "ERROR: Destination caster's or Proxy's reply is not OK: "); 804 for(a = szSendBuffer; *a && *a != '\n' && *a != '\r'; ++a) 805 { 806 fprintf(stderr, "%.1s", isprint(*a) ? a : "."); 807 } 808 fprintf(stderr, "\n"); 809 outputmode = END; 810 break; 811 } 812 else 813 { 814 fprintf(stderr, 815 "Destination caster response:\n%s\nconnection successfull\n", 816 szSendBuffer); 817 } 818 send_receive_loop(socket_tcp, gpsfd, outputmode, NULL, 0); 819 break; 820 case HTTP: /*** Ntrip-Version 2.0 HTTP/1.1 ***/ 821 nBufferBytes = snprintf(szSendBuffer, sizeof(szSendBuffer), 822 "POST %s/%s HTTP/1.1\r\n" 823 "Host: %s\r\n" 824 "Ntrip-Version: Ntrip/2.0\r\n" 825 "User-Agent: NTRIP %s\r\n" 826 "Authorization: Basic %s\r\n" 827 "Ntrip-STR: %s\r\n" 828 "Transfer-Encoding: chunked\r\n\r\n", 829 post_extension, mountpoint, casterouthost, AGENTSTRING, 830 authorization, ntrip_str); 831 if((nBufferBytes > (int)sizeof(szSendBuffer)) || (nBufferBytes < 0)) 832 { 833 fprintf(stderr, "ERROR: Destination caster request to long\n"); 834 outputmode = END; 835 break; 836 } 837 if (!send_to_caster(szSendBuffer, socket_tcp, nBufferBytes)) 838 { 839 outputmode = END; 840 break; 841 } 842 /* check Destination caster's response */ 843 nBufferBytes = recv(socket_tcp, szSendBuffer, sizeof(szSendBuffer), 0); 844 szSendBuffer[nBufferBytes] = '\0'; 845 if(!strstr(szSendBuffer, "HTTP/1.1 200 OK")) 846 { 847 char *a; 848 fprintf(stderr, 849 "ERROR: Destination caster's or Proxy's reply is not OK: "); 850 for(a = szSendBuffer; *a && *a != '\n' && *a != '\r'; ++a) 851 { 852 fprintf(stderr, "%.1s", isprint(*a) ? a : "."); 853 } 854 fprintf(stderr, "\n"); 855 /* fallback if necessary */ 856 if(!strstr(szSendBuffer,"Ntrip-Version: Ntrip/2.0\r\n")) 857 { 858 fprintf(stderr, 859 " - Ntrip Version 2.0 not implemented at Destination caster" 860 " <%s> or Proxy <%s> or\n" 861 " - HTTP/1.1 not implemented at Proxy or\n" 862 " - RTSP/1.0 not implemented at Destination caster or Proxy\n\n" 863 "caster fallback: Fallback to Ntrip Version 1.0\n\n", 864 casterouthost, proxyhost); 865 outputmode = NTRIPV1; 866 break; 867 } 868 outputmode = END; 869 break; 870 } 871 else 872 { 873 fprintf(stderr, "Destination caster response:\n%s\n" 874 "connection successfull\n",szSendBuffer); 875 } 876 send_receive_loop(socket_tcp, gpsfd, outputmode, NULL, 0); 877 break; 878 case RTSP: /*** Ntrip-Version 2.0 RTSP / RTP ***/ 879 if((socket_udp = socket(AF_INET, SOCK_DGRAM,0)) < 0) 880 { 881 perror("ERROR: udp socket"); 882 exit(4); 883 } 884 /* fill structure with local address information for UDP */ 885 memset(&local, 0, sizeof(local)); 886 local.sin_family = AF_INET; 887 local.sin_port = htons(0); 888 local.sin_addr.s_addr = htonl(INADDR_ANY); 889 len = (socklen_t)sizeof(local); 890 /* bind() in order to get a random RTP client_port */ 891 if((bind(socket_udp,(struct sockaddr *)&local, len)) < 0) 892 { 893 perror("ERROR: udp bind"); 894 if(close(socket_udp)==-1) perror("ERROR: close udp socket"); 895 if(close(socket_tcp)==-1) perror("ERROR: close tcp socket"); 896 exit(4); 897 } 898 if((getsockname(socket_udp, (struct sockaddr*)&local, &len)) != -1) 899 { 900 client_port = (unsigned int)ntohs(local.sin_port); 901 }else{ 902 perror("ERROR: getsockname(localhost)"); 903 if(close(socket_udp)==-1) perror("ERROR: close udp socket"); 904 if(close(socket_tcp)==-1) perror("ERROR: close tcp socket"); 905 exit(4); 906 } 907 nBufferBytes = snprintf(szSendBuffer, sizeof(szSendBuffer), 908 "SETUP rtsp://%s%s/%s RTSP/1.0\r\n" 909 "CSeq: 1\r\n" 910 "Ntrip-Version: Ntrip/2.0\r\n" 911 "Ntrip-Component: Ntripserver\r\n" 912 "User-Agent: NTRIP %s \r\n" 913 "Transport: RTP/GNSS;unicast;client_port=%u\r\n" 914 "Authorization: Basic %s\r\n" 915 "Ntrip-STR: %s\r\n\r\n", 916 casterouthost, rtsp_extension, mountpoint, AGENTSTRING, client_port, 917 authorization, ntrip_str); 918 if((nBufferBytes > (int)sizeof(szSendBuffer)) || (nBufferBytes < 0)) 919 { 920 fprintf(stderr, "ERROR: Destination caster request to long\n"); 921 outputmode = END; 922 break; 923 } 924 if (!send_to_caster(szSendBuffer, socket_tcp, nBufferBytes)) 925 { 926 outputmode = END; 927 break; 928 } 929 while((nBufferBytes = recv(socket_tcp, szSendBuffer, 930 sizeof(szSendBuffer), 0)) > 0) 931 { 932 /* check Destination caster's response */ 933 szSendBuffer[nBufferBytes] = '\0'; 934 if(!strstr(szSendBuffer, "RTSP/1.0 200 OK")) 935 { 936 char *a; 937 fprintf(stderr, 938 "ERROR: Destination caster's or Proxy's reply is not OK: "); 939 for(a = szSendBuffer; *a && *a != '\n' && *a != '\r'; ++a) 940 { 941 fprintf(stderr, "%c", isprint(*a) ? *a : '.'); 942 } 943 fprintf(stderr, "\n"); 944 /* fallback if necessary */ 945 if(strncmp(szSendBuffer, "RTSP",4) != 0) 946 { 947 if(strstr(szSendBuffer,"Ntrip-Version: Ntrip/2.0\r\n")) 948 { 949 fprintf(stderr, 950 " - RTSP not implemented at Destination caster <%s> or" 951 " Proxy <%s>\n\n" 952 "caster fallback: Fallback to Ntrip Version 2.0 in TCP/IP" 953 " mode\n\n", casterouthost, proxyhost); 954 outputmode = HTTP; 955 break; 956 } 957 else 958 { 959 fprintf(stderr, 960 " - Ntrip-Version 2.0 not implemented at Destination caster" 961 "<%s> or Proxy <%s> or\n" 962 " - HTTP/1.1 not implemented at Proxy or\n" 963 " - RTSP/1.0 not implemented at Destination caster or Proxy\n\n" 964 "caster fallback: Fallback to Ntrip Version 1.0\n\n", 965 casterouthost, proxyhost); 966 outputmode = NTRIPV1; 967 break; 968 } 969 } 970 else 971 { 972 outputmode = END; 973 break; 974 } 975 } 976 else 977 { 978 fprintf(stderr, "Destination caster response:\n%s\n",szSendBuffer); 979 } 980 if((strstr(szSendBuffer,"RTSP/1.0 200 OK\r\n")) 981 && (strstr(szSendBuffer,"CSeq: 1\r\n"))) 982 { 983 for(token = strtok(szSendBuffer, dlim); token != NULL; 984 token = strtok(NULL, dlim)) 985 { 986 tok_buf[i] = token; i++; 987 } 988 session = atoi(tok_buf[6]); 989 server_port = atoi(tok_buf[10]); 990 nBufferBytes = snprintf(szSendBuffer, sizeof(szSendBuffer), 991 "POST rtsp://%s%s/%s RTSP/1.0\r\n" 992 "CSeq: 2\r\n" 993 "Session: %d\r\n" 994 "\r\n", 995 casterouthost, rtsp_extension, mountpoint, session); 996 if((nBufferBytes >= (int)sizeof(szSendBuffer)) 997 || (nBufferBytes < 0)) 998 { 999 fprintf(stderr, "ERROR: Destination caster request to long\n"); 1000 outputmode = END; 1001 break; 1002 } 1003 if(!send_to_caster(szSendBuffer, socket_tcp, nBufferBytes)) 1004 { 1005 outputmode = END; 1006 break; 1007 } 1008 }else if((strstr(szSendBuffer,"RTSP/1.0 200 OK\r\n")) && (strstr(szSendBuffer,"CSeq: 2\r\n"))) { 1009 /* fill structure with caster address information for UDP */ 1010 memset(&casterRTP, 0, sizeof(casterRTP)); 1011 casterRTP.sin_family = AF_INET; 1012 casterRTP.sin_port = htons(((uint16_t)server_port)); 1013 if((he = gethostbyname(outhost))== NULL) { 1014 fprintf(stderr, "ERROR: Destination caster unknown\n"); 1015 if(close(socket_udp)==-1) perror("ERROR: close udp socket"); 1016 if(close(socket_tcp)==-1) perror("ERROR: close tcp socket"); 1017 exit(4); 1018 }else{ 1019 memcpy((char *)&casterRTP.sin_addr.s_addr, 1020 he->h_addr_list[0], (size_t)he->h_length); 1021 } 1022 cseq = 2; 1023 len = (socklen_t)sizeof(casterRTP); 1024 send_receive_loop(socket_udp, gpsfd, outputmode, (struct sockaddr *)&casterRTP, (socklen_t)len); 1025 break; 1026 }else{break;} 1027 } 1028 break; 1029 } 1030 } 1031 close_session(socket_udp, socket_tcp, casterouthost, mountpoint, cseq, session, rtsp_extension, gpsfd); 656 1032 return 0; 657 1033 } 658 1034 659 static void send_receive_loop(int sock, int fd) 1035 static void send_receive_loop(int sock, int fd, int outmode, struct sockaddr* pcasterRTP, 1036 socklen_t length) 660 1037 { 661 1038 int nodata = 0; 662 1039 char buffer[BUFSZ] = { 0 }; 663 1040 char sisnetbackbuffer[200]; 1041 char szSendBuffer[BUFSZ] = ""; 664 1042 int nBufferBytes = 0; 1043 1044 /* RTSP / RTP Mode */ 1045 int isfirstpacket = 1; 1046 struct timeval now; 1047 struct timeval last = {0,0}; 1048 long int sendtimediff; 1049 int rtpseq = 0; 1050 int rtpssrc = 0; 1051 int rtptime = 0; 1052 665 1053 /* data transmission */ 666 printf("transfering data ...\n"); 1054 fprintf(stderr,"transfering data ...\n"); 1055 667 1056 while(1) 668 1057 { 1058 /* signal handling*/ 1059 if(signal_was_caught()) 1060 { 1061 fprintf(stderr, "NtripLinuxServer exits send-receive mode\n"); 1062 break; 1063 } 669 1064 if(!nodata) alarm(ALARMTIME); 670 1065 else nodata = 0; … … 672 1067 if(!nBufferBytes) 673 1068 { 674 if( mode == SISNET && sisnet <= 30)1069 if(inputmode == SISNET && sisnet <= 30) 675 1070 { 676 1071 int i; … … 683 1078 if((send(gpsfd, "MSG\r\n", i, 0)) != i) 684 1079 { 685 perror("ERROR: sending data request");1080 perror("ERROR: sending SISNeT data request"); 686 1081 exit(1); 687 1082 } 688 1083 } 689 /* receiving data*/1084 /*** receiving data ****/ 690 1085 nBufferBytes = read(fd, buffer, sizeof(buffer)); 691 1086 if(!nBufferBytes) … … 703 1098 /* we can compare the whole buffer, as the additional bytes 704 1099 remain unchanged */ 705 if( mode == SISNET && sisnet <= 30 &&1100 if(inputmode == SISNET && sisnet <= 30 && 706 1101 !memcmp(sisnetbackbuffer, buffer, sizeof(sisnetbackbuffer))) 707 1102 { … … 709 1104 } 710 1105 } 711 if(nBufferBytes) 1106 /** send data ***/ 1107 if((nBufferBytes) && (outmode == NTRIPV1)) /*** Ntrip-Version 1.0 ***/ 712 1108 { 713 1109 int i; 714 /* send data */715 1110 if((i = send(sock, buffer, (size_t)nBufferBytes, MSG_DONTWAIT)) 716 1111 != nBufferBytes) 717 1112 { 718 1113 if(i < 0) … … 720 1115 if(errno != EAGAIN) 721 1116 { 722 perror("WARNING: could not send data - retry connection"); 1117 perror("WARNING: could not send data to Destination caster" 1118 " - retry connection"); 723 1119 close(sock); 724 1120 sleep(5); … … 731 1127 nBufferBytes -= i; 732 1128 } 1129 }else 1130 { 1131 nBufferBytes = 0; 1132 } 1133 } 1134 /*** Ntrip-Version 2.0 HTTP/1.1 ***/ 1135 else if((nBufferBytes) && (outmode == HTTP)) 1136 { 1137 int i, nChunkBytes, j = 1; 1138 nChunkBytes = snprintf(szSendBuffer, sizeof(szSendBuffer),"%x\r\n", 1139 nBufferBytes); 1140 send(sock, szSendBuffer, nChunkBytes, MSG_DONTWAIT); 1141 if((i = send(sock, buffer, (size_t)nBufferBytes, MSG_DONTWAIT)) 1142 != nBufferBytes) 1143 { 1144 if(i < 0) 1145 { 1146 if(errno != EAGAIN) 1147 { 1148 perror("WARNING: could not send data to Destination caster" 1149 " - retry connection"); 1150 close(sock); 1151 sleep(5); 1152 return; 1153 } 1154 } 1155 else if(i) 1156 { 1157 while(j>0) 1158 { 1159 j = send(sock, buffer, (size_t)BUFSZ, MSG_DONTWAIT); 1160 } 1161 } 733 1162 } 734 1163 else 735 1164 { 1165 send(sock, "\r\n", strlen("\r\n"), MSG_DONTWAIT); 736 1166 nBufferBytes = 0; 737 1167 } 738 1168 } 739 } 1169 /*** Ntrip-Version 2.0 RTSP(TCP) / RTP(UDP) ***/ 1170 else if((nBufferBytes) && (outmode == RTSP)) 1171 { 1172 char rtpbuffer[BUFSZ+12]; 1173 int i, j; 1174 /* Signal Handling */ 1175 if(signal_was_caught()) 1176 { 1177 fprintf(stderr, "NtripLinuxServer exits send-receive mode \n"); 1178 break; 1179 } 1180 gettimeofday(&now, NULL); 1181 /* RTP data packet generation*/ 1182 if(isfirstpacket){ 1183 rtpseq = rand(); 1184 rtptime = rand(); 1185 rtpssrc = rand(); 1186 last = now; 1187 isfirstpacket = 0; 1188 } 1189 else 1190 { 1191 ++rtpseq; 1192 sendtimediff = (((now.tv_sec - last.tv_sec)*1000000) 1193 + (now.tv_usec - last.tv_usec)); 1194 rtptime += sendtimediff/TIME_RESOLUTION; 1195 } 1196 rtpbuffer[0] = (RTP_VERSION<<6); 1197 /* padding, extension, csrc are empty */ 1198 rtpbuffer[1] = 96; 1199 /* marker is empty */ 1200 rtpbuffer[2] = rtpseq>>8; 1201 rtpbuffer[3] = rtpseq; 1202 rtpbuffer[4] = rtptime>>24; 1203 rtpbuffer[5] = rtptime>>16; 1204 rtpbuffer[6] = rtptime>>8; 1205 rtpbuffer[7] = rtptime; 1206 rtpbuffer[8] = rtpssrc>>24; 1207 rtpbuffer[9] = rtpssrc>>16; 1208 rtpbuffer[10] = rtpssrc>>8; 1209 rtpbuffer[11] = rtpssrc; 1210 for(j=0; j<nBufferBytes; j++) {rtpbuffer[12+j] = buffer[j];} 1211 last.tv_sec = now.tv_sec; 1212 last.tv_usec = now.tv_usec; 1213 1214 if ((i = sendto(sock, rtpbuffer, 12 + nBufferBytes, 0, pcasterRTP, 1215 length)) != (nBufferBytes + 12)) 1216 { 1217 if(i < 0) 1218 { 1219 if(errno != EAGAIN) 1220 { 1221 perror("WARNING: could not send data to Destination caster - retry connection"); 1222 close(sock); 1223 sleep(5); 1224 return; 1225 } 1226 } 1227 else if(i) 1228 { 1229 memmove(buffer, buffer+(i-12), (size_t)(nBufferBytes-(i-12))); 1230 nBufferBytes -= i-12; 1231 } 1232 } 1233 else 1234 { 1235 nBufferBytes = 0; 1236 } 1237 } 1238 } 1239 return; 740 1240 } 741 1241 742 /* 1242 1243 /******************************************************************** 743 1244 * openserial 744 1245 * … … 758 1259 * Remarks: 759 1260 * 760 * /1261 ********************************************************************/ 761 1262 762 1263 static int openserial(const char * tty, int blocksz, int baud) … … 789 1290 790 1291 #if (B4800 != 4800) 791 /* 792 * Not every system has speed settings equal to absolute speed value. 793 */ 1292 /* Not every system has speed settings equal to absolute speed value. */ 794 1293 795 1294 switch (baud) … … 855 1354 if(fcntl(fd, F_SETFL, 0) == -1) 856 1355 { 857 perror("WARNING: setting blocking mode failed");1356 perror("WARNING: setting blocking inputmode failed"); 858 1357 } 859 1358 return (fd); 860 } 861 862 /* 863 * usage 864 * 865 * Send a usage message to standard error and quit the program. 866 * 867 * Parameters: 868 * None. 869 * 870 * Return Value: 871 * The function does not return a value. 872 * 873 * Remarks: 874 * 875 */ 876 1359 } /* openserial */ 1360 1361 /******************************************************************** 1362 * usage 1363 * 1364 * Send a usage message to standard error and quit the program. 1365 * 1366 * Parameters: 1367 * None. 1368 * 1369 * Return Value: 1370 * The function does not return a value. 1371 * 1372 * Remarks: 1373 * 1374 *********************************************************************/ 877 1375 static 878 1376 #ifdef __GNUC__ … … 881 1379 void usage(int rc, char *name) 882 1380 { 883 fprintf(stderr, "Version %s (%s) GPL" COMPILEDATE "\nUsage:\n%s [OPTIONS] ",1381 fprintf(stderr, "Version %s (%s) GPL" COMPILEDATE "\nUsage:\n%s [OPTIONS]\n", 884 1382 revisionstr, datestr, name); 885 fprintf(stderr, " Options are: [-] \n"); 886 fprintf(stderr, " -a DestinationCaster name or address (default: %s)\n", 887 NTRIP_CASTER); 888 fprintf(stderr, " -p DestinationCaster port (default: %d)\n", NTRIP_PORT); 889 fprintf(stderr, " -m DestinationCaster mountpoint\n"); 890 fprintf(stderr, " -c DestinationCaster password\n"); 891 fprintf(stderr, " -h|? print this help screen\n"); 892 fprintf(stderr, " -M <mode> sets the input mode\n"); 893 fprintf(stderr, " (1=serial, 2=tcpsocket, 3=file, 4=sisnet" 894 ", 5=udpsocket, 6=caster)\n"); 895 fprintf(stderr, " Mode = file:\n"); 896 fprintf(stderr, " -s file, simulate data stream by reading log file\n"); 897 fprintf(stderr, " default/current setting is %s\n", filepath); 898 fprintf(stderr, " Mode = serial:\n"); 899 fprintf(stderr, " -b baud_rate, sets serial input baud rate\n"); 900 fprintf(stderr, " default/current value is %d\n", ttybaud); 901 fprintf(stderr, " -i input_device, sets name of serial input device\n"); 902 fprintf(stderr, " default/current value is %s\n", ttyport); 903 fprintf(stderr, " (normally a symbolic link to /dev/tty\?\?)\n"); 904 fprintf(stderr, " Mode = tcpsocket or udpsocket:\n"); 905 fprintf(stderr, " -P receiver port (default: %d)\n", SERV_TCP_PORT); 906 fprintf(stderr, " -H hostname of TCP server (default: %s)\n", 907 SERV_HOST_ADDR); 908 fprintf(stderr, " -f initfile send to server\n"); 909 fprintf(stderr, " -x receiver id\n"); 910 fprintf(stderr, " -y receiver password\n"); 911 fprintf(stderr, " -B bindmode: bind to incoming UDP stream\n"); 912 fprintf(stderr, " Mode = sisnet:\n"); 913 fprintf(stderr, " -P receiver port (default: %d)\n", SISNET_PORT); 914 fprintf(stderr, " -H hostname of TCP server (default: %s)\n", 915 SISNET_SERVER); 916 fprintf(stderr, " -u username\n"); 917 fprintf(stderr, " -l password\n"); 918 fprintf(stderr, " -V version [2.1, 3.0 or 3.1] (default: 3.1)\n"); 919 fprintf(stderr, " Mode = caster:\n"); 920 fprintf(stderr, " -P SourceCaster port (default: %d)\n", NTRIP_PORT); 921 fprintf(stderr, " -H SourceCaster hostname (default: %s)\n", 922 NTRIP_CASTER); 923 fprintf(stderr, " -D SourceCaster mountpoint\n"); 924 fprintf(stderr, " -U SourceCaster mountpoint username\n"); 925 fprintf(stderr, " -W SourceCaster mountpoint password\n"); 926 fprintf(stderr, "\n"); 1383 fprintf(stderr, "PURPOSE\n"); 1384 fprintf(stderr, " The purpose of this program is to pick up a GNSS data stream (Input, Source)\n"); 1385 fprintf(stderr, " from either\n\n"); 1386 fprintf(stderr, " 1. a Serial port, or\n"); 1387 fprintf(stderr, " 2. an IP server, or\n"); 1388 fprintf(stderr, " 3. a File, or\n"); 1389 fprintf(stderr, " 4. a SISNeT Data Server, or\n"); 1390 fprintf(stderr, " 5. a UDP server, or\n"); 1391 fprintf(stderr, " 6. an NTRIP Version 1.0 Caster\n\n"); 1392 fprintf(stderr, " and forward that incoming stream (Output, Destination) to either\n\n"); 1393 fprintf(stderr, " - an NTRIP Version 1.0 Caster, or\n"); 1394 fprintf(stderr, " - an NTRIP Version 2.0 Caster via TCP/IP or RTSP/RTP.\n\n\n"); 1395 fprintf(stderr, "OPTIONS\n"); 1396 fprintf(stderr, " -h|? print this help screen\n\n"); 1397 fprintf(stderr, " -E <ProxyHost> Proxy server host name or address, required i.e. when\n"); 1398 fprintf(stderr, " running the program in a proxy server protected LAN,\n"); 1399 fprintf(stderr, " optional\n"); 1400 fprintf(stderr, " -F <ProxyPort> Proxy server IP port, required i.e. when running\n"); 1401 fprintf(stderr, " the program in a proxy server protected LAN, optional\n\n"); 1402 fprintf(stderr, " -M <InputMode> Sets the input mode (1 = Serial Port, 2 = IP server,\n"); 1403 fprintf(stderr, " 3 = File, 4 = SISNeT Data Server, 5 = UDP server, 6 = NTRIP Caster),\n"); 1404 fprintf(stderr, " mandatory\n\n"); 1405 fprintf(stderr, " <InputMode> = 1 (Serial Port):\n"); 1406 fprintf(stderr, " -i <Device> Serial input device, default: /dev/gps, mandatory if\n"); 1407 fprintf(stderr, " <InputMode>=1\n"); 1408 fprintf(stderr, " -b <BaudRate> Serial input baud rate, default: 19200 bps, mandatory\n"); 1409 fprintf(stderr, " if <InputMode>=1\n\n"); 1410 fprintf(stderr, " <InputMode> = 2|5 (IP port | UDP port):\n"); 1411 fprintf(stderr, " -H <ServerHost> Input host name or address, default: 127.0.0.1,\n"); 1412 fprintf(stderr, " mandatory if <InputMode> = 2|5\n"); 1413 fprintf(stderr, " -P <ServerPort> Input port, default: 1025, mandatory if <InputMode>= 2|5\n"); 1414 fprintf(stderr, " -f <ServerFile> Name of initialization file to be send to server,\n"); 1415 fprintf(stderr, " optional\n"); 1416 fprintf(stderr, " -x <ServerUser> User ID to access incoming stream, optional\n"); 1417 fprintf(stderr, " -y <ServerPass> Password, to access incoming stream, optional\n"); 1418 fprintf(stderr, " -B Bind to incoming UDP stream, optional for <InputMode> = 5\n\n"); 1419 fprintf(stderr, " <InputMode> = 3 (File):\n"); 1420 fprintf(stderr, " -s <File> File name to simulate stream by reading data from (log)\n"); 1421 fprintf(stderr, " file, default is /dev/stdin, mandatory for <InputMode> = 3\n\n"); 1422 fprintf(stderr, " <InputMode> = 4 (SISNeT Data Server):\n"); 1423 fprintf(stderr, " -H <SisnetHost> SISNeT Data Server name or address,\n"); 1424 fprintf(stderr, " default: 131.176.49.142, mandatory if <InputMode> = 4\n"); 1425 fprintf(stderr, " -P <SisnetPort> SISNeT Data Server port, default: 7777, mandatory if\n"); 1426 fprintf(stderr, " <InputMode> = 4\n"); 1427 fprintf(stderr, " -u <SisnetUser> SISNeT Data Server user ID, mandatory if <InputMode> = 4\n"); 1428 fprintf(stderr, " -l <SisnetPass> SISNeT Data Server password, mandatory if <InputMode> = 4\n"); 1429 fprintf(stderr, " -V <SisnetVers> SISNeT Data Server Version number, options are 2.1, 3.0\n"); 1430 fprintf(stderr, " or 3.1, default: 3.1, mandatory if <InputMode> = 4\n\n"); 1431 fprintf(stderr, " <InputMode> = 6 (NTRIP Version 1.0 Caster):\n"); 1432 fprintf(stderr, " -H <SourceHost> Source caster name or address, default: 127.0.0.1,\n"); 1433 fprintf(stderr, " mandatory if <InputMode> = 6\n"); 1434 fprintf(stderr, " -P <SourcePort> Source caster port, default: 2101, mandatory if\n"); 1435 fprintf(stderr, " <InputMode> = 6\n"); 1436 fprintf(stderr, " -D <SourceMount> Source caster mountpoint for stream input, mandatory if\n"); 1437 fprintf(stderr, " <InputMode> = 6\n"); 1438 fprintf(stderr, " -U <SourceUser> Source caster user Id for input stream access, mandatory\n"); 1439 fprintf(stderr, " for protected streams if <InputMode> = 6\n"); 1440 fprintf(stderr, " -W <SourcePass> Source caster password for input stream access, mandatory\n"); 1441 fprintf(stderr, " for protected streams if <InputMode> = 6\n\n"); 1442 fprintf(stderr, " -O <OutputMode> Sets the output mode for communatation with the destination\n"); 1443 fprintf(stderr, " caster (r = NTRIP Version 2.0 Caster in RTSP/RTP mode, t = Ntrip Version 2.0\n"); 1444 fprintf(stderr, " Caster in TCP/IP mode, f = NTRIP Version 1.0 Caster)\n\n"); 1445 fprintf(stderr, " Defaults to NTRIP1.0, but wil change to 2.0 in future versions\n"); 1446 fprintf(stderr, " Note that the program automatically falls back from mode r to mode t and\n"); 1447 fprintf(stderr, " further to mode f if necessary.\n\n"); 1448 fprintf(stderr, " -a <DestHost> Destination caster name or address, default: 127.0.0.1,\n"); 1449 fprintf(stderr, " mandatory\n"); 1450 fprintf(stderr, " -p <DestPort> Destination caster port, default: 2101, mandatory\n"); 1451 fprintf(stderr, " -m <DestMount> Destination caster mountpoint for stream upload,\n"); 1452 fprintf(stderr, " mandatory\n"); 1453 fprintf(stderr, " -n <DestUser> Destination caster user ID for stream upload to\n"); 1454 fprintf(stderr, " mountpoint, only for NTRIP Version 2.0 destination\n"); 1455 fprintf(stderr, " casters, mandatory\n"); 1456 fprintf(stderr, " -c <DestPass> Destination caster password for stream upload to\n"); 1457 fprintf(stderr, " mountpoint, mandatory\n"); 1458 fprintf(stderr, " -N <STR-record> Sourcetable STR-record\n"); 1459 fprintf(stderr, " optional for Ntrip Version 2.0 in RTSP/RTP and TCP/IP mode\n\n"); 927 1460 exit(rc); 928 } 929 930 static const char encodingTable [64] = { 1461 } /* usage */ 1462 1463 1464 /********************************************************************/ 1465 /* signal handling */ 1466 /********************************************************************/ 1467 #ifdef __GNUC__ 1468 static void handle_sigint(int sig __attribute__((__unused__))) 1469 #else /* __GNUC__ */ 1470 static void handle_sigint(int sig) 1471 #endif /* __GNUC__ */ 1472 {sigint_received = 1;} 1473 1474 static void setup_signal_handler(int sig, void (*handler)(int)) 1475 { 1476 #if _POSIX_VERSION > 198800L 1477 struct sigaction action; 1478 1479 action.sa_handler = handler; 1480 sigemptyset(&(action.sa_mask)); 1481 sigaddset(&(action.sa_mask), sig); 1482 action.sa_flags = 0; 1483 sigaction(sig, &action, 0); 1484 #else 1485 signal(sig, handler); 1486 #endif 1487 return; 1488 } /* setupsignal_handler */ 1489 1490 static int signal_was_caught(void) 1491 { 1492 fflush(stdout); 1493 if(sigint_received) 1494 fprintf(stderr, "\nSIGINT received: "); 1495 1496 return (sigint_received); 1497 } /* signal_was_caught */ 1498 1499 /******************************************************************** 1500 * base64-encoding * 1501 *******************************************************************/ 1502 static const char encodingTable [64] = 1503 { 931 1504 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', 932 1505 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f', … … 975 1548 *out = 0; 976 1549 return bytes; 977 } 1550 }/* base64 Encoding */ 1551 1552 1553 /******************************************************************** 1554 * send message to caster * 1555 *********************************************************************/ 1556 static int send_to_caster(char *input, int socket, int input_size) 1557 { 1558 int send_error = 1; 1559 1560 if((send(socket, input, (size_t)input_size, 0)) != input_size) 1561 { 1562 fprintf(stderr, "ERROR: could not send full header to Destination caster\n"); 1563 send_error = 0; 1564 }else{ 1565 fprintf(stderr, "\nDestination caster request:\n"); 1566 fprintf(stderr, "%s", input); 1567 } 1568 return send_error; 1569 }/* send_to_caster */ 1570 1571 1572 /******************************************************************** 1573 * close session * 1574 *********************************************************************/ 1575 static void close_session(int sock_udp, int sock_tcp, 1576 const char *caster_addr, const char *mountpoint, int cseq, 1577 int session, char *rtsp_ext, int in_fd) 1578 { 1579 int size_send_buf; 1580 char send_buf[BUFSZ]; 1581 1582 if(in_fd) 1583 { 1584 if(close(in_fd)==-1) 1585 { 1586 perror("ERROR: close input device "); 1587 exit(0); 1588 } 1589 else 1590 { 1591 fprintf(stderr, "\nclose input device: successful\n"); 1592 } 1593 } 1594 1595 if(sock_udp != 0) 1596 { 1597 if(cseq == 2) 1598 { 1599 size_send_buf = snprintf(send_buf, sizeof(send_buf), 1600 "TEARDOWN rtsp://%s%s/%s RTSP/1.0\r\n" 1601 "CSeq: 2\r\n" 1602 "Session: %d\r\n" 1603 "\r\n", 1604 caster_addr, rtsp_ext, mountpoint, session); 1605 if((size_send_buf >= (int)sizeof(send_buf)) || (size_send_buf < 0)) 1606 { 1607 fprintf(stderr, "ERROR: Destination caster request to long\n"); 1608 exit(0); 1609 } 1610 send_to_caster(send_buf, sock_tcp, size_send_buf); strcpy(send_buf,""); 1611 size_send_buf = recv(sock_tcp, send_buf, sizeof(send_buf), 0); 1612 send_buf[size_send_buf] = '\0'; 1613 fprintf(stderr, "Destination caster response:\n%s", send_buf); 1614 } 1615 if(close(sock_udp)==-1) 1616 { 1617 perror("ERROR: close udp socket"); 1618 exit(0); 1619 } 1620 else 1621 { 1622 fprintf(stderr, "close udp socket: successful\n"); 1623 } 1624 } 1625 1626 if(close(sock_tcp)==-1) 1627 { 1628 perror("ERROR: close tcp socket"); 1629 exit(0); 1630 } 1631 else 1632 { 1633 fprintf(stderr, "close tcp socket: successful\n\n"); 1634 } 1635 } /* close_session */
Note:
See TracChangeset
for help on using the changeset viewer.