Changeset 9401 in ntrip
- Timestamp:
- Apr 12, 2021, 3:50:38 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/ntripserver/ntripserver.c
r9109 r9401 39 39 /* SVN revision and version */ 40 40 static char revisionstr[] = "$Revision$"; 41 static char datestr[] 41 static char datestr[] = "$Date$"; 42 42 43 43 #include <ctype.h> … … 64 64 typedef u_short uint16_t; 65 65 #else 66 67 68 69 70 71 72 73 74 66 typedef int sockettype; 67 #include <arpa/inet.h> 68 #include <sys/socket.h> 69 #include <netinet/in.h> 70 #include <netdb.h> 71 #include <sys/termios.h> 72 #define closesocket(sock) close(sock) 73 #define INVALID_HANDLE_VALUE -1 74 #define INVALID_SOCKET -1 75 75 #endif 76 76 … … 88 88 #endif 89 89 90 enum MODE { SERIAL = 1, TCPSOCKET = 2, INFILE = 3, SISNET = 4, UDPSOCKET = 5, 91 CASTER = 6, LAST }; 92 93 enum OUTMODE { HTTP = 1, RTSP = 2, NTRIP1 = 3, UDP = 4, END }; 90 enum MODE { 91 SERIAL = 1, 92 TCPSOCKET = 2, 93 INFILE = 3, 94 SISNET = 4, 95 UDPSOCKET = 5, 96 NTRIP1_IN = 6, 97 NTRIP2_HTTP_IN = 7, // HTTP only 98 LAST 99 }; 100 101 enum OUTMODE { 102 HTTP = 1, 103 RTSP = 2, 104 NTRIP1 = 3, 105 UDP = 4, 106 TDC = 5, 107 END 108 }; 94 109 95 110 #define AGENTSTRING "NTRIP NtripServerPOSIX" … … 105 120 #define NTRIP_PORT 2101 106 121 122 #define DABPLUS_SERVER "62.225.182.198" 123 #define DABPLUS_PORT 10000 124 107 125 #define SISNET_SERVER "131.176.49.142" 108 126 #define SISNET_PORT 7777 … … 111 129 #define TIME_RESOLUTION 125 112 130 113 static int ttybaud 131 static int ttybaud = 19200; 114 132 #ifndef WINDOWSVERSION 115 static const char *ttyport 133 static const char *ttyport = "/dev/gps"; 116 134 #else 117 static const char *ttyport= "COM1";118 #endif 119 static const char *filepath 120 static enum MODE inputmode 121 static int sisnet 122 static int gps_file 123 static sockettype gps_socket 124 static sockettype socket_tcp 125 static sockettype socket_udp 135 static const char *ttyport = "COM1"; 136 #endif 137 static const char *filepath = "/dev/stdin"; 138 static enum MODE inputmode = INFILE; 139 static int sisnet = 31; 140 static int gps_file = -1; 141 static sockettype gps_socket = INVALID_SOCKET; 142 static sockettype socket_tcp = INVALID_SOCKET; 143 static sockettype socket_udp = INVALID_SOCKET; 126 144 #ifndef WINDOWSVERSION 127 static int gps_serial 128 static int sigpipe_received 145 static int gps_serial = INVALID_HANDLE_VALUE; 146 static int sigpipe_received = 0; 129 147 #else 130 HANDLE gps_serial= INVALID_HANDLE_VALUE;131 #endif 132 static int sigalarm_received 133 static int sigint_received 134 static int reconnect_sec 135 static const char * 148 HANDLE gps_serial = INVALID_HANDLE_VALUE; 149 #endif 150 static int sigalarm_received = 0; 151 static int sigint_received = 0; 152 static int reconnect_sec = 1; 153 static const char *casterouthost = NTRIP_CASTER; 136 154 static char rtsp_extension[SZ] = ""; 137 static const char * 138 static int udp_cseq 155 static const char *mountpoint = NULL; 156 static int udp_cseq = 1; 139 157 static int udp_tim, udp_seq, udp_init; 140 158 141 159 /* Forward references */ 142 160 static void send_receive_loop(sockettype sock, int outmode, 143 struct sockaddr * pcasterRTP, socklen_t length, unsigned int rtpssrc); 144 static void usage(int, char *); 145 static int encode(char *buf, int size, const char *user, const char *pwd); 146 static int send_to_caster(char *input, sockettype socket, int input_size); 161 struct sockaddr *pcasterRTP, socklen_t length, unsigned int rtpssrc, 162 int chnunkymode); 163 static void usage(int, char*); 164 static int encode(char *buf, int size, const char *user, const char *pwd); 165 static int send_to_caster(char *input, sockettype socket, int input_size); 147 166 static void close_session(const char *caster_addr, const char *mountpoint, 148 int session, char *rtsp_ext, int fallback);149 static int 167 int session, char *rtsp_ext, int fallback); 168 static int reconnect(int rec_sec, int rec_sec_max); 150 169 static void handle_sigint(int sig); 151 170 static void setup_signal_handler(int sig, void (*handler)(int)); 152 171 #ifndef WINDOWSVERSION 153 static int openserial(const char *tty, int blocksz, int baud);172 static int openserial(const char *tty, int blocksz, int baud); 154 173 static void handle_sigpipe(int sig); 155 174 static void handle_alarm(int sig); 156 175 #else 157 static HANDLE openserial(const char * tty, int baud); 158 #endif 159 176 static HANDLE openserial(const char * tty, int baud); 177 #endif 160 178 161 179 /* 162 * main163 *164 * Main entry point for the program. Processes command-line arguments and165 * prepares for action.166 *167 * Parameters:168 * argc : integer : Number of command-line arguments.169 * argv : array of char : Command-line arguments as an array of170 * zero-terminated pointers to strings.171 *172 * Return Value:173 * The function does not return a value (although its return type is int).174 *175 * Remarks:176 *177 */178 int main(int argc, char **argv) 179 { 180 int c;181 int size = 2048; /* for setting send buffer size */182 struct sockaddr_in caster;183 const char * proxyhost = "";184 unsigned int proxyport = 0; 180 * main 181 * 182 * Main entry point for the program. Processes command-line arguments and 183 * prepares for action. 184 * 185 * Parameters: 186 * argc : integer : Number of command-line arguments. 187 * argv : array of char : Command-line arguments as an array of 188 * zero-terminated pointers to strings. 189 * 190 * Return Value: 191 * The function does not return a value (although its return type is int). 192 * 193 * Remarks: 194 * 195 */ 196 int main(int argc, char **argv) { 197 int c; 198 int size = 2048; /* for setting send buffer size */ 199 struct sockaddr_in caster; 200 const char *proxyhost = ""; 201 unsigned int proxyport = 0; 202 185 203 /*** INPUT ***/ 186 const char * 187 unsigned int 188 const char * 189 unsigned int 190 191 char 192 193 struct hostent * 194 195 const char * 196 const char * 197 198 const char * 199 const char * 200 const char * 201 202 const char * recvrid= 0;203 const char * 204 205 const char * 206 207 int 204 const char *casterinhost = 0; 205 unsigned int casterinport = 0; 206 const char *inhost = 0; 207 unsigned int inport = 0; 208 int chunkymode = 0; 209 char get_extension[SZ] = ""; 210 211 struct hostent *he; 212 213 const char *sisnetpassword = ""; 214 const char *sisnetuser = ""; 215 216 const char *stream_name = 0; 217 const char *stream_user = 0; 218 const char *stream_password = 0; 219 220 const char *recvrid = 0; 221 const char *recvrpwd = 0; 222 223 const char *initfile = NULL; 224 225 int bindmode = 0; 208 226 209 227 /*** OUTPUT ***/ 210 unsigned int 211 const char * 212 unsigned int 213 char 214 215 const char * 216 217 const char * 218 const char * 219 220 int 228 unsigned int casteroutport = NTRIP_PORT; 229 const char *outhost = 0; 230 unsigned int outport = 0; 231 char post_extension[SZ] = ""; 232 233 const char *ntrip_str = ""; 234 235 const char *user = ""; 236 const char *password = ""; 237 238 int outputmode = NTRIP1; 221 239 222 240 struct sockaddr_in casterRTP; 223 241 struct sockaddr_in local; 224 int 225 int 226 unsigned int 227 socklen_t 228 int 229 230 char 231 char 232 int 233 char * 234 char * 235 char * 236 237 int 242 int client_port = 0; 243 int server_port = 0; 244 unsigned int session = 0; 245 socklen_t len = 0; 246 int i = 0; 247 248 char szSendBuffer[BUFSZ]; 249 char authorization[SZ]; 250 int nBufferBytes = 0; 251 char *dlim = " \r\n="; 252 char *token; 253 char *tok_buf[BUFSZ]; 254 255 int reconnect_sec_max = 0; 238 256 239 257 setbuf(stdout, 0); … … 245 263 int i = 2; 246 264 strcpy(revisionstr, "1."); 247 for (a = revisionstr+11; *a && *a != ' '; ++a)265 for (a = revisionstr + 11; *a && *a != ' '; ++a) 248 266 revisionstr[i++] = *a; 249 267 revisionstr[i] = 0; 250 268 i = 0; 251 for (a = datestr+7; *a && *a != ' '; ++a)269 for (a = datestr + 7; *a && *a != ' '; ++a) 252 270 datestr[i++] = *a; 253 271 datestr[i] = 0; … … 273 291 274 292 /* get and check program arguments */ 275 if(argc <= 1) 276 { 293 if (argc <= 1) { 277 294 usage(2, argv[0]); 278 295 exit(1); 279 296 } 280 while((c = getopt(argc, argv, 281 "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) 282 { 283 switch (c) 284 { 285 case 'M': /*** InputMode ***/ 286 if(!strcmp(optarg, "serial")) inputmode = SERIAL; 287 else if(!strcmp(optarg, "tcpsocket")) inputmode = TCPSOCKET; 288 else if(!strcmp(optarg, "file")) inputmode = INFILE; 289 else if(!strcmp(optarg, "sisnet")) inputmode = SISNET; 290 else if(!strcmp(optarg, "udpsocket")) inputmode = UDPSOCKET; 291 else if(!strcmp(optarg, "caster")) inputmode = CASTER; 292 else inputmode = atoi(optarg); 293 if((inputmode == 0) || (inputmode >= LAST)) 294 { 295 fprintf(stderr, "ERROR: can't convert <%s> to a valid InputMode\n", 296 optarg); 297 usage(-1, argv[0]); 298 } 299 break; 300 case 'i': /* serial input device */ 301 ttyport = optarg; 302 break; 303 case 'B': /* bind to incoming UDP stream */ 304 bindmode = 1; 305 break; 306 case 'V': /* Sisnet data server version number */ 307 if(!strcmp("3.0", optarg)) sisnet = 30; 308 else if(!strcmp("3.1", optarg)) sisnet = 31; 309 else if(!strcmp("2.1", optarg)) sisnet = 21; 310 else 311 { 312 fprintf(stderr, "ERROR: unknown SISNeT version <%s>\n", optarg); 313 usage(-2, argv[0]); 314 } 315 break; 316 case 'b': /* serial input baud rate */ 317 ttybaud = atoi(optarg); 318 if(ttybaud <= 1) 319 { 320 fprintf(stderr, "ERROR: can't convert <%s> to valid serial baud rate\n", 321 optarg); 322 usage(1, argv[0]); 323 } 324 break; 325 case 'a': /* Destination caster address */ 326 casterouthost = optarg; 327 break; 328 case 'p': /* Destination caster port */ 329 casteroutport = atoi(optarg); 330 if(casteroutport <= 1 || casteroutport > 65535) 331 { 332 fprintf(stderr, 333 "ERROR: can't convert <%s> to a valid HTTP server port\n", optarg); 334 usage(1, argv[0]); 335 } 336 break; 337 case 'm': /* Destination caster mountpoint for stream upload */ 338 mountpoint = optarg; 339 break; 340 case 's': /* File name for input data simulation from file */ 341 filepath = optarg; 342 break; 343 case 'f': /* name of an initialization file */ 344 initfile = optarg; 345 break; 346 case 'x': /* user ID to access incoming stream */ 347 recvrid = optarg; 348 break; 349 case 'y': /* password to access incoming stream */ 350 recvrpwd = optarg; 351 break; 352 case 'u': /* Sisnet data server user ID */ 353 sisnetuser = optarg; 354 break; 355 case 'l': /* Sisnet data server password */ 356 sisnetpassword = optarg; 357 break; 358 case 'c': /* DestinationCaster password for stream upload to mountpoint */ 359 password = optarg; 360 break; 361 case 'H': /* Input host address*/ 362 casterinhost = optarg; 363 break; 364 case 'P': /* Input port */ 365 casterinport = atoi(optarg); 366 if(casterinport <= 1 || casterinport > 65535) 367 { 368 fprintf(stderr, "ERROR: can't convert <%s> to a valid port number\n", 369 optarg); 370 usage(1, argv[0]); 371 } 372 break; 373 case 'D': /* Source caster mountpoint for stream input */ 374 stream_name = optarg; 375 break; 376 case 'U': /* Source caster user ID for input stream access */ 377 stream_user = optarg; 378 break; 379 case 'W': /* Source caster password for input stream access */ 380 stream_password = optarg; 381 break; 382 case 'E': /* Proxy Server */ 383 proxyhost = optarg; 384 break; 385 case 'F': /* Proxy port */ 386 proxyport = atoi(optarg); 387 break; 388 case 'R': /* maximum delay between reconnect attempts in seconds */ 389 reconnect_sec_max = atoi(optarg); 390 break; 391 case 'O': /* OutputMode */ 392 outputmode = 0; 393 if (!strcmp(optarg,"n") || !strcmp(optarg,"ntrip1")) 394 outputmode = NTRIP1; 395 else if(!strcmp(optarg,"h") || !strcmp(optarg,"http")) 396 outputmode = HTTP; 397 else if(!strcmp(optarg,"r") || !strcmp(optarg,"rtsp")) 398 outputmode = RTSP; 399 else if(!strcmp(optarg,"u") || !strcmp(optarg,"udp")) 400 outputmode = UDP; 401 else outputmode = atoi(optarg); 402 if((outputmode == 0) || (outputmode >= END)) 403 { 404 fprintf(stderr, "ERROR: can't convert <%s> to a valid OutputMode\n", 405 optarg); 406 usage(-1, argv[0]); 407 } 408 break; 409 case 'n': /* Destination caster user ID for stream upload to mountpoint */ 410 user = optarg; 411 break; 412 case 'N': /* Ntrip-STR, optional for Ntrip Version 2.0 */ 413 ntrip_str = optarg; 414 break; 415 case 'h': /* print help screen */ 416 case '?': 417 usage(0, argv[0]); 418 break; 419 default: 420 usage(2, argv[0]); 421 break; 297 while ((c = getopt(argc, argv, 298 "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) { 299 switch (c) { 300 case 'M': /*** InputMode ***/ 301 if (!strcmp(optarg, "serial")) 302 inputmode = SERIAL; 303 else if (!strcmp(optarg, "tcpsocket")) 304 inputmode = TCPSOCKET; 305 else if (!strcmp(optarg, "file")) 306 inputmode = INFILE; 307 else if (!strcmp(optarg, "sisnet")) 308 inputmode = SISNET; 309 else if (!strcmp(optarg, "udpsocket")) 310 inputmode = UDPSOCKET; 311 else if (!strcmp(optarg, "ntrip1")) 312 inputmode = NTRIP1_IN; 313 else if (!strcmp(optarg, "ntrip2http")) 314 inputmode = NTRIP2_HTTP_IN; 315 else 316 inputmode = atoi(optarg); 317 if ((inputmode == 0) || (inputmode >= LAST)) { 318 fprintf(stderr, "ERROR: can't convert <%s> to a valid InputMode\n", 319 optarg); 320 usage(-1, argv[0]); 321 } 322 break; 323 case 'i': /* serial input device */ 324 ttyport = optarg; 325 break; 326 case 'B': /* bind to incoming UDP stream */ 327 bindmode = 1; 328 break; 329 case 'V': /* Sisnet data server version number */ 330 if (!strcmp("3.0", optarg)) 331 sisnet = 30; 332 else if (!strcmp("3.1", optarg)) 333 sisnet = 31; 334 else if (!strcmp("2.1", optarg)) 335 sisnet = 21; 336 else { 337 fprintf(stderr, "ERROR: unknown SISNeT version <%s>\n", optarg); 338 usage(-2, argv[0]); 339 } 340 break; 341 case 'b': /* serial input baud rate */ 342 ttybaud = atoi(optarg); 343 if (ttybaud <= 1) { 344 fprintf(stderr, 345 "ERROR: can't convert <%s> to valid serial baud rate\n", optarg); 346 usage(1, argv[0]); 347 } 348 break; 349 case 'a': /* Destination caster address */ 350 casterouthost = optarg; 351 break; 352 case 'p': /* Destination caster port */ 353 casteroutport = atoi(optarg); 354 if (casteroutport <= 1 || casteroutport > 65535) { 355 fprintf(stderr, 356 "ERROR: can't convert <%s> to a valid HTTP server port\n", 357 optarg); 358 usage(1, argv[0]); 359 } 360 break; 361 case 'm': /* Destination caster mountpoint for stream upload */ 362 mountpoint = optarg; 363 break; 364 case 's': /* File name for input data simulation from file */ 365 filepath = optarg; 366 break; 367 case 'f': /* name of an initialization file */ 368 initfile = optarg; 369 break; 370 case 'x': /* user ID to access incoming stream */ 371 recvrid = optarg; 372 break; 373 case 'y': /* password to access incoming stream */ 374 recvrpwd = optarg; 375 break; 376 case 'u': /* Sisnet data server user ID */ 377 sisnetuser = optarg; 378 break; 379 case 'l': /* Sisnet data server password */ 380 sisnetpassword = optarg; 381 break; 382 case 'c': /* DestinationCaster password for stream upload to mountpoint */ 383 password = optarg; 384 break; 385 case 'H': /* Input host address*/ 386 casterinhost = optarg; 387 break; 388 case 'P': /* Input port */ 389 casterinport = atoi(optarg); 390 if (casterinport <= 1 || casterinport > 65535) { 391 fprintf(stderr, "ERROR: can't convert <%s> to a valid port number\n", 392 optarg); 393 usage(1, argv[0]); 394 } 395 break; 396 case 'D': /* Source caster mountpoint for stream input */ 397 stream_name = optarg; 398 break; 399 case 'U': /* Source caster user ID for input stream access */ 400 stream_user = optarg; 401 break; 402 case 'W': /* Source caster password for input stream access */ 403 stream_password = optarg; 404 break; 405 case 'E': /* Proxy Server */ 406 proxyhost = optarg; 407 break; 408 case 'F': /* Proxy port */ 409 proxyport = atoi(optarg); 410 break; 411 case 'R': /* maximum delay between reconnect attempts in seconds */ 412 reconnect_sec_max = atoi(optarg); 413 break; 414 case 'O': /* OutputMode */ 415 outputmode = 0; 416 if (!strcmp(optarg, "n") || !strcmp(optarg, "ntrip1")) 417 outputmode = NTRIP1; 418 else if (!strcmp(optarg, "h") || !strcmp(optarg, "http")) 419 outputmode = HTTP; 420 else if (!strcmp(optarg, "r") || !strcmp(optarg, "rtsp")) 421 outputmode = RTSP; 422 else if (!strcmp(optarg, "u") || !strcmp(optarg, "udp")) 423 outputmode = UDP; 424 else if (!strcmp(optarg, "t") || !strcmp(optarg, "tdc")) 425 outputmode = TDC; 426 else 427 outputmode = atoi(optarg); 428 if ((outputmode == 0) || (outputmode >= END)) { 429 fprintf(stderr, "ERROR: can't convert <%s> to a valid OutputMode\n", 430 optarg); 431 usage(-1, argv[0]); 432 } 433 break; 434 case 'n': /* Destination caster user ID for stream upload to mountpoint */ 435 user = optarg; 436 break; 437 case 'N': /* Ntrip-STR, optional for Ntrip Version 2.0 */ 438 ntrip_str = optarg; 439 break; 440 case 'h': /* print help screen */ 441 case '?': 442 usage(0, argv[0]); 443 break; 444 default: 445 usage(2, argv[0]); 446 break; 422 447 } 423 448 } … … 427 452 428 453 /*** argument analysis ***/ 429 if(argc > 0) 430 { 454 if (argc > 0) { 431 455 fprintf(stderr, "ERROR: Extra args on command line: "); 432 for(; argc > 0; argc--) 433 { 456 for (; argc > 0; argc--) { 434 457 fprintf(stderr, " %s", *argv++); 435 458 } 436 459 fprintf(stderr, "\n"); 437 usage(1, argv[0]); /* never returns */ 438 } 439 440 if((reconnect_sec_max > 0) && (reconnect_sec_max < 256)) 441 { 460 usage(1, argv[0]); /* never returns */ 461 } 462 463 if ((reconnect_sec_max > 0) && (reconnect_sec_max < 256)) { 442 464 fprintf(stderr, 443 "WARNING: maximum delay between reconnect attemts changed from %d to 256 seconds\n"444 ,reconnect_sec_max);465 "WARNING: maximum delay between reconnect attempts changed from %d to 256 seconds\n", 466 reconnect_sec_max); 445 467 reconnect_sec_max = 256; 446 468 } 447 469 448 if(!mountpoint) 449 { 470 if (!mountpoint && outputmode != TDC) { 450 471 fprintf(stderr, "ERROR: Missing mountpoint argument for stream upload\n"); 451 472 exit(1); 452 473 } 453 474 454 if(!password[0]) 455 { 456 fprintf(stderr, "WARNING: Missing password argument for stream upload - " 457 "are you really sure?\n"); 458 } 459 else 460 { 475 if (outputmode == TDC) { 476 mountpoint = NULL; 477 if (!strcmp(casterouthost, NTRIP_CASTER)) { 478 casterouthost = DABPLUS_SERVER; 479 } 480 if (casteroutport == NTRIP_PORT) { 481 casteroutport = DABPLUS_PORT; 482 } 483 } 484 485 if (!password[0]) { 486 if (outputmode != TDC) 487 fprintf(stderr, 488 "WARNING: Missing password argument for stream upload - are you really sure?\n"); 489 } else { 461 490 nBufferBytes += encode(authorization, sizeof(authorization), user, 462 password); 463 if(nBufferBytes > (int)sizeof(authorization)) 464 { 491 password); 492 if (nBufferBytes > (int) sizeof(authorization)) { 465 493 fprintf(stderr, "ERROR: user ID and/or password too long: %d (%d)\n" 466 " user ID: %s \npassword: <%s>\n",467 nBufferBytes, (int)sizeof(authorization), user, password);494 " user ID: %s \npassword: <%s>\n", nBufferBytes, 495 (int) sizeof(authorization), user, password); 468 496 exit(1); 469 497 } 470 498 } 471 499 472 if(stream_name && stream_user && !stream_password) 473 { 474 fprintf(stderr, "WARNING: Missing password argument for stream download" 475 " - are you really sure?\n"); 500 if (stream_name && stream_user && !stream_password) { 501 fprintf(stderr, 502 "WARNING: Missing password argument for stream download - are you really sure?\n"); 476 503 } 477 504 478 505 /*** proxy server handling ***/ 479 if(*proxyhost) 480 { 506 if (*proxyhost) { 481 507 outhost = inhost = proxyhost; 482 508 outport = inport = proxyport; 483 i = snprintf(szSendBuffer, sizeof(szSendBuffer),"http://%s:%d", 484 casterouthost, casteroutport); 485 if((i > SZ) || (i < 0)) 486 { 487 fprintf(stderr, "ERROR: Destination caster name/port to long - " 488 "length = %d (max: %d)\n", i, SZ); 509 i = snprintf(szSendBuffer, sizeof(szSendBuffer), "http://%s:%d", casterouthost, casteroutport); 510 if ((i > SZ) || (i < 0)) { 511 fprintf(stderr, 512 "ERROR: Destination caster name/port to long - length = %d (max: %d)\n", 513 i, SZ); 489 514 exit(0); 490 } 491 else 492 { 493 strncpy(post_extension, szSendBuffer, (size_t)i); 515 } else { 516 strncpy(post_extension, szSendBuffer, (size_t) i); 494 517 strcpy(szSendBuffer, ""); 495 i = snprintf(szSendBuffer, sizeof(szSendBuffer), ":%d", casteroutport);518 i = snprintf(szSendBuffer, sizeof(szSendBuffer), ":%d", casteroutport); 496 519 strncpy(rtsp_extension, szSendBuffer, SZ); 497 strcpy(szSendBuffer,""); i = 0; 498 } 499 i = snprintf(szSendBuffer, sizeof(szSendBuffer),"http://%s:%d", casterinhost, casterinport); 500 if((i > SZ) || (i < 0)) 501 { 502 fprintf(stderr,"ERROR: Destination caster name/port to long - length = %d (max: %d)\n", i, SZ); 520 strcpy(szSendBuffer, ""); i = 0; 521 } 522 i = snprintf(szSendBuffer, sizeof(szSendBuffer), "http://%s:%d", casterinhost, casterinport); 523 if ((i > SZ) || (i < 0)) { 524 fprintf(stderr, 525 "ERROR: Destination caster name/port to long - length = %d (max: %d)\n", 526 i, SZ); 503 527 exit(0); 504 } 505 else 506 { 507 strncpy(get_extension, szSendBuffer, (size_t)i); 528 } else { 529 strncpy(get_extension, szSendBuffer, (size_t) i); 508 530 strcpy(szSendBuffer, ""); 509 531 i = 0; 510 }511 }512 else513 {514 out host = casterouthost; outport = casteroutport;515 inhost = casterinhost; inport = casterinport;516 }517 518 while(inputmode != LAST) 519 {532 fprintf(stdout, "%s",get_extension); 533 } 534 } else { 535 outhost = casterouthost; 536 outport = casteroutport; 537 inhost = casterinhost; 538 inport = casterinport; 539 } 540 541 while (inputmode != LAST) { 520 542 int input_init = 1; 521 if(sigint_received) break; 543 if (sigint_received) 544 break; 522 545 /*** InputMode handling ***/ 523 switch(inputmode) 524 { 525 case INFILE: 526 { 527 if((gps_file = open(filepath, O_RDONLY)) < 0) 528 { 546 switch (inputmode) { 547 case INFILE: { 548 if ((gps_file = open(filepath, O_RDONLY)) < 0) { 529 549 perror("ERROR: opening input file"); 530 550 exit(1); … … 532 552 #ifndef WINDOWSVERSION 533 553 /* set blocking inputmode in case it was not set 534 554 (seems to be sometimes for fifo's) */ 535 555 fcntl(gps_file, F_SETFL, 0); 536 556 #endif 537 557 printf("file input: file = %s\n", filepath); 538 558 } 539 break; 540 case SERIAL: /* open serial port */ 541 { 559 break; 560 case SERIAL: /* open serial port */ { 542 561 #ifndef WINDOWSVERSION 543 562 gps_serial = openserial(ttyport, 1, ttybaud); … … 545 564 gps_serial = openserial(ttyport, ttybaud); 546 565 #endif 547 if(gps_serial == INVALID_HANDLE_VALUE) exit(1); 566 if (gps_serial == INVALID_HANDLE_VALUE) 567 exit(1); 548 568 printf("serial input: device = %s, speed = %d\n", ttyport, ttybaud); 549 569 550 if(initfile) 551 { 570 if (initfile) { 552 571 char buffer[1024]; 553 572 FILE *fh; 554 573 int i; 555 574 556 if((fh = fopen(initfile, "r"))) 557 { 558 while((i = fread(buffer, 1, sizeof(buffer), fh)) > 0) 559 { 575 if ((fh = fopen(initfile, "r"))) { 576 while ((i = fread(buffer, 1, sizeof(buffer), fh)) > 0) { 560 577 #ifndef WINDOWSVERSION 561 if((write(gps_serial, buffer, i)) != i) 562 { 578 if ((write(gps_serial, buffer, i)) != i) { 563 579 perror("WARNING: sending init file"); 564 580 input_init = 0; … … 567 583 #else 568 584 DWORD nWrite = -1; 569 if(!WriteFile(gps_serial, buffer, sizeof(buffer), &nWrite, NULL)) 570 { 585 if(!WriteFile(gps_serial, buffer, sizeof(buffer), &nWrite, NULL)) { 571 586 fprintf(stderr,"ERROR: sending init file \n"); 572 587 input_init = 0; … … 576 591 #endif 577 592 } 578 if(i < 0) 579 { 593 if (i < 0) { 580 594 perror("ERROR: reading init file"); 581 595 reconnect_sec_max = 0; … … 584 598 } 585 599 fclose(fh); 586 } 587 else 588 { 600 } else { 589 601 fprintf(stderr, "ERROR: can't read init file <%s>\n", initfile); 590 602 reconnect_sec_max = 0; … … 594 606 } 595 607 } 596 break; 597 case TCPSOCKET: case UDPSOCKET: case SISNET: case CASTER: 598 { 599 if(inputmode == SISNET) 600 { 601 if(!inhost) inhost = SISNET_SERVER; 602 if(!inport) inport = SISNET_PORT; 603 } 604 else if(inputmode == CASTER) 605 { 606 if(!inport) inport = NTRIP_PORT; 607 if(!inhost) inhost = NTRIP_CASTER; 608 } 609 else if((inputmode == TCPSOCKET) || (inputmode == UDPSOCKET)) 610 { 611 if(!inport) inport = SERV_TCP_PORT; 612 if(!inhost) inhost = SERV_HOST_ADDR; 613 } 614 615 if(!(he = gethostbyname(inhost))) 616 { 608 break; 609 case TCPSOCKET: 610 case UDPSOCKET: 611 case SISNET: 612 case NTRIP1_IN: 613 case NTRIP2_HTTP_IN: { 614 if (inputmode == SISNET) { 615 if (!inhost) 616 inhost = SISNET_SERVER; 617 if (!inport) 618 inport = SISNET_PORT; 619 } else if (inputmode == NTRIP1_IN || inputmode == NTRIP2_HTTP_IN) { 620 if (!inport) 621 inport = NTRIP_PORT; 622 if (!inhost) 623 inhost = NTRIP_CASTER; 624 } else if ((inputmode == TCPSOCKET) || (inputmode == UDPSOCKET)) { 625 if (!inport) 626 inport = SERV_TCP_PORT; 627 if (!inhost) 628 inhost = SERV_HOST_ADDR; 629 } 630 631 if (!(he = gethostbyname(inhost))) { 617 632 fprintf(stderr, "ERROR: Input host <%s> unknown\n", inhost); 618 633 usage(-2, argv[0]); 619 634 } 620 635 621 if((gps_socket = socket(AF_INET, inputmode == UDPSOCKET 622 ? SOCK_DGRAM : SOCK_STREAM, 0)) == INVALID_SOCKET) 623 { 636 if ((gps_socket = socket(AF_INET, inputmode == UDPSOCKET ? SOCK_DGRAM : SOCK_STREAM, 0)) == INVALID_SOCKET) { 624 637 fprintf(stderr, 625 "ERROR: can't create socket for incoming data stream\n");638 "ERROR: can't create socket for incoming data stream\n"); 626 639 exit(1); 627 640 } 628 641 629 memset((char 630 if (!bindmode)642 memset((char*) &caster, 0x00, sizeof(caster)); 643 if (!bindmode) 631 644 memcpy(&caster.sin_addr, he->h_addr, (size_t)he->h_length); 632 645 caster.sin_family = AF_INET; … … 634 647 635 648 fprintf(stderr, "%s input: host = %s, port = %d, %s%s%s%s%s\n", 636 inputmode == CASTER ? "caster" : inputmode == SISNET ? "sisnet" : 637 inputmode == TCPSOCKET ? "tcp socket" : "udp socket", 638 bindmode ? "127.0.0.1" : inet_ntoa(caster.sin_addr), 639 inport, stream_name ? "stream = " : "", stream_name ? stream_name : "", 640 initfile ? ", initfile = " : "", initfile ? initfile : "", 641 bindmode ? "binding mode" : ""); 642 643 if(bindmode) 644 { 645 if(bind(gps_socket, (struct sockaddr *) &caster, sizeof(caster)) < 0) 646 { 649 inputmode == NTRIP1_IN ? "ntrip1" : 650 inputmode == NTRIP2_HTTP_IN ? "ntrip2" : 651 inputmode == SISNET ? "sisnet" : 652 inputmode == TCPSOCKET ? "tcp socket" : "udp socket", 653 bindmode ? "127.0.0.1" : inet_ntoa(caster.sin_addr), inport, 654 stream_name ? "stream = " : "", stream_name ? stream_name : "", 655 initfile ? ", initfile = " : "", initfile ? initfile : "", 656 bindmode ? "binding mode" : ""); 657 658 if (bindmode) { 659 if (bind(gps_socket, (struct sockaddr*) &caster, sizeof(caster)) 660 < 0) { 647 661 fprintf(stderr, "ERROR: can't bind input to port %d\n", inport); 648 662 reconnect_sec_max = 0; … … 651 665 } 652 666 } /* connect to input-caster or proxy server*/ 653 else if (connect(gps_socket, (struct sockaddr *)&caster, sizeof(caster)) < 0)654 {667 else if (connect(gps_socket, (struct sockaddr*) &caster, sizeof(caster)) 668 < 0) { 655 669 fprintf(stderr, "WARNING: can't connect input to %s at port %d\n", 656 inet_ntoa(caster.sin_addr), inport);670 inet_ntoa(caster.sin_addr), inport); 657 671 input_init = 0; 658 672 break; 659 673 } 660 674 661 if(stream_name) /* input from Ntrip Version 1.0 caster*/ 662 { 663 int init = 0; 664 665 /* set socket buffer size */ 666 setsockopt(gps_socket, SOL_SOCKET, SO_SNDBUF, (const char *) &size, 667 sizeof(const char *)); 668 if(stream_user && stream_password) 669 { 670 /* leave some space for login */ 671 nBufferBytes=snprintf(szSendBuffer, sizeof(szSendBuffer)-40, 672 "GET %s/%s HTTP/1.0\r\n" 673 "User-Agent: %s/%s\r\n" 674 "Connection: close\r\n" 675 "Authorization: Basic ", get_extension, stream_name, 676 AGENTSTRING, revisionstr); 677 /* second check for old glibc */ 678 if(nBufferBytes > (int)sizeof(szSendBuffer)-40 || nBufferBytes < 0) 679 { 680 fprintf(stderr, "ERROR: Source caster request too long\n"); 675 /* input from NTRIP caster */ 676 int init = 0; 677 /* set socket buffer size */ 678 setsockopt(gps_socket, SOL_SOCKET, SO_SNDBUF, (const char*) &size, sizeof(const char*)); 679 /* input from Ntrip caster*/ 680 nBufferBytes=snprintf(szSendBuffer, sizeof(szSendBuffer) - 40,/* leave some space for login */ 681 "GET %s/%s HTTP/1.1\r\n" 682 "Host: %s\r\n" 683 "%s" 684 "User-Agent: %s/%s\r\n" 685 //"%s%s%s" // nmea 686 "Connection: close%s", 687 get_extension, 688 stream_name ? stream_name : "", 689 casterinhost, 690 inputmode == NTRIP1_IN ? "" : "Ntrip-Version: Ntrip/2.0\r\n", 691 AGENTSTRING, revisionstr, 692 //args.nmea ? "Ntrip-GGA: " : "", args.nmea ? args.nmea : "", args.nmea ? "\r\n" : "", // TODO: add argument 693 (*stream_user || *stream_password) ? "\r\nAuthorization: Basic " : ""); 694 /* second check for old glibc */ 695 if (nBufferBytes > (int) sizeof(szSendBuffer) - 40 || nBufferBytes < 0) { 696 fprintf(stderr, "ERROR: Source caster request too long\n"); 697 input_init = 0; 698 reconnect_sec_max = 0; 699 break; 700 } 701 nBufferBytes += encode(szSendBuffer + nBufferBytes, sizeof(szSendBuffer) - nBufferBytes - 4, 702 stream_user, stream_password); 703 if (nBufferBytes > (int) sizeof(szSendBuffer) - 4) { 704 fprintf(stderr, "ERROR: Source caster user ID and/or password too long\n"); 705 input_init = 0; 706 reconnect_sec_max = 0; 707 break; 708 } 709 szSendBuffer[nBufferBytes++] = '\r'; 710 szSendBuffer[nBufferBytes++] = '\n'; 711 szSendBuffer[nBufferBytes++] = '\r'; 712 szSendBuffer[nBufferBytes++] = '\n'; 713 fprintf(stdout, "%s", szSendBuffer); 714 if ((send(gps_socket, szSendBuffer, (size_t) nBufferBytes, 0)) != nBufferBytes) { 715 fprintf(stderr, "WARNING: could not send Source caster request\n"); 716 input_init = 0; 717 break; 718 } 719 nBufferBytes = 0; 720 /* check Source caster's response */ 721 while (!init && nBufferBytes < (int) sizeof(szSendBuffer) && 722 (nBufferBytes += recv(gps_socket, szSendBuffer, sizeof(szSendBuffer) - nBufferBytes, 0)) > 0) { 723 if( nBufferBytes > 17 && !strstr(szSendBuffer, "ICY 200 OK") && /* case 'proxy & ntrip 1.0 caster' */ 724 (!strncmp(szSendBuffer, "HTTP/1.1 200 OK\r\n", 17) || 725 !strncmp(szSendBuffer, "HTTP/1.0 200 OK\r\n", 17)) ) { 726 const char *datacheck = "Content-Type: gnss/data\r\n"; 727 const char *chunkycheck = "Transfer-Encoding: chunked\r\n"; 728 int l = strlen(datacheck)-1; 729 int j=0; 730 for(i = 0; j != l && i < nBufferBytes-l; ++i) { 731 for(j = 0; j < l && szSendBuffer[i+j] == datacheck[j]; ++j) 732 ; 733 } 734 if(i == nBufferBytes-l) { 735 fprintf(stderr, "No 'Content-Type: gnss/data' found\n"); 681 736 input_init = 0; 682 reconnect_sec_max =0; 737 } 738 l = strlen(chunkycheck)-1; 739 j=0; 740 for(i = 0; j != l && i < nBufferBytes-l; ++i) { 741 for(j = 0; j < l && szSendBuffer[i+j] == chunkycheck[j]; ++j) 742 ; 743 } 744 if(i < nBufferBytes-l) 745 chunkymode = 1; 746 init = 1; 747 } 748 else if (strstr(szSendBuffer, "\r\n")) { 749 if (!strstr(szSendBuffer, "ICY 200 OK")) { 750 int k; 751 fprintf(stderr, "ERROR: could not get requested data from Source caster: "); 752 for (k = 0; k < nBufferBytes && szSendBuffer[k] != '\n' && szSendBuffer[k] != '\r'; ++k) { 753 fprintf(stderr, "%c", isprint(szSendBuffer[k]) ? szSendBuffer[k] : '.'); 754 } 755 fprintf(stderr, "\n"); 756 if (!strstr(szSendBuffer, "SOURCETABLE 200 OK")) { 757 reconnect_sec_max = 0; 758 } 759 input_init = 0; 683 760 break; 761 } else {// eventuell auskommentieren! 762 init = 1; 684 763 } 685 nBufferBytes += encode(szSendBuffer+nBufferBytes, 686 sizeof(szSendBuffer)-nBufferBytes-4, stream_user, stream_password); 687 if(nBufferBytes > (int)sizeof(szSendBuffer)-4) 688 { 689 fprintf(stderr, 690 "ERROR: Source caster user ID and/or password too long\n"); 691 input_init = 0; 692 reconnect_sec_max =0; 693 break; 694 } 695 szSendBuffer[nBufferBytes++] = '\r'; 696 szSendBuffer[nBufferBytes++] = '\n'; 697 szSendBuffer[nBufferBytes++] = '\r'; 698 szSendBuffer[nBufferBytes++] = '\n'; 699 } 700 else 701 { 702 nBufferBytes = snprintf(szSendBuffer, sizeof(szSendBuffer), 703 "GET %s/%s HTTP/1.0\r\n" 704 "User-Agent: %s/%s\r\n" 705 "Connection: close\r\n" 706 "\r\n", get_extension, stream_name, AGENTSTRING, revisionstr); 707 } 708 if((send(gps_socket, szSendBuffer, (size_t)nBufferBytes, 0)) 709 != nBufferBytes) 710 { 711 fprintf(stderr, "WARNING: could not send Source caster request\n"); 712 input_init = 0; 713 break; 714 } 715 nBufferBytes = 0; 716 /* check Source caster's response */ 717 while(!init && nBufferBytes < (int)sizeof(szSendBuffer) 718 && (nBufferBytes += recv(gps_socket, szSendBuffer, 719 sizeof(szSendBuffer)-nBufferBytes, 0)) > 0) 720 { 721 if(strstr(szSendBuffer, "\r\n")) 722 { 723 if(!strstr(szSendBuffer, "ICY 200 OK")) 724 { 725 int k; 726 fprintf(stderr, 727 "ERROR: could not get requested data from Source caster: "); 728 for(k = 0; k < nBufferBytes && szSendBuffer[k] != '\n' 729 && szSendBuffer[k] != '\r'; ++k) 730 { 731 fprintf(stderr, "%c", isprint(szSendBuffer[k]) 732 ? szSendBuffer[k] : '.'); 733 } 734 fprintf(stderr, "\n"); 735 if(!strstr(szSendBuffer, "SOURCETABLE 200 OK")) 736 { 737 reconnect_sec_max =0; 738 } 739 input_init = 0; 740 break; 741 } 742 else init = 1; 743 } 744 } 745 } /* end input from Ntrip Version 1.0 caster */ 746 747 if(initfile && inputmode != SISNET) 748 { 764 } 765 766 } 767 /* end input from NTRIP caster */ 768 769 if (initfile && inputmode != SISNET) { 749 770 char buffer[1024]; 750 771 FILE *fh; 751 772 int i; 752 773 753 if((fh = fopen(initfile, "r"))) 754 { 755 while((i = fread(buffer, 1, sizeof(buffer), fh)) > 0) 756 { 757 if((send(gps_socket, buffer, (size_t)i, 0)) != i) 758 { 774 if ((fh = fopen(initfile, "r"))) { 775 while ((i = fread(buffer, 1, sizeof(buffer), fh)) > 0) { 776 if ((send(gps_socket, buffer, (size_t) i, 0)) != i) { 759 777 perror("WARNING: sending init file"); 760 778 input_init = 0; … … 762 780 } 763 781 } 764 if(i < 0) 765 { 782 if (i < 0) { 766 783 perror("ERROR: reading init file"); 767 784 reconnect_sec_max = 0; … … 770 787 } 771 788 fclose(fh); 772 } 773 else 774 { 789 } else { 775 790 fprintf(stderr, "ERROR: can't read init file <%s>\n", initfile); 776 791 reconnect_sec_max = 0; … … 780 795 } 781 796 } 782 if(inputmode == SISNET) 783 { 784 int i, j; 785 char buffer[1024]; 786 787 i = snprintf(buffer, sizeof(buffer), sisnet >= 30 ? "AUTH,%s,%s\r\n" 788 : "AUTH,%s,%s", sisnetuser, sisnetpassword); 789 if((send(gps_socket, buffer, (size_t)i, 0)) != i) 790 { 791 perror("WARNING: sending authentication for SISNeT data server"); 792 input_init = 0; 793 break; 794 } 795 i = sisnet >= 30 ? 7 : 5; 796 if((j = recv(gps_socket, buffer, i, 0)) != i && strncmp("*AUTH", buffer, 5)) 797 { 798 fprintf(stderr, "WARNING: SISNeT connect failed:"); 799 for(i = 0; i < j; ++i) 800 { 801 if(buffer[i] != '\r' && buffer[i] != '\n') 802 { 803 fprintf(stderr, "%c", isprint(buffer[i]) ? buffer[i] : '.'); 804 } 805 } 806 fprintf(stderr, "\n"); 807 input_init = 0; 808 break; 809 } 810 if(sisnet >= 31) 811 { 812 if((send(gps_socket, "START\r\n", 7, 0)) != i) 813 { 814 perror("WARNING: sending Sisnet start command"); 797 if (inputmode == SISNET) { 798 int i, j; 799 char buffer[1024]; 800 801 i = snprintf(buffer, sizeof(buffer), 802 sisnet >= 30 ? "AUTH,%s,%s\r\n" : "AUTH,%s,%s", sisnetuser, 803 sisnetpassword); 804 if ((send(gps_socket, buffer, (size_t) i, 0)) != i) { 805 perror("WARNING: sending authentication for SISNeT data server"); 815 806 input_init = 0; 816 807 break; 817 808 } 818 } 819 } 820 /*** receiver authentication ***/ 821 if (recvrid && recvrpwd && ((inputmode == TCPSOCKET) 822 || (inputmode == UDPSOCKET))) 823 { 824 if (strlen(recvrid) > (BUFSZ-3)) 825 { 826 fprintf(stderr, "ERROR: Receiver ID too long\n"); 827 reconnect_sec_max = 0; 828 input_init = 0; 829 break; 830 } 831 else 832 { 833 fprintf(stderr, "Sending user ID for receiver...\n"); 834 nBufferBytes = recv(gps_socket, szSendBuffer, BUFSZ, 0); 835 strcpy(szSendBuffer, recvrid); 836 strcat(szSendBuffer,"\r\n"); 837 if(send(gps_socket,szSendBuffer, strlen(szSendBuffer), MSG_DONTWAIT) < 0) 838 { 839 perror("WARNING: sending user ID for receiver"); 809 i = sisnet >= 30 ? 7 : 5; 810 if ((j = recv(gps_socket, buffer, i, 0)) != i 811 && strncmp("*AUTH", buffer, 5)) { 812 fprintf(stderr, "WARNING: SISNeT connect failed:"); 813 for (i = 0; i < j; ++i) { 814 if (buffer[i] != '\r' && buffer[i] != '\n') { 815 fprintf(stderr, "%c", isprint(buffer[i]) ? buffer[i] : '.'); 816 } 817 } 818 fprintf(stderr, "\n"); 840 819 input_init = 0; 841 820 break; 842 821 } 843 } 844 845 if (strlen(recvrpwd) > (BUFSZ-3)) 846 { 847 fprintf(stderr, "ERROR: Receiver password too long\n"); 848 reconnect_sec_max = 0; 849 input_init = 0; 850 break; 851 } 852 else 853 { 854 fprintf(stderr, "Sending user password for receiver...\n"); 855 nBufferBytes = recv(gps_socket, szSendBuffer, BUFSZ, 0); 856 strcpy(szSendBuffer, recvrpwd); 857 strcat(szSendBuffer,"\r\n"); 858 if(send(gps_socket, szSendBuffer, strlen(szSendBuffer), MSG_DONTWAIT) < 0) 859 { 860 perror("WARNING: sending user password for receiver"); 822 if (sisnet >= 31) { 823 if ((send(gps_socket, "START\r\n", 7, 0)) != i) { 824 perror("WARNING: sending Sisnet start command"); 825 input_init = 0; 826 break; 827 } 828 } 829 } 830 /*** receiver authentication ***/ 831 if (recvrid && recvrpwd 832 && ((inputmode == TCPSOCKET) || (inputmode == UDPSOCKET))) { 833 if (strlen(recvrid) > (BUFSZ - 3)) { 834 fprintf(stderr, "ERROR: Receiver ID too long\n"); 835 reconnect_sec_max = 0; 861 836 input_init = 0; 862 837 break; 863 } 864 } 865 } 866 break; 867 default: 868 usage(-1, argv[0]); 869 break; 838 } else { 839 fprintf(stderr, "Sending user ID for receiver...\n"); 840 nBufferBytes = recv(gps_socket, szSendBuffer, BUFSZ, 0); 841 strcpy(szSendBuffer, recvrid); 842 strcat(szSendBuffer, "\r\n"); 843 if (send(gps_socket, szSendBuffer, strlen(szSendBuffer), 844 MSG_DONTWAIT) < 0) { 845 perror("WARNING: sending user ID for receiver"); 846 input_init = 0; 847 break; 848 } 849 } 850 851 if (strlen(recvrpwd) > (BUFSZ - 3)) { 852 fprintf(stderr, "ERROR: Receiver password too long\n"); 853 reconnect_sec_max = 0; 854 input_init = 0; 855 break; 856 } else { 857 fprintf(stderr, "Sending user password for receiver...\n"); 858 nBufferBytes = recv(gps_socket, szSendBuffer, BUFSZ, 0); 859 strcpy(szSendBuffer, recvrpwd); 860 strcat(szSendBuffer, "\r\n"); 861 if (send(gps_socket, szSendBuffer, strlen(szSendBuffer), 862 MSG_DONTWAIT) < 0) { 863 perror("WARNING: sending user password for receiver"); 864 input_init = 0; 865 break; 866 } 867 } 868 } 869 break; 870 default: 871 usage(-1, argv[0]); 872 break; 870 873 } 871 874 … … 873 876 int output_init = 1, fallback = 0; 874 877 875 while((input_init) && (output_init)) 876 { 878 while ((input_init) && (output_init)) { 877 879 #ifndef WINDOWSVERSION 878 if((sigalarm_received) || (sigint_received) || (sigpipe_received)) break; 880 if ((sigalarm_received) || (sigint_received) || (sigpipe_received)) 881 break; 879 882 #else 880 883 if((sigalarm_received) || (sigint_received)) break; 881 884 #endif 882 if (!(he = gethostbyname(outhost)))883 {884 fprintf(stderr, "ERROR: Destination caster or proxy host <%s> unknown\n",885 outhost);885 if (!(he = gethostbyname(outhost))) { 886 fprintf(stderr, 887 "ERROR: Destination caster, server or proxy host <%s> unknown\n", 888 outhost); 886 889 close_session(casterouthost, mountpoint, session, rtsp_extension, 0); 887 890 usage(-2, argv[0]); … … 889 892 890 893 /* create socket */ 891 if((socket_tcp = socket(AF_INET, (outputmode == UDP ? SOCK_DGRAM 892 : SOCK_STREAM), 0)) == INVALID_SOCKET) 893 { 894 if ((socket_tcp = socket(AF_INET, (outputmode == UDP ? SOCK_DGRAM : SOCK_STREAM), 0)) == INVALID_SOCKET) { 894 895 perror("ERROR: tcp socket"); 895 896 reconnect_sec_max = 0; … … 897 898 } 898 899 899 memset((char 900 memset((char*) &caster, 0x00, sizeof(caster)); 900 901 memcpy(&caster.sin_addr, he->h_addr, (size_t)he->h_length); 901 902 caster.sin_family = AF_INET; 902 903 caster.sin_port = htons(outport); 903 904 904 /* connect to Destination caster or Proxy server*/905 /* connect to Destination caster, server or proxy host */ 905 906 fprintf(stderr, "caster output: host = %s, port = %d, mountpoint = %s" 906 ", mode = %s\n\n", inet_ntoa(caster.sin_addr), outport, mountpoint, 907 outputmode == NTRIP1 ? "ntrip1" : outputmode == HTTP ? "http" : 908 outputmode == UDP ? "udp" : "rtsp"); 909 910 if(connect(socket_tcp, (struct sockaddr *) &caster, sizeof(caster)) < 0) 911 { 907 ", mode = %s\n\n", inet_ntoa(caster.sin_addr), outport, mountpoint, 908 outputmode == NTRIP1 ? "ntrip1" : outputmode == HTTP ? "http" : 909 outputmode == UDP ? "udp" : "rtsp"); 910 911 if (connect(socket_tcp, (struct sockaddr*) &caster, sizeof(caster)) < 0) { 912 912 fprintf(stderr, "WARNING: can't connect output to %s at port %d\n", 913 inet_ntoa(caster.sin_addr), outport);913 inet_ntoa(caster.sin_addr), outport); 914 914 break; 915 915 } 916 916 917 917 /*** OutputMode handling ***/ 918 switch(outputmode) 919 { 920 case UDP: 918 switch (outputmode) { 919 case UDP: { 920 unsigned int session; 921 char rtpbuf[1526]; 922 int i = 12, j; 923 924 udp_init = time(0); 925 srand(udp_init); 926 session = rand(); 927 udp_tim = rand(); 928 udp_seq = rand(); 929 930 rtpbuf[0] = (2 << 6); 931 /* padding, extension, csrc are empty */ 932 rtpbuf[1] = 97; 933 /* marker is empty */ 934 rtpbuf[2] = (udp_seq >> 8) & 0xFF; 935 rtpbuf[3] = (udp_seq) & 0xFF; 936 rtpbuf[4] = (udp_tim >> 24) & 0xFF; 937 rtpbuf[5] = (udp_tim >> 16) & 0xFF; 938 rtpbuf[6] = (udp_tim >> 8) & 0xFF; 939 rtpbuf[7] = (udp_tim) & 0xFF; 940 /* sequence and timestamp are empty */ 941 rtpbuf[8] = (session >> 24) & 0xFF; 942 rtpbuf[9] = (session >> 16) & 0xFF; 943 rtpbuf[10] = (session >> 8) & 0xFF; 944 rtpbuf[11] = (session) & 0xFF; 945 ++udp_seq; 946 947 j = snprintf(rtpbuf + i, sizeof(rtpbuf) - i - 40, /* leave some space for login */ 948 "POST /%s HTTP/1.1\r\n" 949 "Host: %s\r\n" 950 "Ntrip-Version: Ntrip/2.0\r\n" 951 "User-Agent: %s/%s\r\n" 952 "Authorization: Basic %s%s%s\r\n" 953 "Connection: close\r\n" 954 "Transfer-Encoding: chunked\r\n\r\n", mountpoint, casterouthost, 955 AGENTSTRING, revisionstr, authorization, 956 ntrip_str ? 957 (outputmode == NTRIP1 ? "\r\nSTR: " : "\r\nNtrip-STR: ") : "", 958 ntrip_str); 959 i += j; 960 if (i > (int) sizeof(rtpbuf) - 40 || j < 0) /* second check for old glibc */ 921 961 { 922 unsigned int session; 923 char rtpbuf[1526]; 924 int i=12, j; 925 926 udp_init = time(0); 927 srand(udp_init); 928 session = rand(); 929 udp_tim = rand(); 930 udp_seq = rand(); 931 932 rtpbuf[0] = (2<<6); 933 /* padding, extension, csrc are empty */ 934 rtpbuf[1] = 97; 935 /* marker is empty */ 936 rtpbuf[2] = (udp_seq>>8)&0xFF; 937 rtpbuf[3] = (udp_seq)&0xFF; 938 rtpbuf[4] = (udp_tim>>24)&0xFF; 939 rtpbuf[5] = (udp_tim>>16)&0xFF; 940 rtpbuf[6] = (udp_tim>>8)&0xFF; 941 rtpbuf[7] = (udp_tim)&0xFF; 942 /* sequence and timestamp are empty */ 943 rtpbuf[8] = (session>>24)&0xFF; 944 rtpbuf[9] = (session>>16)&0xFF; 945 rtpbuf[10] = (session>>8)&0xFF; 946 rtpbuf[11] = (session)&0xFF; 947 ++udp_seq; 948 949 j = snprintf(rtpbuf+i, sizeof(rtpbuf)-i-40, /* leave some space for login */ 950 "POST /%s HTTP/1.1\r\n" 951 "Host: %s\r\n" 952 "Ntrip-Version: Ntrip/2.0\r\n" 953 "User-Agent: %s/%s\r\n" 954 "Authorization: Basic %s%s%s\r\n" 955 "Connection: close\r\n" 956 "Transfer-Encoding: chunked\r\n\r\n", 957 mountpoint, casterouthost, AGENTSTRING, 958 revisionstr, authorization, ntrip_str ? (outputmode == NTRIP1 ? "\r\nSTR: " : "\r\nNtrip-STR: ") : "", 959 ntrip_str); 960 i += j; 961 if(i > (int)sizeof(rtpbuf)-40 || j < 0) /* second check for old glibc */ 962 { 963 fprintf(stderr, "Requested data too long\n"); 962 fprintf(stderr, "Requested data too long\n"); 963 reconnect_sec_max = 0; 964 output_init = 0; 965 break; 966 } else { 967 rtpbuf[i++] = '\r'; 968 rtpbuf[i++] = '\n'; 969 rtpbuf[i++] = '\r'; 970 rtpbuf[i++] = '\n'; 971 972 if (send(socket_tcp, rtpbuf, i, 0) != i) { 973 perror("Could not send UDP packet"); 964 974 reconnect_sec_max = 0; 965 975 output_init = 0; 966 976 break; 967 } 968 else 969 { 970 rtpbuf[i++] = '\r'; 971 rtpbuf[i++] = '\n'; 972 rtpbuf[i++] = '\r'; 973 rtpbuf[i++] = '\n'; 974 975 if(send(socket_tcp, rtpbuf, i, 0) != i) 976 { 977 perror("Could not send UDP packet"); 978 reconnect_sec_max = 0; 979 output_init = 0; 980 break; 981 } 982 else 983 { 984 int stop = 0; 985 int numbytes; 986 if((numbytes=recv(socket_tcp, rtpbuf, sizeof(rtpbuf)-1, 0)) > 0) 987 { 988 /* we don't expect message longer than 1513, so we cut the last 989 byte for security reasons to prevent buffer overrun */ 990 rtpbuf[numbytes] = 0; 991 if(numbytes > 17+12 && 992 (!strncmp(rtpbuf+12, "HTTP/1.1 200 OK\r\n", 17) || 993 !strncmp(rtpbuf+12, "HTTP/1.0 200 OK\r\n", 17))) 977 } else { 978 int stop = 0; 979 int numbytes; 980 if ((numbytes = recv(socket_tcp, rtpbuf, sizeof(rtpbuf) - 1, 0)) 981 > 0) { 982 /* we don't expect message longer than 1513, so we cut the last 983 byte for security reasons to prevent buffer overrun */ 984 rtpbuf[numbytes] = 0; 985 if (numbytes > 17 + 12 986 && (!strncmp(rtpbuf + 12, "HTTP/1.1 200 OK\r\n", 17) 987 || !strncmp(rtpbuf + 12, "HTTP/1.0 200 OK\r\n", 17))) { 988 const char *sessioncheck = "session: "; 989 int l = strlen(sessioncheck) - 1; 990 int j = 0; 991 for (i = 12; j != l && i < numbytes - l; ++i) { 992 for (j = 0; 993 j < l && tolower(rtpbuf[i + j]) == sessioncheck[j]; ++j) 994 ; 995 } 996 if (i != numbytes - l) /* found a session number */ 994 997 { 995 const char *sessioncheck = "session: "; 996 int l = strlen(sessioncheck)-1; 997 int j=0; 998 for(i = 12; j != l && i < numbytes-l; ++i) 999 { 1000 for(j = 0; j < l && tolower(rtpbuf[i+j]) == sessioncheck[j]; ++j) 1001 ; 1002 } 1003 if(i != numbytes-l) /* found a session number */ 1004 { 1005 i+=l; 1006 session = 0; 1007 while(i < numbytes && rtpbuf[i] >= '0' && rtpbuf[i] <= '9') 1008 session = session * 10 + rtpbuf[i++]-'0'; 1009 if(rtpbuf[i] != '\r') 1010 { 1011 fprintf(stderr, "Could not extract session number\n"); 1012 stop = 1; 1013 } 998 i += l; 999 session = 0; 1000 while (i < numbytes && rtpbuf[i] >= '0' && rtpbuf[i] <= '9') 1001 session = session * 10 + rtpbuf[i++] - '0'; 1002 if (rtpbuf[i] != '\r') { 1003 fprintf(stderr, "Could not extract session number\n"); 1004 stop = 1; 1014 1005 } 1015 1006 } 1016 else 1017 { 1018 int k; 1019 fprintf(stderr, "Could not access mountpoint: "); 1020 for(k = 12; k < numbytes && rtpbuf[k] != '\n' && rtpbuf[k] != '\r'; ++k) 1021 { 1022 fprintf(stderr, "%c", isprint(rtpbuf[k]) ? rtpbuf[k] : '.'); 1023 } 1024 fprintf(stderr, "\n"); 1025 stop = 1; 1007 } else { 1008 int k; 1009 fprintf(stderr, "Could not access mountpoint: "); 1010 for (k = 12; 1011 k < numbytes && rtpbuf[k] != '\n' && rtpbuf[k] != '\r'; 1012 ++k) { 1013 fprintf(stderr, "%c", isprint(rtpbuf[k]) ? rtpbuf[k] : '.'); 1026 1014 } 1027 } 1028 if(!stop) 1029 { 1030 send_receive_loop(socket_tcp, outputmode, NULL, 0, session); 1031 input_init = output_init = 0; 1032 /* send connection close always to allow nice session closing */ 1033 udp_tim += (time(0)-udp_init)*1000000/TIME_RESOLUTION; 1034 rtpbuf[0] = (2<<6); 1035 /* padding, extension, csrc are empty */ 1036 rtpbuf[1] = 98; 1037 /* marker is empty */ 1038 rtpbuf[2] = (udp_seq>>8)&0xFF; 1039 rtpbuf[3] = (udp_seq)&0xFF; 1040 rtpbuf[4] = (udp_tim>>24)&0xFF; 1041 rtpbuf[5] = (udp_tim>>16)&0xFF; 1042 rtpbuf[6] = (udp_tim>>8)&0xFF; 1043 rtpbuf[7] = (udp_tim)&0xFF; 1044 /* sequence and timestamp are empty */ 1045 rtpbuf[8] = (session>>24)&0xFF; 1046 rtpbuf[9] = (session>>16)&0xFF; 1047 rtpbuf[10] = (session>>8)&0xFF; 1048 rtpbuf[11] = (session)&0xFF; 1049 1050 send(socket_tcp, rtpbuf, 12, 0); /* cleanup */ 1051 } 1052 else 1053 { 1054 reconnect_sec_max = 600; 1055 output_init = 0; 1015 fprintf(stderr, "\n"); 1016 stop = 1; 1056 1017 } 1057 1018 } 1019 if (!stop) { 1020 send_receive_loop(socket_tcp, outputmode, NULL, 0, session, chunkymode); 1021 input_init = output_init = 0; 1022 /* send connection close always to allow nice session closing */ 1023 udp_tim += (time(0) - udp_init) * 1000000 / TIME_RESOLUTION; 1024 rtpbuf[0] = (2 << 6); 1025 /* padding, extension, csrc are empty */ 1026 rtpbuf[1] = 98; 1027 /* marker is empty */ 1028 rtpbuf[2] = (udp_seq >> 8) & 0xFF; 1029 rtpbuf[3] = (udp_seq) & 0xFF; 1030 rtpbuf[4] = (udp_tim >> 24) & 0xFF; 1031 rtpbuf[5] = (udp_tim >> 16) & 0xFF; 1032 rtpbuf[6] = (udp_tim >> 8) & 0xFF; 1033 rtpbuf[7] = (udp_tim) & 0xFF; 1034 /* sequence and timestamp are empty */ 1035 rtpbuf[8] = (session >> 24) & 0xFF; 1036 rtpbuf[9] = (session >> 16) & 0xFF; 1037 rtpbuf[10] = (session >> 8) & 0xFF; 1038 rtpbuf[11] = (session) & 0xFF; 1039 1040 send(socket_tcp, rtpbuf, 12, 0); /* cleanup */ 1041 } else { 1042 reconnect_sec_max = 600; 1043 output_init = 0; 1044 } 1058 1045 } 1059 1046 } 1047 } 1060 1048 break; 1061 1049 case NTRIP1: /*** OutputMode Ntrip Version 1.0 ***/ 1062 1050 fallback = 0; 1063 1051 nBufferBytes = snprintf(szSendBuffer, sizeof(szSendBuffer), 1064 "SOURCE %s %s/%s\r\n"1065 "Source-Agent: %s/%s\r\n\r\n",1066 password, post_extension,mountpoint, AGENTSTRING, revisionstr);1067 if ((nBufferBytes > (int)sizeof(szSendBuffer)) || (nBufferBytes < 0))1068 {1052 "SOURCE %s %s/%s\r\n" 1053 "Source-Agent: %s/%s\r\n\r\n", password, post_extension, 1054 mountpoint, AGENTSTRING, revisionstr); 1055 if ((nBufferBytes > (int) sizeof(szSendBuffer)) 1056 || (nBufferBytes < 0)) { 1069 1057 fprintf(stderr, "ERROR: Destination caster request to long\n"); 1070 1058 reconnect_sec_max = 0; … … 1072 1060 break; 1073 1061 } 1074 if(!send_to_caster(szSendBuffer, socket_tcp, nBufferBytes)) 1075 { 1062 if (!send_to_caster(szSendBuffer, socket_tcp, nBufferBytes)) { 1076 1063 output_init = 0; 1077 1064 break; 1078 1065 } 1079 1066 /* check Destination caster's response */ 1080 nBufferBytes = recv(socket_tcp, szSendBuffer, sizeof(szSendBuffer), 0); 1067 nBufferBytes = recv(socket_tcp, szSendBuffer, sizeof(szSendBuffer), 1068 0); 1081 1069 szSendBuffer[nBufferBytes] = '\0'; 1082 if(!strstr(szSendBuffer, "OK")) 1083 { 1070 if (!strstr(szSendBuffer, "OK")) { 1084 1071 char *a; 1085 1072 fprintf(stderr, 1086 "ERROR: Destination caster's or Proxy's reply is not OK: "); 1087 for(a = szSendBuffer; *a && *a != '\n' && *a != '\r'; ++a) 1088 { 1073 "ERROR: Destination caster's or Proxy's reply is not OK: "); 1074 for (a = szSendBuffer; *a && *a != '\n' && *a != '\r'; ++a) { 1089 1075 fprintf(stderr, "%.1s", isprint(*a) ? a : "."); 1090 1076 } 1091 1077 fprintf(stderr, "\n"); 1092 if ((strstr(szSendBuffer,"ERROR - Bad Password"))1093 || (strstr(szSendBuffer,"400 Bad Request")))1094 reconnect_sec_max = 0;1078 if ((strstr(szSendBuffer, "ERROR - Bad Password")) 1079 || (strstr(szSendBuffer, "400 Bad Request"))) 1080 reconnect_sec_max = 0; 1095 1081 output_init = 0; 1096 1082 break; 1097 1083 } 1098 1084 #ifndef NDEBUG 1099 else 1100 { 1101 fprintf(stderr, "Destination caster response:\n%s\n", 1102 szSendBuffer); 1103 } 1104 #endif 1105 send_receive_loop(socket_tcp, outputmode, NULL, 0, 0); 1085 else { 1086 fprintf(stderr, "Destination caster response:\n%s\n", szSendBuffer); 1087 } 1088 #endif 1089 send_receive_loop(socket_tcp, outputmode, NULL, 0, 0, chunkymode); 1106 1090 input_init = output_init = 0; 1107 1091 break; 1108 1092 case HTTP: /*** Ntrip-Version 2.0 HTTP/1.1 ***/ 1109 1093 nBufferBytes = snprintf(szSendBuffer, sizeof(szSendBuffer), 1110 "POST %s/%s HTTP/1.1\r\n" 1111 "Host: %s\r\n" 1112 "Ntrip-Version: Ntrip/2.0\r\n" 1113 "User-Agent: %s/%s\r\n" 1114 "Authorization: Basic %s%s%s\r\n" 1115 "Connection: close\r\n" 1116 "Transfer-Encoding: chunked\r\n\r\n", 1117 post_extension, mountpoint, casterouthost, AGENTSTRING, 1118 revisionstr, authorization, ntrip_str ? "\r\nNtrip-STR: " : "", 1119 ntrip_str); 1120 if((nBufferBytes > (int)sizeof(szSendBuffer)) || (nBufferBytes < 0)) 1121 { 1094 "POST %s/%s HTTP/1.1\r\n" 1095 "Host: %s\r\n" 1096 "Ntrip-Version: Ntrip/2.0\r\n" 1097 "User-Agent: %s/%s\r\n" 1098 "Authorization: Basic %s%s%s\r\n" 1099 "Connection: close\r\n" 1100 "Transfer-Encoding: chunked\r\n\r\n", post_extension, 1101 mountpoint, casterouthost, AGENTSTRING, revisionstr, 1102 authorization, ntrip_str ? "\r\nNtrip-STR: " : "", ntrip_str); 1103 if ((nBufferBytes > (int) sizeof(szSendBuffer)) 1104 || (nBufferBytes < 0)) { 1122 1105 fprintf(stderr, "ERROR: Destination caster request to long\n"); 1123 1106 reconnect_sec_max = 0; … … 1125 1108 break; 1126 1109 } 1127 if(!send_to_caster(szSendBuffer, socket_tcp, nBufferBytes)) 1128 { 1110 if (!send_to_caster(szSendBuffer, socket_tcp, nBufferBytes)) { 1129 1111 output_init = 0; 1130 1112 break; 1131 1113 } 1132 1114 /* check Destination caster's response */ 1133 nBufferBytes = recv(socket_tcp, szSendBuffer, sizeof(szSendBuffer), 0);1115 nBufferBytes = recv(socket_tcp, szSendBuffer, sizeof(szSendBuffer), 0); 1134 1116 szSendBuffer[nBufferBytes] = '\0'; 1135 if(!strstr(szSendBuffer, "HTTP/1.1 200 OK")) 1136 { 1117 if (!strstr(szSendBuffer, "HTTP/1.1 200 OK")) { 1137 1118 char *a; 1138 fprintf(stderr, 1139 "ERROR: Destination caster's%s reply is not OK: ", 1140 *proxyhost ? " or Proxy's" : ""); 1141 for(a = szSendBuffer; *a && *a != '\n' && *a != '\r'; ++a) 1142 { 1119 fprintf(stderr, "ERROR: Destination caster's%s reply is not OK: ", 1120 *proxyhost ? " or Proxy's" : ""); 1121 for (a = szSendBuffer; *a && *a != '\n' && *a != '\r'; ++a) { 1143 1122 fprintf(stderr, "%.1s", isprint(*a) ? a : "."); 1144 1123 } 1145 1124 fprintf(stderr, "\n"); 1146 1125 /* fallback if necessary */ 1147 if(!strstr(szSendBuffer,"Ntrip-Version: Ntrip/2.0\r\n")) 1148 { 1126 if (!strstr(szSendBuffer, "Ntrip-Version: Ntrip/2.0\r\n")) { 1149 1127 fprintf(stderr, 1150 " Ntrip Version 2.0 not implemented at Destination caster" 1151 " <%s>%s%s%s\n%s\n" 1152 "ntripserver falls back to Ntrip Version 1.0\n\n", 1153 casterouthost, 1154 *proxyhost ? " or Proxy <" : "", proxyhost, *proxyhost ? ">" : "", 1155 *proxyhost ? " or HTTP/1.1 not implemented at Proxy\n" : ""); 1128 " Ntrip Version 2.0 not implemented at Destination caster" 1129 " <%s>%s%s%s\n%s\n" 1130 "ntripserver falls back to Ntrip Version 1.0\n\n", 1131 casterouthost, *proxyhost ? " or Proxy <" : "", proxyhost, 1132 *proxyhost ? ">" : "", 1133 *proxyhost ? 1134 " or HTTP/1.1 not implemented at Proxy\n" : ""); 1156 1135 close_session(casterouthost, mountpoint, session, rtsp_extension, 1); 1157 1136 outputmode = NTRIP1; 1158 1137 break; 1159 } 1160 else if((strstr(szSendBuffer,"HTTP/1.1 401 Unauthorized")) 1161 || (strstr(szSendBuffer,"501 Not Implemented"))) 1162 { 1163 reconnect_sec_max = 0; 1138 } else if ((strstr(szSendBuffer, "HTTP/1.1 401 Unauthorized")) 1139 || (strstr(szSendBuffer, "501 Not Implemented"))) { 1140 reconnect_sec_max = 0; 1164 1141 } 1165 1142 output_init = 0; … … 1167 1144 } 1168 1145 #ifndef NDEBUG 1169 else 1170 { 1171 fprintf(stderr, "Destination caster response:\n%s\n",szSendBuffer); 1172 } 1173 #endif 1174 send_receive_loop(socket_tcp, outputmode, NULL, 0, 0); 1146 else { 1147 fprintf(stderr, "Destination caster response:\n%s\n", szSendBuffer); 1148 } 1149 #endif 1150 send_receive_loop(socket_tcp, outputmode, NULL, 0, 0, chunkymode); 1175 1151 input_init = output_init = 0; 1176 1152 break; 1177 1153 case RTSP: /*** Ntrip-Version 2.0 RTSP / RTP ***/ 1178 if((socket_udp = socket(AF_INET, SOCK_DGRAM,0)) == INVALID_SOCKET) 1179 { 1154 if ((socket_udp = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) { 1180 1155 perror("ERROR: udp socket"); 1181 1156 exit(4); … … 1186 1161 local.sin_port = htons(0); 1187 1162 local.sin_addr.s_addr = htonl(INADDR_ANY); 1188 len = (socklen_t) sizeof(local);1163 len = (socklen_t) sizeof(local); 1189 1164 /* bind() in order to get a random RTP client_port */ 1190 if((bind(socket_udp,(struct sockaddr *)&local, len)) < 0) 1191 { 1165 if ((bind(socket_udp, (struct sockaddr*) &local, len)) < 0) { 1192 1166 perror("ERROR: udp bind"); 1193 1167 reconnect_sec_max = 0; … … 1195 1169 break; 1196 1170 } 1197 if((getsockname(socket_udp, (struct sockaddr*)&local, &len)) != -1) 1198 { 1199 client_port = (unsigned int)ntohs(local.sin_port); 1200 } 1201 else 1202 { 1171 if ((getsockname(socket_udp, (struct sockaddr*) &local, &len)) 1172 != -1) { 1173 client_port = (unsigned int) ntohs(local.sin_port); 1174 } else { 1203 1175 perror("ERROR: getsockname(localhost)"); 1204 1176 reconnect_sec_max = 0; … … 1207 1179 } 1208 1180 nBufferBytes = snprintf(szSendBuffer, sizeof(szSendBuffer), 1209 "SETUP rtsp://%s%s/%s RTSP/1.0\r\n"1210 "CSeq: %d\r\n"1211 "Ntrip-Version: Ntrip/2.0\r\n"1212 "Ntrip-Component: Ntripserver\r\n"1213 "User-Agent: %s/%s\r\n"1214 "Transport: RTP/GNSS;unicast;client_port=%u\r\n"1215 "Authorization: Basic %s%s%s\r\n\r\n",1216 casterouthost, rtsp_extension, mountpoint, udp_cseq++, AGENTSTRING,1217 revisionstr, client_port, authorization, ntrip_str1218 ? "\r\nNtrip-STR: " : "",ntrip_str);1219 if ((nBufferBytes > (int)sizeof(szSendBuffer)) || (nBufferBytes < 0))1220 {1181 "SETUP rtsp://%s%s/%s RTSP/1.0\r\n" 1182 "CSeq: %d\r\n" 1183 "Ntrip-Version: Ntrip/2.0\r\n" 1184 "Ntrip-Component: Ntripserver\r\n" 1185 "User-Agent: %s/%s\r\n" 1186 "Transport: RTP/GNSS;unicast;client_port=%u\r\n" 1187 "Authorization: Basic %s%s%s\r\n\r\n", casterouthost, 1188 rtsp_extension, mountpoint, udp_cseq++, AGENTSTRING, revisionstr, 1189 client_port, authorization, ntrip_str ? "\r\nNtrip-STR: " : "", 1190 ntrip_str); 1191 if ((nBufferBytes > (int) sizeof(szSendBuffer)) 1192 || (nBufferBytes < 0)) { 1221 1193 fprintf(stderr, "ERROR: Destination caster request to long\n"); 1222 1194 reconnect_sec_max = 0; … … 1224 1196 break; 1225 1197 } 1226 if(!send_to_caster(szSendBuffer, socket_tcp, nBufferBytes)) 1227 { 1198 if (!send_to_caster(szSendBuffer, socket_tcp, nBufferBytes)) { 1228 1199 output_init = 0; 1229 1200 break; 1230 1201 } 1231 while((nBufferBytes = recv(socket_tcp, szSendBuffer, 1232 sizeof(szSendBuffer), 0)) > 0) 1233 { 1202 while ((nBufferBytes = recv(socket_tcp, szSendBuffer, 1203 sizeof(szSendBuffer), 0)) > 0) { 1234 1204 /* check Destination caster's response */ 1235 1205 szSendBuffer[nBufferBytes] = '\0'; 1236 if(!strstr(szSendBuffer, "RTSP/1.0 200 OK")) 1237 { 1206 if (!strstr(szSendBuffer, "RTSP/1.0 200 OK")) { 1238 1207 char *a; 1239 fprintf(stderr, 1240 "ERROR: Destination caster's%s reply is not OK: ", 1241 *proxyhost ? " or Proxy's" : ""); 1242 for(a = szSendBuffer; *a && *a != '\n' && *a != '\r'; ++a) 1243 { 1208 fprintf(stderr, "ERROR: Destination caster's%s reply is not OK: ", 1209 *proxyhost ? " or Proxy's" : ""); 1210 for (a = szSendBuffer; *a && *a != '\n' && *a != '\r'; ++a) { 1244 1211 fprintf(stderr, "%c", isprint(*a) ? *a : '.'); 1245 1212 } 1246 1213 fprintf(stderr, "\n"); 1247 1214 /* fallback if necessary */ 1248 if(strncmp(szSendBuffer, "RTSP",4) != 0) 1249 { 1250 if(strstr(szSendBuffer,"Ntrip-Version: Ntrip/2.0\r\n")) 1251 { 1215 if (strncmp(szSendBuffer, "RTSP", 4) != 0) { 1216 if (strstr(szSendBuffer, "Ntrip-Version: Ntrip/2.0\r\n")) { 1252 1217 fprintf(stderr, 1253 " RTSP not implemented at Destination caster <%s>%s%s%s\n\n" 1254 "ntripserver falls back to Ntrip Version 2.0 in TCP/IP" 1255 " mode\n\n", casterouthost, 1256 *proxyhost ? " or Proxy <" :"", proxyhost, *proxyhost ? ">":""); 1257 close_session(casterouthost, mountpoint, session, rtsp_extension, 1); 1218 " RTSP not implemented at Destination caster <%s>%s%s%s\n\n" 1219 "ntripserver falls back to Ntrip Version 2.0 in TCP/IP" 1220 " mode\n\n", casterouthost, 1221 *proxyhost ? " or Proxy <" : "", proxyhost, 1222 *proxyhost ? ">" : ""); 1223 close_session(casterouthost, mountpoint, session, 1224 rtsp_extension, 1); 1258 1225 outputmode = HTTP; 1259 1226 fallback = 1; 1260 1227 break; 1261 } 1262 else 1263 { 1228 } else { 1264 1229 fprintf(stderr, 1265 " Ntrip-Version 2.0 not implemented at Destination caster" 1266 "<%s>%s%s%s\n%s" 1267 " or RTSP/1.0 not implemented at Destination caster%s\n\n" 1268 "ntripserver falls back to Ntrip Version 1.0\n\n", 1269 casterouthost, *proxyhost ? " or Proxy <" :"", proxyhost, 1270 *proxyhost ? ">":"", 1271 *proxyhost ? " or HTTP/1.1 not implemented at Proxy\n" : "", 1272 *proxyhost ? " or Proxy" :""); 1273 close_session(casterouthost, mountpoint, session, rtsp_extension, 1); 1230 " Ntrip-Version 2.0 not implemented at Destination caster" 1231 "<%s>%s%s%s\n%s" 1232 " or RTSP/1.0 not implemented at Destination caster%s\n\n" 1233 "ntripserver falls back to Ntrip Version 1.0\n\n", 1234 casterouthost, *proxyhost ? " or Proxy <" : "", proxyhost, 1235 *proxyhost ? ">" : "", 1236 *proxyhost ? 1237 " or HTTP/1.1 not implemented at Proxy\n" : "", 1238 *proxyhost ? " or Proxy" : ""); 1239 close_session(casterouthost, mountpoint, session, 1240 rtsp_extension, 1); 1274 1241 outputmode = NTRIP1; 1275 1242 fallback = 1; 1276 1243 break; 1277 1244 } 1278 } 1279 else if((strstr(szSendBuffer, "RTSP/1.0 401 Unauthorized")) 1280 || (strstr(szSendBuffer, "RTSP/1.0 501 Not Implemented"))) 1281 { 1245 } else if ((strstr(szSendBuffer, "RTSP/1.0 401 Unauthorized")) 1246 || (strstr(szSendBuffer, "RTSP/1.0 501 Not Implemented"))) { 1282 1247 reconnect_sec_max = 0; 1283 1248 } … … 1286 1251 } 1287 1252 #ifndef NDEBUG 1288 else 1289 { 1290 fprintf(stderr, "Destination caster response:\n%s\n",szSendBuffer); 1253 else { 1254 fprintf(stderr, "Destination caster response:\n%s\n", szSendBuffer); 1291 1255 } 1292 1256 #endif 1293 if((strstr(szSendBuffer,"RTSP/1.0 200 OK\r\n")) 1294 && (strstr(szSendBuffer,"CSeq: 1\r\n"))) 1295 { 1296 for(token = strtok(szSendBuffer, dlim); token != NULL; 1297 token = strtok(NULL, dlim)) 1298 { 1299 tok_buf[i] = token; i++; 1257 if ((strstr(szSendBuffer, "RTSP/1.0 200 OK\r\n")) 1258 && (strstr(szSendBuffer, "CSeq: 1\r\n"))) { 1259 for (token = strtok(szSendBuffer, dlim); token != NULL; token = 1260 strtok(NULL, dlim)) { 1261 tok_buf[i] = token; 1262 i++; 1300 1263 } 1301 1264 session = atoi(tok_buf[6]); 1302 1265 server_port = atoi(tok_buf[10]); 1303 1266 nBufferBytes = snprintf(szSendBuffer, sizeof(szSendBuffer), 1304 "RECORD rtsp://%s%s/%s RTSP/1.0\r\n" 1305 "CSeq: %d\r\n" 1306 "Session: %u\r\n" 1307 "\r\n", 1308 casterouthost, rtsp_extension, mountpoint, udp_cseq++, 1309 session); 1310 if((nBufferBytes >= (int)sizeof(szSendBuffer)) 1311 || (nBufferBytes < 0)) 1312 { 1313 fprintf(stderr, "ERROR: Destination caster request to long\n"); 1267 "RECORD rtsp://%s%s/%s RTSP/1.0\r\n" 1268 "CSeq: %d\r\n" 1269 "Session: %u\r\n" 1270 "\r\n", casterouthost, rtsp_extension, mountpoint, 1271 udp_cseq++, session); 1272 if ((nBufferBytes >= (int) sizeof(szSendBuffer)) 1273 || (nBufferBytes < 0)) { 1274 fprintf(stderr, "ERROR: Destination caster request to long\n"); 1314 1275 reconnect_sec_max = 0; 1315 1276 output_init = 0; 1316 1277 break; 1317 1278 } 1318 if(!send_to_caster(szSendBuffer, socket_tcp, nBufferBytes)) 1319 { 1279 if (!send_to_caster(szSendBuffer, socket_tcp, nBufferBytes)) { 1320 1280 output_init = 0; 1321 1281 break; 1322 1282 } 1323 } 1324 else if((strstr(szSendBuffer,"RTSP/1.0 200 OK\r\n")) && (strstr(szSendBuffer, 1325 "CSeq: 2\r\n"))) 1326 { 1283 } else if ((strstr(szSendBuffer, "RTSP/1.0 200 OK\r\n")) 1284 && (strstr(szSendBuffer, "CSeq: 2\r\n"))) { 1327 1285 /* fill structure with caster address information for UDP */ 1328 1286 memset(&casterRTP, 0, sizeof(casterRTP)); 1329 1287 casterRTP.sin_family = AF_INET; 1330 casterRTP.sin_port = htons(((uint16_t)server_port)); 1331 if((he = gethostbyname(outhost))== NULL) 1332 { 1288 casterRTP.sin_port = htons(((uint16_t) server_port)); 1289 if ((he = gethostbyname(outhost)) == NULL) { 1333 1290 fprintf(stderr, "ERROR: Destination caster unknown\n"); 1334 1291 reconnect_sec_max = 0; 1335 1292 output_init = 0; 1336 1293 break; 1294 } else { 1295 memcpy((char*) &casterRTP.sin_addr.s_addr, he->h_addr_list[0], 1296 (size_t) he->h_length); 1337 1297 } 1338 else 1339 { 1340 memcpy((char *)&casterRTP.sin_addr.s_addr, 1341 he->h_addr_list[0], (size_t)he->h_length); 1342 } 1343 len = (socklen_t)sizeof(casterRTP); 1344 send_receive_loop(socket_udp, outputmode, (struct sockaddr *)&casterRTP, 1345 (socklen_t)len, session); 1298 len = (socklen_t) sizeof(casterRTP); 1299 send_receive_loop(socket_udp, outputmode, 1300 (struct sockaddr*) &casterRTP, (socklen_t) len, session, chunkymode); 1301 break; 1302 } else { 1346 1303 break; 1347 1304 } 1348 else{break;}1349 1305 } 1350 1306 input_init = output_init = 0; 1351 1307 break; 1308 case TDC: 1309 break; 1352 1310 } 1353 1311 } 1354 1312 close_session(casterouthost, mountpoint, session, rtsp_extension, 0); 1355 if ( (reconnect_sec_max || fallback) && !sigint_received)1313 if ((reconnect_sec_max || fallback) && !sigint_received) 1356 1314 reconnect_sec = reconnect(reconnect_sec, reconnect_sec_max); 1357 else inputmode = LAST; 1315 else 1316 inputmode = LAST; 1358 1317 } 1359 1318 return 0; 1360 1319 } 1361 1320 1362 static void send_receive_loop(sockettype sock, int outmode, struct sockaddr* pcasterRTP,1363 socklen_t length, unsigned int rtpssrc) 1364 {1365 int 1366 char 1367 char 1368 char 1369 int 1370 int 1371 1372 1373 int 1374 struct 1375 struct timeval last = {0,0};1321 static void send_receive_loop(sockettype sock, int outmode, 1322 struct sockaddr *pcasterRTP, socklen_t length, unsigned int rtpssrc, 1323 int chunkymode) { 1324 int nodata = 0; 1325 char buffer[BUFSZ] = { 0 }; 1326 char sisnetbackbuffer[200]; 1327 char szSendBuffer[BUFSZ] = ""; 1328 int nBufferBytes = 0; 1329 int remainChunk = 0; 1330 1331 /* RTSP / RTP Mode */ 1332 int isfirstpacket = 1; 1333 struct timeval now; 1334 struct timeval last = { 0, 0 }; 1376 1335 long int sendtimediff; 1377 int rtpseq = 0; 1378 int rtptime = 0; 1379 time_t laststate = time(0); 1380 1381 if(outmode == UDP) 1382 { 1336 int rtpseq = 0; 1337 int rtptime = 0; 1338 time_t laststate = time(0); 1339 1340 if (outmode == UDP) { 1383 1341 rtptime = time(0); 1384 1342 #ifdef WINDOWSVERSION … … 1386 1344 if(ioctlsocket(socket_tcp, FIONBIO, &blockmode)) 1387 1345 #else /* WINDOWSVERSION */ 1388 if (fcntl(socket_tcp, F_SETFL, O_NONBLOCK) < 0)1346 if (fcntl(socket_tcp, F_SETFL, O_NONBLOCK) < 0) 1389 1347 #endif /* WINDOWSVERSION */ 1390 {1348 { 1391 1349 fprintf(stderr, "Could not set nonblocking mode\n"); 1392 1350 return; 1393 1351 } 1394 } 1395 else if(outmode == RTSP) 1396 { 1352 } else if (outmode == RTSP) { 1397 1353 #ifdef WINDOWSVERSION 1398 1354 u_long blockmode = 1; 1399 1355 if(ioctlsocket(socket_tcp, FIONBIO, &blockmode)) 1400 1356 #else /* WINDOWSVERSION */ 1401 if (fcntl(socket_tcp, F_SETFL, O_NONBLOCK) < 0)1357 if (fcntl(socket_tcp, F_SETFL, O_NONBLOCK) < 0) 1402 1358 #endif /* WINDOWSVERSION */ 1403 {1359 { 1404 1360 fprintf(stderr, "Could not set nonblocking mode\n"); 1405 1361 return; … … 1408 1364 1409 1365 /* data transmission */ 1410 fprintf(stderr, "transfering data ...\n");1411 int 1366 fprintf(stderr, "transfering data ...\n"); 1367 int send_recv_success = 0; 1412 1368 #ifdef WINDOWSVERSION 1413 1369 time_t nodata_begin = 0, nodata_current = 0; 1414 1370 #endif 1415 while(1) 1416 { 1417 if(send_recv_success < 3) send_recv_success++; 1418 if(!nodata) 1419 { 1371 while (1) { 1372 if (send_recv_success < 3) 1373 send_recv_success++; 1374 if (!nodata) { 1420 1375 #ifndef WINDOWSVERSION 1421 1376 alarm(ALARMTIME); … … 1423 1378 time(&nodata_begin); 1424 1379 #endif 1425 } 1426 else 1427 { 1380 } else { 1428 1381 nodata = 0; 1429 1382 #ifdef WINDOWSVERSION 1430 1383 time(&nodata_current); 1431 if(difftime(nodata_current, nodata_begin) >= ALARMTIME) 1432 { 1384 if(difftime(nodata_current, nodata_begin) >= ALARMTIME) { 1433 1385 sigalarm_received = 1; 1434 1386 fprintf(stderr, "ERROR: more than %d seconds no activity\n", ALARMTIME); … … 1440 1392 if((sigalarm_received) || (sigint_received)) break; 1441 1393 #else 1442 if((sigalarm_received) || (sigint_received) || (sigpipe_received)) break; 1443 #endif 1444 if(!nBufferBytes) 1445 { 1446 if(inputmode == SISNET && sisnet <= 30) 1447 { 1394 if ((sigalarm_received) || (sigint_received) || (sigpipe_received)) 1395 break; 1396 #endif 1397 if (!nBufferBytes) { 1398 if (inputmode == SISNET && sisnet <= 30) { 1448 1399 int i; 1449 1400 /* a somewhat higher rate than 1 second to get really each block */ 1450 1401 /* means we need to skip double blocks sometimes */ 1451 struct timeval tv = { 0,700000};1402 struct timeval tv = { 0, 700000 }; 1452 1403 select(0, 0, 0, 0, &tv); 1453 1404 memcpy(sisnetbackbuffer, buffer, sizeof(sisnetbackbuffer)); 1454 1405 i = (sisnet >= 30 ? 5 : 3); 1455 if((send(gps_socket, "MSG\r\n", i, 0)) != i) 1456 { 1406 if ((send(gps_socket, "MSG\r\n", i, 0)) != i) { 1457 1407 perror("WARNING: sending SISNeT data request failed"); 1458 1408 return; … … 1460 1410 } 1461 1411 /*** receiving data ****/ 1462 if (inputmode == INFILE)1412 if (inputmode == INFILE) 1463 1413 nBufferBytes = read(gps_file, buffer, sizeof(buffer)); 1464 else if(inputmode == SERIAL) 1465 { 1414 else if (inputmode == SERIAL) { 1466 1415 #ifndef WINDOWSVERSION 1467 1416 nBufferBytes = read(gps_serial, buffer, sizeof(buffer)); … … 1482 1431 nBufferBytes = read(gps_socket, buffer, sizeof(buffer)); 1483 1432 #endif 1484 if(!nBufferBytes) 1485 { 1433 if (!nBufferBytes) { 1486 1434 fprintf(stderr, "WARNING: no data received from input\n"); 1487 1435 nodata = 1; … … 1492 1440 #endif 1493 1441 continue; 1494 } 1495 else if((nBufferBytes < 0) && (!sigint_received)) 1496 { 1442 } else if ((nBufferBytes < 0) && (!sigint_received)) { 1497 1443 perror("WARNING: reading input failed"); 1498 1444 return; 1499 1445 } 1500 1446 /* we can compare the whole buffer, as the additional bytes 1501 remain unchanged */ 1502 if(inputmode == SISNET && sisnet <= 30 && 1503 !memcmp(sisnetbackbuffer, buffer, sizeof(sisnetbackbuffer))) 1504 { 1447 remain unchanged */ 1448 if (inputmode == SISNET && sisnet <= 30 1449 && !memcmp(sisnetbackbuffer, buffer, sizeof(sisnetbackbuffer))) { 1505 1450 nBufferBytes = 0; 1506 1451 } 1507 1452 } 1508 if (nBufferBytes < 0)1453 if (nBufferBytes < 0) 1509 1454 return; 1455 1456 if (chunkymode) { 1457 int cstop = 0; 1458 int pos = 0; 1459 int chunksize = 0; 1460 int totalbytes = 0; 1461 int nChunkBytes = 0; 1462 char chunkBytes[BUFSZ]; 1463 1464 int i; 1465 while (!sigint_received && !cstop && pos < nBufferBytes) { 1466 switch (chunkymode) { 1467 case 1: /* reading number starts */ 1468 chunksize = 0; 1469 ++chunkymode; /* no break */ 1470 break; 1471 case 2: /* during reading number */ 1472 i = buffer[pos++]; 1473 if (i >= '0' && i <= '9') 1474 chunksize = chunksize * 16 + i - '0'; 1475 else if (i >= 'a' && i <= 'f') 1476 chunksize = chunksize * 16 + i - 'a' + 10; 1477 else if (i >= 'A' && i <= 'F') 1478 chunksize = chunksize * 16 + i - 'A' + 10; 1479 else if (i == '\r') 1480 ++chunkymode; 1481 else if (i == ';') 1482 chunkymode = 5; 1483 else 1484 cstop = 1; 1485 break; 1486 case 3: /* scanning for return */ 1487 if (buffer[pos++] == '\n') 1488 chunkymode = chunksize ? 4 : 1; 1489 else 1490 cstop = 1; 1491 break; 1492 case 4: /* output data */ 1493 i = nBufferBytes - pos; 1494 if (i > chunksize) { 1495 i = chunksize; 1496 } 1497 if (nChunkBytes <= nBufferBytes) { 1498 memcpy(chunkBytes + nChunkBytes, buffer + pos, (size_t) i); 1499 nChunkBytes += i; 1500 } 1501 totalbytes += i; 1502 chunksize -= i; 1503 pos += i; 1504 if (!chunksize) 1505 chunkymode = 1; 1506 break; 1507 case 5: 1508 if (i == '\r') 1509 chunkymode = 3; 1510 break; 1511 } 1512 } 1513 if (cstop) { 1514 fprintf(stderr, "Error in chunky transfer encoding\n"); 1515 return; 1516 } 1517 else { 1518 if (nChunkBytes <= nBufferBytes) { 1519 strcpy(buffer, ""); 1520 memcpy(buffer, chunkBytes, (size_t) nChunkBytes); 1521 nBufferBytes = nChunkBytes; 1522 } 1523 } 1524 } 1510 1525 /** send data ***/ 1511 if ((nBufferBytes)&& (outmode == NTRIP1)) /*** Ntrip-Version 1.0 ***/1526 if ((nBufferBytes) && (outmode == NTRIP1)) /*** Ntrip-Version 1.0 ***/ 1512 1527 { 1513 1528 int i; 1514 if((i = send(sock, buffer, (size_t)nBufferBytes, MSG_DONTWAIT)) 1515 != nBufferBytes) 1516 { 1517 if(i < 0) 1518 { 1519 if(errno != EAGAIN) 1520 { 1529 if ((i = send(sock, buffer, (size_t) nBufferBytes, MSG_DONTWAIT)) != nBufferBytes) { 1530 if (i < 0) { 1531 if (errno != EAGAIN) { 1521 1532 perror("WARNING: could not send data to Destination caster"); 1522 1533 return; 1523 1534 } 1524 } 1525 else if(i) 1526 { 1527 memmove(buffer, buffer+i, (size_t)(nBufferBytes-i)); 1535 } else if (i) { 1536 memmove(buffer, buffer + i, (size_t) (nBufferBytes - i)); 1528 1537 nBufferBytes -= i; 1529 1538 } 1530 }else 1531 { 1539 } else { 1532 1540 nBufferBytes = 0; 1533 1541 } 1534 } 1535 else if((nBufferBytes) && (outmode == UDP)) 1536 { 1542 } else if ((nBufferBytes) && (outmode == UDP)) { 1537 1543 char rtpbuf[1592]; 1538 1544 int i; 1539 1545 int ct = time(0); 1540 udp_tim += (ct -udp_init)*1000000/TIME_RESOLUTION;1546 udp_tim += (ct - udp_init) * 1000000 / TIME_RESOLUTION; 1541 1547 udp_init = ct; 1542 rtpbuf[0] = (2 <<6);1548 rtpbuf[0] = (2 << 6); 1543 1549 rtpbuf[1] = 96; 1544 rtpbuf[2] = (udp_seq >>8)&0xFF;1545 rtpbuf[3] = (udp_seq) &0xFF;1546 rtpbuf[4] = (udp_tim >>24)&0xFF;1547 rtpbuf[5] = (udp_tim >>16)&0xFF;1548 rtpbuf[6] = (udp_tim >>8)&0xFF;1549 rtpbuf[7] = (udp_tim) &0xFF;1550 rtpbuf[8] = (rtpssrc >>24)&0xFF;1551 rtpbuf[9] = (rtpssrc >>16)&0xFF;1552 rtpbuf[10] = (rtpssrc >>8)&0xFF;1553 rtpbuf[11] = (rtpssrc) &0xFF;1550 rtpbuf[2] = (udp_seq >> 8) & 0xFF; 1551 rtpbuf[3] = (udp_seq) & 0xFF; 1552 rtpbuf[4] = (udp_tim >> 24) & 0xFF; 1553 rtpbuf[5] = (udp_tim >> 16) & 0xFF; 1554 rtpbuf[6] = (udp_tim >> 8) & 0xFF; 1555 rtpbuf[7] = (udp_tim) & 0xFF; 1556 rtpbuf[8] = (rtpssrc >> 24) & 0xFF; 1557 rtpbuf[9] = (rtpssrc >> 16) & 0xFF; 1558 rtpbuf[10] = (rtpssrc >> 8) & 0xFF; 1559 rtpbuf[11] = (rtpssrc) & 0xFF; 1554 1560 ++udp_seq; 1555 memcpy(rtpbuf+12, buffer, nBufferBytes); 1556 if((i = send(socket_tcp, rtpbuf, (size_t)nBufferBytes+12, MSG_DONTWAIT)) 1557 != nBufferBytes+12) 1558 { 1559 if(errno != EAGAIN) 1560 { 1561 memcpy(rtpbuf + 12, buffer, nBufferBytes); 1562 if ((i = send(socket_tcp, rtpbuf, (size_t) nBufferBytes + 12, MSG_DONTWAIT)) != nBufferBytes + 12) { 1563 if (errno != EAGAIN) { 1561 1564 perror("WARNING: could not send data to Destination caster"); 1562 1565 return; 1563 1566 } 1564 } 1565 else 1567 } else 1566 1568 nBufferBytes = 0; 1567 1569 i = recv(socket_tcp, rtpbuf, sizeof(rtpbuf), 0); 1568 if(i >= 12 && (unsigned char)rtpbuf[0] == (2 << 6) && rtpssrc == 1569 (unsigned int)(((unsigned char)rtpbuf[8]<<24)+((unsigned char)rtpbuf[9]<<16) 1570 +((unsigned char)rtpbuf[10]<<8)+(unsigned char)rtpbuf[11])) 1571 { 1572 if(rtpbuf[1] == 96) 1573 rtptime = time(0); 1574 else if(rtpbuf[1] == 98) 1575 { 1576 fprintf(stderr, "Connection end\n"); 1577 return; 1578 } 1579 } 1580 else if(time(0) > rtptime+60) 1581 { 1570 if (i >= 12 && (unsigned char) rtpbuf[0] == (2 << 6) 1571 && rtpssrc 1572 == (unsigned int) (((unsigned char) rtpbuf[8] << 24) 1573 + ((unsigned char) rtpbuf[9] << 16) 1574 + ((unsigned char) rtpbuf[10] << 8) 1575 + (unsigned char) rtpbuf[11])) { 1576 if (rtpbuf[1] == 96) 1577 rtptime = time(0); 1578 else if (rtpbuf[1] == 98) { 1579 fprintf(stderr, "Connection end\n"); 1580 return; 1581 } 1582 } else if (time(0) > rtptime + 60) { 1582 1583 fprintf(stderr, "Timeout\n"); 1583 1584 return; … … 1585 1586 } 1586 1587 /*** Ntrip-Version 2.0 HTTP/1.1 ***/ 1587 else if((nBufferBytes) && (outmode == HTTP)) 1588 { 1589 if(!remainChunk) 1590 { 1591 int nChunkBytes = snprintf(szSendBuffer, sizeof(szSendBuffer),"%x\r\n", nBufferBytes); 1588 else if ((nBufferBytes) && (outmode == HTTP)) { 1589 if (!remainChunk) { 1590 int nChunkBytes = snprintf(szSendBuffer, sizeof(szSendBuffer), "%x\r\n", nBufferBytes); 1592 1591 send(sock, szSendBuffer, nChunkBytes, 0); 1593 1592 remainChunk = nBufferBytes; 1594 1593 } 1595 int i = send(sock, buffer, (size_t)remainChunk, MSG_DONTWAIT); 1596 if(i < 0) 1597 { 1598 if(errno != EAGAIN) 1599 { 1594 int i = send(sock, buffer, (size_t) remainChunk, MSG_DONTWAIT); 1595 if (i < 0) { 1596 if (errno != EAGAIN) { 1600 1597 perror("WARNING: could not send data to Destination caster"); 1601 1598 return; 1602 1599 } 1603 } 1604 else if(i) 1605 { 1606 memmove(buffer, buffer+i, (size_t)(nBufferBytes-i)); 1600 } else if (i) { 1601 memmove(buffer, buffer + i, (size_t) (nBufferBytes - i)); 1607 1602 nBufferBytes -= i; 1608 1603 remainChunk -= i; 1609 } 1610 else 1611 { 1612 nBufferBytes = 0; 1613 remainChunk = 0; 1614 } 1615 if(!remainChunk) 1604 } else { 1605 nBufferBytes = 0; 1606 remainChunk = 0; 1607 } 1608 if (!remainChunk) 1616 1609 send(sock, "\r\n", strlen("\r\n"), 0); 1617 1610 } 1618 1611 /*** Ntrip-Version 2.0 RTSP(TCP) / RTP(UDP) ***/ 1619 else if((nBufferBytes) && (outmode == RTSP)) 1620 { 1612 else if ((nBufferBytes) && (outmode == RTSP)) { 1621 1613 time_t ct; 1622 1614 int r; 1623 char rtpbuffer[BUFSZ +12];1615 char rtpbuffer[BUFSZ + 12]; 1624 1616 int i, j; 1625 1617 gettimeofday(&now, NULL); 1626 1618 /* RTP data packet generation*/ 1627 if (isfirstpacket){1619 if (isfirstpacket) { 1628 1620 rtpseq = rand(); 1629 1621 rtptime = rand(); 1630 1622 last = now; 1631 1623 isfirstpacket = 0; 1632 } 1633 else 1634 { 1624 } else { 1635 1625 ++rtpseq; 1636 sendtimediff = (((now.tv_sec - last.tv_sec) *1000000)1637 + (now.tv_usec - last.tv_usec));1638 rtptime += sendtimediff /TIME_RESOLUTION;1639 } 1640 rtpbuffer[0] = (RTP_VERSION <<6);1626 sendtimediff = (((now.tv_sec - last.tv_sec) * 1000000) 1627 + (now.tv_usec - last.tv_usec)); 1628 rtptime += sendtimediff / TIME_RESOLUTION; 1629 } 1630 rtpbuffer[0] = (RTP_VERSION << 6); 1641 1631 /* padding, extension, csrc are empty */ 1642 1632 rtpbuffer[1] = 96; 1643 1633 /* marker is empty */ 1644 rtpbuffer[2] = rtpseq >>8;1634 rtpbuffer[2] = rtpseq >> 8; 1645 1635 rtpbuffer[3] = rtpseq; 1646 rtpbuffer[4] = rtptime >>24;1647 rtpbuffer[5] = rtptime >>16;1648 rtpbuffer[6] = rtptime >>8;1636 rtpbuffer[4] = rtptime >> 24; 1637 rtpbuffer[5] = rtptime >> 16; 1638 rtpbuffer[6] = rtptime >> 8; 1649 1639 rtpbuffer[7] = rtptime; 1650 rtpbuffer[8] = rtpssrc >>24;1651 rtpbuffer[9] = rtpssrc >>16;1652 rtpbuffer[10] = rtpssrc >>8;1640 rtpbuffer[8] = rtpssrc >> 24; 1641 rtpbuffer[9] = rtpssrc >> 16; 1642 rtpbuffer[10] = rtpssrc >> 8; 1653 1643 rtpbuffer[11] = rtpssrc; 1654 for(j=0; j<nBufferBytes; j++) {rtpbuffer[12+j] = buffer[j];} 1655 last.tv_sec = now.tv_sec; 1644 for (j = 0; j < nBufferBytes; j++) { 1645 rtpbuffer[12 + j] = buffer[j]; 1646 } 1647 last.tv_sec = now.tv_sec; 1656 1648 last.tv_usec = now.tv_usec; 1657 if ((i = sendto(sock, rtpbuffer, 12 + nBufferBytes, 0, pcasterRTP, 1658 length)) != (nBufferBytes + 12)) 1659 { 1660 if(i < 0) 1661 { 1662 if(errno != EAGAIN) 1663 { 1649 if ((i = sendto(sock, rtpbuffer, 12 + nBufferBytes, 0, pcasterRTP, length)) 1650 != (nBufferBytes + 12)) { 1651 if (i < 0) { 1652 if (errno != EAGAIN) { 1664 1653 perror("WARNING: could not send data to Destination caster"); 1665 1654 return; 1666 1655 } 1667 } 1668 else if(i) 1669 { 1670 memmove(buffer, buffer+(i-12), (size_t)(nBufferBytes-(i-12))); 1671 nBufferBytes -= i-12; 1672 } 1673 } 1674 else 1675 { 1656 } else if (i) { 1657 memmove(buffer, buffer + (i - 12), 1658 (size_t) (nBufferBytes - (i - 12))); 1659 nBufferBytes -= i - 12; 1660 } 1661 } else { 1676 1662 nBufferBytes = 0; 1677 1663 } 1678 1664 ct = time(0); 1679 if(ct-laststate > 15) 1680 { 1665 if (ct - laststate > 15) { 1681 1666 i = snprintf(buffer, sizeof(buffer), 1682 "GET_PARAMETER rtsp://%s%s/%s RTSP/1.0\r\n" 1683 "CSeq: %d\r\n" 1684 "Session: %u\r\n" 1685 "\r\n", 1686 casterouthost, rtsp_extension, mountpoint, udp_cseq++, rtpssrc); 1687 if(i > (int)sizeof(buffer) || i < 0) 1688 { 1667 "GET_PARAMETER rtsp://%s%s/%s RTSP/1.0\r\n" 1668 "CSeq: %d\r\n" 1669 "Session: %u\r\n" 1670 "\r\n", casterouthost, rtsp_extension, mountpoint, udp_cseq++, 1671 rtpssrc); 1672 if (i > (int) sizeof(buffer) || i < 0) { 1689 1673 fprintf(stderr, "Requested data too long\n"); 1690 1674 return; 1691 } 1692 else if(send(socket_tcp, buffer, (size_t)i, 0) != i) 1693 { 1675 } else if (send(socket_tcp, buffer, (size_t) i, 0) != i) { 1694 1676 perror("send"); 1695 1677 return; … … 1698 1680 } 1699 1681 /* ignore RTSP server replies */ 1700 if((r=recv(socket_tcp, buffer, sizeof(buffer), 0)) < 0) 1701 { 1682 if ((r = recv(socket_tcp, buffer, sizeof(buffer), 0)) < 0) { 1702 1683 #ifdef WINDOWSVERSION 1703 1684 if(WSAGetLastError() != WSAEWOULDBLOCK) 1704 1685 #else /* WINDOWSVERSION */ 1705 if (errno != EAGAIN)1686 if (errno != EAGAIN) 1706 1687 #endif /* WINDOWSVERSION */ 1707 1688 { … … 1709 1690 return; 1710 1691 } 1711 } 1712 else if(!r) 1713 { 1692 } else if (!r) { 1714 1693 fprintf(stderr, "Control connection read error\n"); 1715 1694 return; 1716 1695 } 1717 1696 } 1718 if(send_recv_success == 3) reconnect_sec = 1; 1697 if (send_recv_success == 3) 1698 reconnect_sec = 1; 1719 1699 } 1720 1700 return; 1721 1701 } 1722 1723 1702 1724 1703 /******************************************************************** … … 1742 1721 ********************************************************************/ 1743 1722 #ifndef WINDOWSVERSION 1744 static int openserial(const char * tty, int blocksz, int baud) 1745 { 1723 static int openserial(const char *tty, int blocksz, int baud) { 1746 1724 struct termios termios; 1747 1725 1748 /*** opening the serial port ***/1726 /*** opening the serial port ***/ 1749 1727 gps_serial = open(tty, O_RDWR | O_NONBLOCK | O_EXLOCK); 1750 if(gps_serial < 0) 1751 { 1728 if (gps_serial < 0) { 1752 1729 perror("ERROR: opening serial connection"); 1753 1730 return (-1); 1754 1731 } 1755 1732 1756 /*** configuring the serial port ***/ 1757 if(tcgetattr(gps_serial, &termios) < 0) 1758 { 1733 /*** configuring the serial port ***/ 1734 if (tcgetattr(gps_serial, &termios) < 0) { 1759 1735 perror("ERROR: get serial attributes"); 1760 1736 return (-1); 1761 1737 } 1762 1738 termios.c_iflag = 0; 1763 termios.c_oflag = 0; 1739 termios.c_oflag = 0; /* (ONLRET) */ 1764 1740 termios.c_cflag = CS8 | CLOCAL | CREAD; 1765 1741 termios.c_lflag = 0; 1766 1742 { 1767 1743 int cnt; 1768 for (cnt = 0; cnt < NCCS; cnt++)1744 for (cnt = 0; cnt < NCCS; cnt++) 1769 1745 termios.c_cc[cnt] = -1; 1770 1746 } … … 1773 1749 1774 1750 #if (B4800 != 4800) 1775 /* Not every system has speed settings equal to absolute speed value. */ 1776 switch (baud) 1777 { 1778 case 300: 1779 baud = B300; 1780 break; 1781 case 1200: 1782 baud = B1200; 1783 break; 1784 case 2400: 1785 baud = B2400; 1786 break; 1787 case 4800: 1788 baud = B4800; 1789 break; 1790 case 9600: 1791 baud = B9600; 1792 break; 1793 case 19200: 1794 baud = B19200; 1795 break; 1796 case 38400: 1797 baud = B38400; 1798 break; 1751 /* Not every system has speed settings equal to absolute speed value. */ 1752 switch (baud) { 1753 case 300: 1754 baud = B300; 1755 break; 1756 case 1200: 1757 baud = B1200; 1758 break; 1759 case 2400: 1760 baud = B2400; 1761 break; 1762 case 4800: 1763 baud = B4800; 1764 break; 1765 case 9600: 1766 baud = B9600; 1767 break; 1768 case 19200: 1769 baud = B19200; 1770 break; 1771 case 38400: 1772 baud = B38400; 1773 break; 1799 1774 #ifdef B57600 1800 case 57600:1801 baud = B57600;1802 break;1775 case 57600: 1776 baud = B57600; 1777 break; 1803 1778 #endif 1804 1779 #ifdef B115200 1805 case 115200:1806 baud = B115200;1807 break;1780 case 115200: 1781 baud = B115200; 1782 break; 1808 1783 #endif 1809 1784 #ifdef B230400 1810 case 230400: 1811 baud = B230400; 1812 break; 1813 #endif 1814 default: 1815 fprintf(stderr, "WARNING: Baud settings not useful, using 19200\n"); 1816 baud = B19200; 1817 break; 1818 } 1819 #endif 1820 1821 if(cfsetispeed(&termios, baud) != 0) 1822 { 1785 case 230400: 1786 baud = B230400; 1787 break; 1788 #endif 1789 default: 1790 fprintf(stderr, "WARNING: Baud settings not useful, using 19200\n"); 1791 baud = B19200; 1792 break; 1793 } 1794 #endif 1795 1796 if (cfsetispeed(&termios, baud) != 0) { 1823 1797 perror("ERROR: setting serial speed with cfsetispeed"); 1824 1798 return (-1); 1825 1799 } 1826 if(cfsetospeed(&termios, baud) != 0) 1827 { 1800 if (cfsetospeed(&termios, baud) != 0) { 1828 1801 perror("ERROR: setting serial speed with cfsetospeed"); 1829 1802 return (-1); 1830 1803 } 1831 if(tcsetattr(gps_serial, TCSANOW, &termios) < 0) 1832 { 1804 if (tcsetattr(gps_serial, TCSANOW, &termios) < 0) { 1833 1805 perror("ERROR: setting serial attributes"); 1834 1806 return (-1); 1835 1807 } 1836 if(fcntl(gps_serial, F_SETFL, 0) == -1) 1837 { 1808 if (fcntl(gps_serial, F_SETFL, 0) == -1) { 1838 1809 perror("WARNING: setting blocking inputmode failed"); 1839 1810 } … … 1841 1812 } 1842 1813 #else 1843 static HANDLE openserial(const char * tty, int baud) 1844 { 1814 static HANDLE openserial(const char * tty, int baud) { 1845 1815 char compath[15] = ""; 1846 1816 1847 1817 snprintf(compath, sizeof(compath), "\\\\.\\%s", tty); 1848 1818 if((gps_serial = CreateFile(compath, GENERIC_WRITE|GENERIC_READ 1849 , 0, 0, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE) 1850 { 1819 , 0, 0, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE) { 1851 1820 fprintf(stderr, "ERROR: opening serial connection\n"); 1852 1821 return (INVALID_HANDLE_VALUE); … … 1862 1831 COMMTIMEOUTS ct = {1000, 1, 0, 0, 0}; 1863 1832 1864 if(!BuildCommDCB(str, &dcb)) 1865 { 1833 if(!BuildCommDCB(str, &dcb)) { 1866 1834 fprintf(stderr, "ERROR: get serial attributes\n"); 1867 1835 return (INVALID_HANDLE_VALUE); 1868 1836 } 1869 else if(!SetCommState(gps_serial, &dcb)) 1870 { 1837 else if(!SetCommState(gps_serial, &dcb)) { 1871 1838 fprintf(stderr, "ERROR: set serial attributes\n"); 1872 1839 return (INVALID_HANDLE_VALUE); 1873 1840 } 1874 else if(!SetCommTimeouts(gps_serial, &ct)) 1875 { 1841 else if(!SetCommTimeouts(gps_serial, &ct)) { 1876 1842 fprintf(stderr, "ERROR: set serial timeouts\n"); 1877 1843 return (INVALID_HANDLE_VALUE); … … 1883 1849 1884 1850 /******************************************************************** 1885 * usage1886 *1887 * Send a usage message to standard error and quit the program.1888 *1889 * Parameters:1890 * None.1891 *1892 * Return Value:1893 * The function does not return a value.1894 *1895 * Remarks:1896 *1897 *********************************************************************/1851 * usage 1852 * 1853 * Send a usage message to standard error and quit the program. 1854 * 1855 * Parameters: 1856 * None. 1857 * 1858 * Return Value: 1859 * The function does not return a value. 1860 * 1861 * Remarks: 1862 * 1863 *********************************************************************/ 1898 1864 #ifdef __GNUC__ 1899 1865 __attribute__ ((noreturn)) 1900 1866 #endif /* __GNUC__ */ 1901 void usage(int rc, char *name) 1902 { 1867 void usage(int rc, char *name) { 1903 1868 fprintf(stderr, "Version %s (%s) GPL" COMPILEDATE "\nUsage:\n%s [OPTIONS]\n", 1904 revisionstr, datestr, name);1869 revisionstr, datestr, name); 1905 1870 fprintf(stderr, "PURPOSE\n"); 1906 fprintf(stderr, " The purpose of this program is to pick up a GNSS data stream (Input, Source)\n"); 1871 fprintf(stderr, 1872 " The purpose of this program is to pick up a GNSS data stream (Input, Source)\n"); 1907 1873 fprintf(stderr, " from either\n\n"); 1908 1874 fprintf(stderr, " 1. a Serial port, or\n"); … … 1911 1877 fprintf(stderr, " 4. a SISNeT Data Server, or\n"); 1912 1878 fprintf(stderr, " 5. a UDP server, or\n"); 1913 fprintf(stderr, " 6. an NTRIP Version 1.0 Caster\n\n"); 1914 fprintf(stderr, " and forward that incoming stream (Output, Destination) to either\n\n"); 1879 fprintf(stderr, " 6. an NTRIP Version 1.0 Caster\n"); 1880 fprintf(stderr, " 7. an NTRIP Version 2.0 Caster in HTTP mode \n\n"); 1881 fprintf(stderr, 1882 " and forward that incoming stream (Output, Destination) to either\n\n"); 1915 1883 fprintf(stderr, " - an NTRIP Version 1.0 Caster, or\n"); 1916 fprintf(stderr, " - an NTRIP Version 2.0 Caster via TCP/IP or RTSP/RTP.\n\n\n"); 1884 fprintf(stderr, 1885 " - an NTRIP Version 2.0 Caster via TCP/IP or RTSP/RTP, or \n"); 1886 fprintf(stderr, " - an DABPLUS Content Server via TCP/IP and TDC \n\n\n"); 1917 1887 fprintf(stderr, "OPTIONS\n"); 1918 1888 fprintf(stderr, " -h|? print this help screen\n\n"); 1919 fprintf(stderr, " -E <ProxyHost> Proxy server host name or address, required i.e. when\n"); 1920 fprintf(stderr, " running the program in a proxy server protected LAN,\n"); 1889 fprintf(stderr, 1890 " -E <ProxyHost> Proxy server host name or address, required i.e. when\n"); 1891 fprintf(stderr, 1892 " running the program in a proxy server protected LAN,\n"); 1921 1893 fprintf(stderr, " optional\n"); 1922 fprintf(stderr, " -F <ProxyPort> Proxy server IP port, required i.e. when running\n"); 1923 fprintf(stderr, " the program in a proxy server protected LAN, optional\n"); 1924 fprintf(stderr, " -R <maxDelay> Reconnect mechanism with maximum delay between reconnect\n"); 1925 fprintf(stderr, " attemts in seconds, default: no reconnect activated,\n"); 1894 fprintf(stderr, 1895 " -F <ProxyPort> Proxy server IP port, required i.e. when running\n"); 1896 fprintf(stderr, 1897 " the program in a proxy server protected LAN, optional\n"); 1898 fprintf(stderr, 1899 " -R <maxDelay> Reconnect mechanism with maximum delay between reconnect\n"); 1900 fprintf(stderr, 1901 " attemts in seconds, default: no reconnect activated,\n"); 1926 1902 fprintf(stderr, " optional\n\n"); 1927 fprintf(stderr, " -M <InputMode> Sets the input mode (1 = Serial Port, 2 = IP server,\n"); 1928 fprintf(stderr, " 3 = File, 4 = SISNeT Data Server, 5 = UDP server, 6 = NTRIP Caster),\n"); 1903 fprintf(stderr, 1904 " -M <InputMode> Sets the input mode (1 = Serial Port, 2 = IP server,\n"); 1905 fprintf(stderr, 1906 " 3 = File, 4 = SISNeT Data Server, 5 = UDP server, 6 = NTRIP1 Caster, 7 = NTRIP2 Caster in HTTP mode),\n"); 1929 1907 fprintf(stderr, " mandatory\n\n"); 1930 1908 fprintf(stderr, " <InputMode> = 1 (Serial Port):\n"); 1931 fprintf(stderr, " -i <Device> Serial input device, default: %s, mandatory if\n", ttyport); 1909 fprintf(stderr, 1910 " -i <Device> Serial input device, default: %s, mandatory if\n", 1911 ttyport); 1932 1912 fprintf(stderr, " <InputMode>=1\n"); 1933 fprintf(stderr, " -b <BaudRate> Serial input baud rate, default: 19200 bps, mandatory\n"); 1913 fprintf(stderr, 1914 " -b <BaudRate> Serial input baud rate, default: 19200 bps, mandatory\n"); 1934 1915 fprintf(stderr, " if <InputMode>=1\n"); 1935 fprintf(stderr, " -f <InitFile> Name of initialization file to be send to input device,\n"); 1916 fprintf(stderr, 1917 " -f <InitFile> Name of initialization file to be send to input device,\n"); 1936 1918 fprintf(stderr, " optional\n\n"); 1937 1919 fprintf(stderr, " <InputMode> = 2|5 (IP port | UDP port):\n"); 1938 fprintf(stderr, " -H <ServerHost> Input host name or address, default: 127.0.0.1,\n"); 1920 fprintf(stderr, 1921 " -H <ServerHost> Input host name or address, default: 127.0.0.1,\n"); 1939 1922 fprintf(stderr, " mandatory if <InputMode> = 2|5\n"); 1940 fprintf(stderr, " -P <ServerPort> Input port, default: 1025, mandatory if <InputMode>= 2|5\n"); 1941 fprintf(stderr, " -f <ServerFile> Name of initialization file to be send to server,\n"); 1923 fprintf(stderr, 1924 " -P <ServerPort> Input port, default: 1025, mandatory if <InputMode>= 2|5\n"); 1925 fprintf(stderr, 1926 " -f <ServerFile> Name of initialization file to be send to server,\n"); 1942 1927 fprintf(stderr, " optional\n"); 1943 fprintf(stderr, " -x <ServerUser> User ID to access incoming stream, optional\n"); 1944 fprintf(stderr, " -y <ServerPass> Password, to access incoming stream, optional\n"); 1945 fprintf(stderr, " -B Bind to incoming UDP stream, optional for <InputMode> = 5\n\n"); 1928 fprintf(stderr, 1929 " -x <ServerUser> User ID to access incoming stream, optional\n"); 1930 fprintf(stderr, 1931 " -y <ServerPass> Password, to access incoming stream, optional\n"); 1932 fprintf(stderr, 1933 " -B Bind to incoming UDP stream, optional for <InputMode> = 5\n\n"); 1946 1934 fprintf(stderr, " <InputMode> = 3 (File):\n"); 1947 fprintf(stderr, " -s <File> File name to simulate stream by reading data from (log)\n"); 1948 fprintf(stderr, " file, default is %s, mandatory for <InputMode> = 3\n\n", filepath); 1935 fprintf(stderr, 1936 " -s <File> File name to simulate stream by reading data from (log)\n"); 1937 fprintf(stderr, 1938 " file, default is %s, mandatory for <InputMode> = 3\n\n", 1939 filepath); 1949 1940 fprintf(stderr, " <InputMode> = 4 (SISNeT Data Server):\n"); 1950 fprintf(stderr, " -H <SisnetHost> SISNeT Data Server name or address,\n"); 1951 fprintf(stderr, " default: 131.176.49.142, mandatory if <InputMode> = 4\n"); 1952 fprintf(stderr, " -P <SisnetPort> SISNeT Data Server port, default: 7777, mandatory if\n"); 1941 fprintf(stderr, 1942 " -H <SisnetHost> SISNeT Data Server name or address,\n"); 1943 fprintf(stderr, 1944 " default: 131.176.49.142, mandatory if <InputMode> = 4\n"); 1945 fprintf(stderr, 1946 " -P <SisnetPort> SISNeT Data Server port, default: 7777, mandatory if\n"); 1953 1947 fprintf(stderr, " <InputMode> = 4\n"); 1954 fprintf(stderr, " -u <SisnetUser> SISNeT Data Server user ID, mandatory if <InputMode> = 4\n"); 1955 fprintf(stderr, " -l <SisnetPass> SISNeT Data Server password, mandatory if <InputMode> = 4\n"); 1956 fprintf(stderr, " -V <SisnetVers> SISNeT Data Server Version number, options are 2.1, 3.0\n"); 1957 fprintf(stderr, " or 3.1, default: 3.1, mandatory if <InputMode> = 4\n\n"); 1948 fprintf(stderr, 1949 " -u <SisnetUser> SISNeT Data Server user ID, mandatory if <InputMode> = 4\n"); 1950 fprintf(stderr, 1951 " -l <SisnetPass> SISNeT Data Server password, mandatory if <InputMode> = 4\n"); 1952 fprintf(stderr, 1953 " -V <SisnetVers> SISNeT Data Server Version number, options are 2.1, 3.0\n"); 1954 fprintf(stderr, 1955 " or 3.1, default: 3.1, mandatory if <InputMode> = 4\n\n"); 1958 1956 fprintf(stderr, " <InputMode> = 6 (NTRIP Version 1.0 Caster):\n"); 1959 fprintf(stderr, " -H <SourceHost> Source caster name or address, default: 127.0.0.1,\n"); 1957 fprintf(stderr, 1958 " -H <SourceHost> Source caster name or address, default: 127.0.0.1,\n"); 1960 1959 fprintf(stderr, " mandatory if <InputMode> = 6\n"); 1961 fprintf(stderr, " -P <SourcePort> Source caster port, default: 2101, mandatory if\n"); 1960 fprintf(stderr, 1961 " -P <SourcePort> Source caster port, default: 2101, mandatory if\n"); 1962 1962 fprintf(stderr, " <InputMode> = 6\n"); 1963 fprintf(stderr, " -D <SourceMount> Source caster mountpoint for stream input, mandatory if\n"); 1964 fprintf(stderr, " <InputMode> = 6\n"); 1965 fprintf(stderr, " -U <SourceUser> Source caster user Id for input stream access, mandatory\n"); 1966 fprintf(stderr, " for protected streams if <InputMode> = 6\n"); 1967 fprintf(stderr, " -W <SourcePass> Source caster password for input stream access, mandatory\n"); 1968 fprintf(stderr, " for protected streams if <InputMode> = 6\n\n"); 1969 fprintf(stderr, " -O <OutputMode> Sets output mode for communatation with destination caster\n"); 1970 fprintf(stderr, " 1 = http: NTRIP Version 2.0 Caster in TCP/IP mode\n"); 1971 fprintf(stderr, " 2 = rtsp: NTRIP Version 2.0 Caster in RTSP/RTP mode\n"); 1963 fprintf(stderr, 1964 " -D <SourceMount> Source caster mountpoint for stream input, mandatory if\n"); 1965 fprintf(stderr, " <InputMode> = 6|7\n"); 1966 fprintf(stderr, 1967 " -U <SourceUser> Source caster user Id for input stream access, mandatory\n"); 1968 fprintf(stderr, 1969 " for protected streams if <InputMode> = 6|7\n"); 1970 fprintf(stderr, 1971 " -W <SourcePass> Source caster password for input stream access, mandatory\n"); 1972 fprintf(stderr, 1973 " for protected streams if <InputMode> = 6|7\n\n"); 1974 fprintf(stderr, 1975 " -O <OutputMode> Sets output mode for communication with destination caster / server\n"); 1976 fprintf(stderr, 1977 " 1 = http: NTRIP Version 2.0 Caster in TCP/IP mode\n"); 1978 fprintf(stderr, 1979 " 2 = rtsp: NTRIP Version 2.0 Caster in RTSP/RTP mode\n"); 1972 1980 fprintf(stderr, " 3 = ntrip1: NTRIP Version 1.0 Caster\n"); 1973 fprintf(stderr, " 4 = udp: NTRIP Version 2.0 Caster in Plain UDP mode\n"); 1974 fprintf(stderr, " optional\n\n"); 1975 fprintf(stderr, " Defaults to NTRIP1.0, but will change to 2.0 in future versions\n"); 1976 fprintf(stderr, " Note that the program automatically falls back from mode rtsp to mode http and\n"); 1981 fprintf(stderr, 1982 " 4 = udp: NTRIP Version 2.0 Caster in Plain UDP mode\n"); 1983 fprintf(stderr, 1984 " 5 = tdc: DABPLUS Content Server in TDC mode\n\n\n"); 1985 fprintf(stderr, 1986 " Defaults to NTRIP1.0, but will change to 2.0 in future versions\n"); 1987 fprintf(stderr, 1988 " Note that the program automatically falls back from mode rtsp to mode http and\n"); 1977 1989 fprintf(stderr, " further to mode ntrip1 if necessary.\n\n"); 1978 fprintf(stderr, " -a <DestHost> Destination caster name or address, default: 127.0.0.1,\n"); 1990 fprintf(stderr, 1991 " -a <DestHost> Destination caster name or address, default: 127.0.0.1,\n"); 1979 1992 fprintf(stderr, " mandatory\n"); 1980 fprintf(stderr, " -p <DestPort> Destination caster port, default: 2101, mandatory\n");1981 fprintf(stderr, " -m <DestMount> Destination caster mountpoint for stream upload,\n");1993 fprintf(stderr, 1994 " -p <DestPort> Destination caster port, default: 2101,\n"); 1982 1995 fprintf(stderr, " mandatory\n"); 1983 fprintf(stderr, " -n <DestUser> Destination caster user ID for stream upload to\n"); 1984 fprintf(stderr, " mountpoint, only for NTRIP Version 2.0 destination\n"); 1985 fprintf(stderr, " casters, mandatory\n"); 1986 fprintf(stderr, " -c <DestPass> Destination caster password for stream upload to\n"); 1987 fprintf(stderr, " mountpoint, mandatory\n"); 1996 fprintf(stderr, 1997 " -m <DestMount> Destination caster mountpoint for stream upload,\n"); 1998 fprintf(stderr, 1999 " only for NTRIP destination casters, mandatory\n"); 2000 fprintf(stderr, 2001 " -n <DestUser> Destination caster user ID for stream upload to mountpoint,\n"); 2002 fprintf(stderr, 2003 " only for NTRIP Version 2.0 destination casters, mandatory\n"); 2004 fprintf(stderr, 2005 " -c <DestPass> Destination caster password for stream upload to mountpoint,\n"); 2006 fprintf(stderr, 2007 " only for NTRIP destination casters, mandatory\n"); 1988 2008 fprintf(stderr, " -N <STR-record> Sourcetable STR-record\n"); 1989 fprintf(stderr, " optional for NTRIP Version 2.0 in RTSP/RTP and TCP/IP mode\n\n"); 2009 fprintf(stderr, 2010 " optional for NTRIP Version 2.0 in RTSP/RTP and TCP/IP mode\n\n"); 1990 2011 exit(rc); 1991 2012 } /* usage */ 1992 1993 2013 1994 2014 /********************************************************************/ … … 2001 2021 #endif /* __GNUC__ */ 2002 2022 { 2003 sigint_received 2023 sigint_received = 1; 2004 2024 fprintf(stderr, "WARNING: SIGINT received - ntripserver terminates\n"); 2005 2025 } … … 2026 2046 #endif /* WINDOWSVERSION */ 2027 2047 2028 static void setup_signal_handler(int sig, void (*handler)(int)) 2029 { 2048 static void setup_signal_handler(int sig, void (*handler)(int)) { 2030 2049 #if _POSIX_VERSION > 198800L 2031 2050 struct sigaction action; … … 2042 2061 } /* setupsignal_handler */ 2043 2062 2044 2045 2063 /******************************************************************** 2046 2064 * base64-encoding * 2047 *******************************************************************/ 2048 static const char encodingTable [64] = 2049 { 2050 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', 2051 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f', 2052 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', 2053 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' 2054 }; 2065 *******************************************************************/ 2066 static const char encodingTable[64] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 2067 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 2068 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 2069 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', 2070 '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' }; 2055 2071 2056 2072 /* does not buffer overrun, but breaks directly after an error */ 2057 2073 /* returns the number of required bytes */ 2058 static int encode(char *buf, int size, const char *user, const char *pwd) 2059 { 2074 static int encode(char *buf, int size, const char *user, const char *pwd) { 2060 2075 unsigned char inbuf[3]; 2061 2076 char *out = buf; 2062 2077 int i, sep = 0, fill = 0, bytes = 0; 2063 2078 2064 while(*user || *pwd) 2065 { 2079 while (*user || *pwd) { 2066 2080 i = 0; 2067 while(i < 3 && *user) inbuf[i++] = *(user++); 2068 if(i < 3 && !sep) {inbuf[i++] = ':'; ++sep; } 2069 while(i < 3 && *pwd) inbuf[i++] = *(pwd++); 2070 while(i < 3) {inbuf[i++] = 0; ++fill; } 2071 if(out-buf < size-1) 2072 *(out++) = encodingTable[(inbuf [0] & 0xFC) >> 2]; 2073 if(out-buf < size-1) 2074 *(out++) = encodingTable[((inbuf [0] & 0x03) << 4) 2075 | ((inbuf [1] & 0xF0) >> 4)]; 2076 if(out-buf < size-1) 2077 { 2078 if(fill == 2) 2081 while (i < 3 && *user) 2082 inbuf[i++] = *(user++); 2083 if (i < 3 && !sep) { 2084 inbuf[i++] = ':'; 2085 ++sep; 2086 } 2087 while (i < 3 && *pwd) 2088 inbuf[i++] = *(pwd++); 2089 while (i < 3) { 2090 inbuf[i++] = 0; 2091 ++fill; 2092 } 2093 if (out - buf < size - 1) 2094 *(out++) = encodingTable[(inbuf[0] & 0xFC) >> 2]; 2095 if (out - buf < size - 1) 2096 *(out++) = encodingTable[((inbuf[0] & 0x03) << 4) 2097 | ((inbuf[1] & 0xF0) >> 4)]; 2098 if (out - buf < size - 1) { 2099 if (fill == 2) 2079 2100 *(out++) = '='; 2080 2101 else 2081 *(out++) = encodingTable[((inbuf [1] & 0x0F) << 2) 2082 | ((inbuf [2] & 0xC0) >> 6)]; 2083 } 2084 if(out-buf < size-1) 2085 { 2086 if(fill >= 1) 2102 *(out++) = encodingTable[((inbuf[1] & 0x0F) << 2) 2103 | ((inbuf[2] & 0xC0) >> 6)]; 2104 } 2105 if (out - buf < size - 1) { 2106 if (fill >= 1) 2087 2107 *(out++) = '='; 2088 2108 else 2089 *(out++) = encodingTable[inbuf 2109 *(out++) = encodingTable[inbuf[2] & 0x3F]; 2090 2110 } 2091 2111 bytes += 4; 2092 2112 } 2093 if (out-buf < size)2113 if (out - buf < size) 2094 2114 *out = 0; 2095 2115 return bytes; 2096 2116 }/* base64 Encoding */ 2097 2117 2098 2099 2118 /******************************************************************** 2100 2119 * send message to caster * 2101 *********************************************************************/ 2102 static int send_to_caster(char *input, sockettype socket, int input_size) 2103 { 2104 int send_error = 1; 2105 2106 if((send(socket, input, (size_t)input_size, 0)) != input_size) 2107 { 2108 fprintf(stderr, "WARNING: could not send full header to Destination caster\n"); 2120 *********************************************************************/ 2121 static int send_to_caster(char *input, sockettype socket, int input_size) { 2122 int send_error = 1; 2123 2124 if ((send(socket, input, (size_t) input_size, 0)) != input_size) { 2125 fprintf(stderr, 2126 "WARNING: could not send full header to Destination caster\n"); 2109 2127 send_error = 0; 2110 2128 } 2111 2129 #ifndef NDEBUG 2112 else 2113 { 2130 else { 2114 2131 fprintf(stderr, "\nDestination caster request:\n"); 2115 2132 fprintf(stderr, "%s", input); … … 2119 2136 }/* send_to_caster */ 2120 2137 2121 2122 2138 /******************************************************************** 2123 2139 * reconnect * 2124 *********************************************************************/ 2125 int reconnect(int rec_sec, int rec_sec_max) 2126 { 2127 fprintf(stderr,"reconnect in <%d> seconds\n\n", rec_sec); 2140 *********************************************************************/ 2141 int reconnect(int rec_sec, int rec_sec_max) { 2142 fprintf(stderr, "reconnect in <%d> seconds\n\n", rec_sec); 2128 2143 rec_sec *= 2; 2129 if (rec_sec > rec_sec_max) rec_sec = rec_sec_max; 2144 if (rec_sec > rec_sec_max) 2145 rec_sec = rec_sec_max; 2130 2146 #ifndef WINDOWSVERSION 2131 2147 sleep(rec_sec); … … 2138 2154 } /* reconnect */ 2139 2155 2140 2141 2156 /******************************************************************** 2142 2157 * close session * 2143 *********************************************************************/2158 *********************************************************************/ 2144 2159 static void close_session(const char *caster_addr, const char *mountpoint, 2145 int session, char *rtsp_ext, int fallback) 2146 { 2147 int size_send_buf; 2160 int session, char *rtsp_ext, int fallback) { 2161 int size_send_buf; 2148 2162 char send_buf[BUFSZ]; 2149 2163 2150 if(!fallback) 2151 { 2152 if((gps_socket != INVALID_SOCKET) && 2153 ((inputmode == TCPSOCKET) || (inputmode == UDPSOCKET) || 2154 (inputmode == CASTER) || (inputmode == SISNET))) 2155 { 2156 if(closesocket(gps_socket) == -1) 2157 { 2164 if (!fallback) { 2165 if ((gps_socket != INVALID_SOCKET) 2166 && ((inputmode == TCPSOCKET) || (inputmode == UDPSOCKET) 2167 || (inputmode == NTRIP1_IN) || (inputmode == NTRIP2_HTTP_IN) 2168 || (inputmode == SISNET))) { 2169 if (closesocket(gps_socket) == -1) { 2158 2170 perror("ERROR: close input device "); 2159 2171 exit(0); 2160 } 2161 else 2162 { 2172 } else { 2163 2173 gps_socket = -1; 2164 2174 #ifndef NDEBUG … … 2166 2176 #endif 2167 2177 } 2168 } 2169 else if((gps_serial != INVALID_HANDLE_VALUE) && (inputmode == SERIAL)) 2170 { 2178 } else if ((gps_serial != INVALID_HANDLE_VALUE) && (inputmode == SERIAL)) { 2171 2179 #ifndef WINDOWSVERSION 2172 if(close(gps_serial) == INVALID_HANDLE_VALUE) 2173 { 2180 if (close(gps_serial) == INVALID_HANDLE_VALUE) { 2174 2181 perror("ERROR: close input device "); 2175 2182 exit(0); … … 2182 2189 } 2183 2190 #endif 2184 else 2185 { 2191 else { 2186 2192 gps_serial = INVALID_HANDLE_VALUE; 2187 2193 #ifndef NDEBUG … … 2189 2195 #endif 2190 2196 } 2191 } 2192 else if((gps_file != -1) && (inputmode == INFILE)) 2193 { 2194 if(close(gps_file) == -1) 2195 { 2197 } else if ((gps_file != -1) && (inputmode == INFILE)) { 2198 if (close(gps_file) == -1) { 2196 2199 perror("ERROR: close input device "); 2197 2200 exit(0); 2198 } 2199 else 2200 { 2201 } else { 2201 2202 gps_file = -1; 2202 2203 #ifndef NDEBUG … … 2207 2208 } 2208 2209 2209 if(socket_udp != INVALID_SOCKET) 2210 { 2211 if(udp_cseq > 2) 2212 { 2210 if (socket_udp != INVALID_SOCKET) { 2211 if (udp_cseq > 2) { 2213 2212 size_send_buf = snprintf(send_buf, sizeof(send_buf), 2214 "TEARDOWN rtsp://%s%s/%s RTSP/1.0\r\n" 2215 "CSeq: %d\r\n" 2216 "Session: %u\r\n" 2217 "\r\n", 2218 caster_addr, rtsp_ext, mountpoint, udp_cseq++, session); 2219 if((size_send_buf >= (int)sizeof(send_buf)) || (size_send_buf < 0)) 2220 { 2213 "TEARDOWN rtsp://%s%s/%s RTSP/1.0\r\n" 2214 "CSeq: %d\r\n" 2215 "Session: %u\r\n" 2216 "\r\n", caster_addr, rtsp_ext, mountpoint, udp_cseq++, session); 2217 if ((size_send_buf >= (int) sizeof(send_buf)) || (size_send_buf < 0)) { 2221 2218 fprintf(stderr, "ERROR: Destination caster request to long\n"); 2222 2219 exit(0); 2223 2220 } 2224 send_to_caster(send_buf, socket_tcp, size_send_buf); strcpy(send_buf,""); 2221 send_to_caster(send_buf, socket_tcp, size_send_buf); 2222 strcpy(send_buf, ""); 2225 2223 size_send_buf = recv(socket_tcp, send_buf, sizeof(send_buf), 0); 2226 2224 send_buf[size_send_buf] = '\0'; … … 2229 2227 #endif 2230 2228 } 2231 if(closesocket(socket_udp)==-1) 2232 { 2229 if (closesocket(socket_udp) == -1) { 2233 2230 perror("ERROR: close udp socket"); 2234 2231 exit(0); 2235 } 2236 else 2237 { 2232 } else { 2238 2233 socket_udp = -1; 2239 2234 #ifndef NDEBUG … … 2243 2238 } 2244 2239 2245 if(socket_tcp != INVALID_SOCKET) 2246 { 2247 if(closesocket(socket_tcp) == -1) 2248 { 2240 if (socket_tcp != INVALID_SOCKET) { 2241 if (closesocket(socket_tcp) == -1) { 2249 2242 perror("ERROR: close tcp socket"); 2250 2243 exit(0); 2251 } 2252 else 2253 { 2244 } else { 2254 2245 socket_tcp = -1; 2255 2246 #ifndef NDEBUG
Note:
See TracChangeset
for help on using the changeset viewer.