- Timestamp:
- Jun 2, 2005, 11:33:11 AM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/ntripserver/NtripLinuxServer.c
r22 r23 41 41 */ 42 42 43 /* $Id: NtripLinuxServer.c,v 1.1 0 2005/04/27 08:32:43stoecker Exp $43 /* $Id: NtripLinuxServer.c,v 1.11 2005/04/27 10:31:12 stoecker Exp $ 44 44 * Changes - Version 0.7 45 45 * Sep 22 2003 Steffen Tschirpke <St.Tschirpke@actina.de> … … 59 59 * - TCP sending now somewhat more stable 60 60 * - cleanup of error handling 61 * 62 * Changes - Version 0.11 63 * Jun 02 2005 Dirk Stoecker <soft@dstoecker.de> 64 * - added SISNeT support 65 * - added UDP support 66 * - cleanup of host and port handling 67 * - added inactivity alarm of 60 seconds 61 68 */ 62 69 … … 66 73 #include <getopt.h> 67 74 #include <netdb.h> 75 #include <signal.h> 68 76 #include <stdio.h> 69 77 #include <stdlib.h> … … 83 91 #endif 84 92 85 enum MODE { SERIAL = 1, TCPSOCKET = 2, INFILE = 3 };86 87 #define VERSION "NTRIP NtripServerLinux/0.1 0"93 enum MODE { SERIAL = 1, TCPSOCKET = 2, INFILE = 3, SISNET = 4, UDPSOCKET = 5 }; 94 95 #define VERSION "NTRIP NtripServerLinux/0.11" 88 96 #define BUFSZ 1024 89 97 … … 95 103 #define NTRIP_CASTER "www.euref-ip.net" 96 104 #define NTRIP_PORT 80 105 106 /* default sisnet source */ 107 #define SISNET_SERVER "131.176.49.142" 108 #define SISNET_PORT 7777 109 110 #define ALARMTIME 60 97 111 98 112 static int ttybaud = 19200; … … 100 114 static const char *filepath = "/dev/stdin"; 101 115 static enum MODE mode = INFILE; 116 static int sisnetv3 = 0; 117 static int gpsfd = -1; 102 118 103 119 /* Forward references */ 104 120 static int openserial(const char * tty, int blocksz, int baud); 105 static void send_receive_loop(int sock, int fd );121 static void send_receive_loop(int sock, int fd, int sisnet); 106 122 static void usage(int); 123 124 static void sighandler_alarm(/*int arg*/) 125 { 126 fprintf(stderr, "ERROR: more than %d seconds no activity\n", ALARMTIME); 127 exit(1); 128 } 107 129 108 130 /* … … 126 148 int main(int argc, char **argv) 127 149 { 128 int c , gpsfd = -1;150 int c; 129 151 int size = 2048; /* for setting send buffer size */ 130 152 131 unsigned int out_port = 0; 132 unsigned int in_port = 0; 153 const char *inhost = 0; 154 const char *outhost = 0; 155 unsigned int outport = 0; 156 unsigned int inport = 0; 133 157 const char *mountpoint = NULL; 134 158 const char *password = ""; 159 const char *sisnetpassword = ""; 160 const char *sisnetuser = ""; 135 161 const char *initfile = NULL; 136 162 int sock_id; 137 163 char szSendBuffer[BUFSZ]; 138 164 int nBufferBytes; 139 140 struct hostent *inhost; 141 struct hostent *outhost; 142 143 struct sockaddr_in in_addr; 144 struct sockaddr_in out_addr; 145 146 if(!(outhost = gethostbyname(NTRIP_CASTER))) 147 { 148 fprintf(stderr, "WARNING: host %s unknown\n", NTRIP_CASTER); 149 } 150 else 151 { 152 memset((char *) &out_addr, 0x00, sizeof(out_addr)); 153 memcpy(&out_addr.sin_addr, outhost->h_addr, (size_t)outhost->h_length); 154 } 155 165 struct hostent *he; 166 struct sockaddr_in addr; 167 168 signal(SIGALRM,sighandler_alarm); 169 alarm(ALARMTIME); 156 170 /* get and check program arguments */ 157 171 if(argc <= 1) … … 160 174 exit(1); 161 175 } 162 while((c = getopt(argc, argv, "M:i:h:b:p:s:a:m:c:H:P:f: ")) != EOF)176 while((c = getopt(argc, argv, "M:i:h:b:p:s:a:m:c:H:P:f:l:u:V:")) != EOF) 163 177 { 164 178 switch (c) … … 168 182 else if(!strcmp(optarg, "tcpsocket")) mode = 2; 169 183 else if(!strcmp(optarg, "file")) mode = 3; 184 else if(!strcmp(optarg, "sisnet")) mode = 4; 185 else if(!strcmp(optarg, "udpsocket")) mode = 5; 170 186 else mode = atoi(optarg); 171 if((mode == 0) || (mode > 3))187 if((mode == 0) || (mode > 5)) 172 188 { 173 189 fprintf(stderr, "ERROR: can't convert %s to a valid mode\n", optarg); … … 178 194 ttyport = optarg; 179 195 break; 196 case 'V': 197 if(!strcmp("3.0", optarg)) sisnetv3 = 1; 198 else if(strcmp("2.1", optarg)) 199 { 200 fprintf(stderr, "ERROR: unknown SISNeT version %s\n", optarg); 201 usage(-2); 202 } 180 203 case 'b': /* serial ttyin speed */ 181 204 ttybaud = atoi(optarg); … … 187 210 break; 188 211 case 'a': /* http server IP address A.B.C.D */ 189 outhost = gethostbyname(optarg); 190 if(outhost == NULL) 191 { 192 fprintf(stderr, "ERROR: host %s unknown\n", optarg); 193 usage(-2); 194 } 195 memset((char *) &out_addr, 0x00, sizeof(out_addr)); 196 memcpy(&out_addr.sin_addr, outhost->h_addr, (size_t)outhost->h_length); 212 outhost = optarg; 197 213 break; 198 214 case 'p': /* http server port */ 199 out _port = atoi(optarg);200 if(out _port <= 1)215 outport = atoi(optarg); 216 if(outport <= 1 || outport > 65535) 201 217 { 202 218 fprintf(stderr, "ERROR: can't convert %s to a valid HTTP server port\n", … … 214 230 initfile = optarg; 215 231 break; 232 case 'u': 233 sisnetuser = optarg; 234 break; 235 case 'l': 236 sisnetpassword = optarg; 237 break; 216 238 case 'c': /* password */ 217 239 password = optarg; 218 240 break; 219 241 case 'H': /* host */ 220 inhost = gethostbyname(optarg); 221 if(inhost == NULL) 222 { 223 fprintf(stderr, "ERROR: host %s unknown\n", optarg); 224 usage(-2); 225 } 226 memset((char *) &in_addr, 0x00, sizeof(in_addr)); 227 memcpy(&in_addr.sin_addr, inhost->h_addr, (size_t)inhost->h_length); 242 inhost = optarg; 228 243 break; 229 244 case 'P': /* port */ 230 in _port = atoi(optarg);231 if(in _port <= 1)232 { 233 fprintf(stderr, "ERROR: can't convert %s to a valid receiver port\n",245 inport = atoi(optarg); 246 if(inport <= 1 || inport > 65535) 247 { 248 fprintf(stderr, "ERROR: can't convert %s to a valid port number\n", 234 249 optarg); 235 250 usage(1); … … 244 259 break; 245 260 } 246 247 if(in_port <= 0)248 {249 in_port = SERV_TCP_PORT;250 }251 if(out_port <= 0)252 {253 out_port = NTRIP_PORT;254 }255 261 } 256 262 … … 279 285 } 280 286 281 switch (mode) 287 if(!outhost) outhost = NTRIP_CASTER; 288 if(!outport) outport = NTRIP_PORT; 289 290 switch(mode) 282 291 { 283 292 case INFILE: … … 304 313 } 305 314 break; 306 case TCPSOCKET: 307 { 308 in_addr.sin_family = AF_INET; 309 in_addr.sin_port = htons(in_port); 310 311 if((gpsfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) 315 case TCPSOCKET: case UDPSOCKET: case SISNET: 316 { 317 if(mode == SISNET) 318 { 319 if(!inhost) inhost = SISNET_SERVER; 320 if(!inport) inport = SISNET_PORT; 321 } 322 else 323 { 324 if(!inport) inport = SERV_TCP_PORT; 325 if(!inhost) inhost = "127.0.0.1"; 326 } 327 328 if(!(he = gethostbyname(inhost))) 329 { 330 fprintf(stderr, "ERROR: host %s unknown\n", inhost); 331 usage(-2); 332 } 333 334 if((gpsfd = socket(AF_INET, mode == UDPSOCKET ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0) 312 335 { 313 336 fprintf(stderr, "ERROR: can't create socket\n"); … … 315 338 } 316 339 317 printf("socket input: host = %s, port = %d%s%s\n", 318 inet_ntoa(in_addr.sin_addr), in_port, initfile ? ", initfile = " : "", 340 memset((char *) &addr, 0x00, sizeof(addr)); 341 memcpy(&addr.sin_addr, he->h_addr, (size_t)he->h_length); 342 addr.sin_family = AF_INET; 343 addr.sin_port = htons(inport); 344 345 printf("%s input: host = %s, port = %d%s%s\n", mode == SISNET ? "sisnet" 346 : "socket", 347 inet_ntoa(addr.sin_addr), inport, initfile ? ", initfile = " : "", 319 348 initfile ? initfile : ""); 320 349 321 if(connect(gpsfd, (struct sockaddr *) & in_addr, sizeof(in_addr)) < 0)350 if(connect(gpsfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) 322 351 { 323 352 fprintf(stderr, "ERROR: can't connect input to %s at port %d\n", 324 inet_ntoa( in_addr.sin_addr), in_port);353 inet_ntoa(addr.sin_addr), inport); 325 354 exit(1); 326 355 } 327 if(initfile )356 if(initfile && mode != SISNET) 328 357 { 329 358 char buffer[1024]; … … 355 384 } 356 385 } 386 if(mode == SISNET) 387 { 388 int i, j; 389 char buffer[1024]; 390 391 i = snprintf(buffer, sizeof(buffer), sisnetv3 ? "AUTH,%s,%s\r\n" : "AUTH,%s,%s", 392 sisnetuser,sisnetpassword); 393 if((send(gpsfd, buffer, (size_t)i, 0)) != i) 394 { 395 perror("ERROR: sending authentication"); 396 exit(1); 397 } 398 i = sisnetv3 ? 7 : 5; 399 if((j = recv(gpsfd, buffer, i, 0)) != i && strncmp("*AUTH", buffer, 5)) 400 { 401 fprintf(stderr, "ERROR: SISNeT connect failed:"); 402 for(i = 0; i < j; ++i) 403 { 404 if(buffer[i] != '\r' && buffer[i] != '\n') 405 { 406 fprintf(stderr, "%c", isprint(buffer[i]) ? buffer[i] : '.'); 407 } 408 } 409 fprintf(stderr, "\n"); 410 exit(1); 411 } 412 } 357 413 break; 358 414 default: … … 361 417 } 362 418 363 out_addr.sin_family = AF_INET;364 out_addr.sin_port = htons((u_short) (out_port));365 366 419 /* ----- main part ----- */ 367 420 while(1) 368 421 { 422 if(!(he = gethostbyname(outhost))) 423 { 424 fprintf(stderr, "ERROR: host %s unknown\n", outhost); 425 usage(-2); 426 } 427 369 428 /* create socket */ 370 429 if((sock_id = socket(AF_INET, SOCK_STREAM, 0)) < 0) 371 430 { 372 fprintf(stderr, "ERROR 431 fprintf(stderr, "ERROR: could not create socket\n"); 373 432 exit(2); 374 433 } 434 435 memset((char *) &addr, 0x00, sizeof(addr)); 436 memcpy(&addr.sin_addr, he->h_addr, (size_t)he->h_length); 437 addr.sin_family = AF_INET; 438 addr.sin_port = htons(outport); 439 375 440 /* connect to caster */ 376 441 fprintf(stderr, "caster output: host = %s, port = %d, mountpoint = %s\n", 377 inet_ntoa( out_addr.sin_addr), out_port, mountpoint);378 if(connect(sock_id, (struct sockaddr *) & out_addr, sizeof(out_addr)) < 0)442 inet_ntoa(addr.sin_addr), outport, mountpoint); 443 if(connect(sock_id, (struct sockaddr *) &addr, sizeof(addr)) < 0) 379 444 { 380 445 fprintf(stderr, "ERROR: can't connect output to %s at port %d\n", 381 inet_ntoa( out_addr.sin_addr), out_port);446 inet_ntoa(addr.sin_addr), outport); 382 447 close(sock_id); 383 448 exit(3); … … 420 485 } 421 486 printf("connection succesfull\n"); 422 send_receive_loop(sock_id, gpsfd );487 send_receive_loop(sock_id, gpsfd, mode == SISNET); 423 488 } 424 489 exit(0); 425 490 } 426 491 427 static void send_receive_loop(int sock, int fd )492 static void send_receive_loop(int sock, int fd, int sisnet) 428 493 { 429 494 char buffer[BUFSZ] = { 0 }; 495 char sisnetbackbuffer[200]; 430 496 int nBufferBytes = 0, i; 431 497 /* data transmission */ … … 433 499 while(1) 434 500 { 501 alarm(ALARMTIME); 502 435 503 if(!nBufferBytes) 436 504 { 505 if(sisnet) 506 { 507 int i; 508 /* a somewhat higher rate than 1 second to get really each block */ 509 /* means we need to skip double blocks sometimes */ 510 struct timeval tv = {0,700000}; 511 select(0, 0, 0, 0, &tv); 512 memcpy(sisnetbackbuffer, buffer, sizeof(sisnetbackbuffer)); 513 i = (sisnetv3 ? 5 : 3); 514 if((send(gpsfd, "MSG\r\n", i, 0)) != i) 515 { 516 perror("ERROR: sending data request"); 517 exit(1); 518 } 519 } 437 520 /* receiving data */ 438 521 nBufferBytes = read(fd, buffer, BUFSZ); … … 447 530 exit(1); 448 531 } 449 } 450 /* send data */ 451 if((i = send(sock, buffer, (size_t)nBufferBytes, MSG_DONTWAIT)) 452 != nBufferBytes) 453 { 454 if(i < 0 && errno != EAGAIN) 455 { 456 perror("WARNING: could not send data - retry connection"); 457 close(sock); 458 sleep(5); 459 return; 460 } 461 else if(i) 462 { 463 memmove(buffer, buffer+i, (size_t)(nBufferBytes-i)); 464 nBufferBytes -= i; 465 } 466 } 467 else 468 { 469 nBufferBytes = 0; 532 /* we can compare the whole buffer, as the additional bytes remain unchanged */ 533 if(!memcmp(sisnetbackbuffer, buffer, sizeof(sisnetbackbuffer))) 534 { 535 nBufferBytes = 0; 536 } 537 } 538 if(nBufferBytes) 539 { 540 /* send data */ 541 if((i = send(sock, buffer, (size_t)nBufferBytes, MSG_DONTWAIT)) 542 != nBufferBytes) 543 { 544 if(i < 0 && errno != EAGAIN) 545 { 546 perror("WARNING: could not send data - retry connection"); 547 close(sock); 548 sleep(5); 549 return; 550 } 551 else if(i) 552 { 553 memmove(buffer, buffer+i, (size_t)(nBufferBytes-i)); 554 nBufferBytes -= i; 555 } 556 } 557 else 558 { 559 nBufferBytes = 0; 560 } 470 561 } 471 562 } … … 618 709 fprintf(stderr, " -h|? print this help screen\n"); 619 710 fprintf(stderr, " -M <mode> sets the mode\n"); 620 fprintf(stderr, " (1=serial, 2=tcpsocket, 3=file )\n");711 fprintf(stderr, " (1=serial, 2=tcpsocket, 3=file, 4=sisnet, 5=udpsocket)\n"); 621 712 fprintf(stderr, " Mode = file:\n"); 622 713 fprintf(stderr, " -s file, simulate data stream by reading log file\n"); … … 628 719 fprintf(stderr, " default/current value is %s\n", ttyport); 629 720 fprintf(stderr, " (normally a symbolic link to /dev/tty\?\?)\n"); 630 fprintf(stderr, " Mode = tcpsocket :\n");631 fprintf(stderr, " -P receiver port (default: 1025)\n");632 fprintf(stderr, " -H hostname of TCP server (default: 127.0.0.1)\n");721 fprintf(stderr, " Mode = tcpsocket or udpsocket:\n"); 722 fprintf(stderr, " -P receiver port (default: %d)\n", SERV_TCP_PORT); 723 fprintf(stderr, " -H hostname of TCP server (default: %s)\n", SERV_HOST_ADDR); 633 724 fprintf(stderr, " -f initfile send to server\n"); 634 fprintf(stderr, " \n"); 725 fprintf(stderr, " Mode = sisnet:\n"); 726 fprintf(stderr, " -P receiver port (default: %d)\n", SISNET_PORT); 727 fprintf(stderr, " -H hostname of TCP server (default: %s)\n", SISNET_SERVER); 728 fprintf(stderr, " -u username\n"); 729 fprintf(stderr, " -l password\n"); 730 fprintf(stderr, " -V version [2.1 or 3.0] (default: 2.1)\n"); 731 fprintf(stderr, "\n"); 635 732 exit(rc); 636 733 }
Note:
See TracChangeset
for help on using the changeset viewer.