46 string::size_type position =
g_nmea.find(
'\n');
47 if( position ==
g_nmea.npos )
50 string candidate =
g_nmea.substr(0,position);
57 regex e(
"\\$GNGGA,(.*?),(.*?),.*?,(.*?),.*?,(.*?),.*?,(.*?),(.*?),");
58 if( std::regex_search (candidate, m, e) )
62 cout<<
"Lat:"<<m[2]<<
"Longi:"<<m[3]<<endl;
63 location.
nmea = candidate;
90 typedef u_long in_addr_t;
91 typedef size_t socklen_t;
94 fprintf(stderr,
"%s: %d\n", s, WSAGetLastError());
101 #include <arpa/inet.h> 102 #include <sys/socket.h> 103 #include <netinet/in.h> 106 #define closesocket(sock) close(sock) 107 #define ALARMTIME (2*60) 108 #define myperror perror 112 #define COMPILEDATE " built " __DATE__ 116 #define AGENTSTRING "NTRIP NtripClientPOSIX" 117 #define TIME_RESOLUTION 125 119 #define MAXDATASIZE 1000 123 static char datestr[] =
"$Date: 2009/09/11 09:49:19 $";
131 #define LONG_OPT(a) a 132 static struct option
opts[] = {
133 {
"bitrate", no_argument, 0,
'b'},
134 {
"data", required_argument, 0,
'd'},
135 {
"mountpoint", required_argument, 0,
'm'},
136 {
"initudp", no_argument, 0,
'I'},
137 {
"udpport", required_argument, 0,
'P'},
138 {
"server", required_argument, 0,
's'},
139 {
"password", required_argument, 0,
'p'},
140 {
"port", required_argument, 0,
'r'},
141 {
"proxyport", required_argument, 0,
'R'},
142 {
"proxyhost", required_argument, 0,
'S'},
143 {
"user", required_argument, 0,
'u'},
144 {
"nmea", required_argument, 0,
'n'},
145 {
"mode", required_argument, 0,
'M'},
146 {
"serdevice", required_argument, 0,
'D'},
147 {
"baud", required_argument, 0,
'B'},
148 {
"stopbits", required_argument, 0,
'T'},
149 {
"protocol", required_argument, 0,
'C'},
150 {
"parity", required_argument, 0,
'Y'},
151 {
"databits", required_argument, 0,
'A'},
152 {
"serlogfile", required_argument, 0,
'l'},
153 {
"help", no_argument, 0,
'h'},
156 #define ARGOPT "-d:m:bhp:r:s:u:n:S:R:M:IP:D:B:T:C:Y:A:l:" 159 #ifndef WINDOWSVERSION 163 int sig __attribute__((__unused__)))
169 fprintf(stderr,
"ERROR: more than %d seconds no activity\n",
ALARMTIME);
171 fprintf(stderr,
"ERROR: user break\n");
176 static void sighandler_int(
int sig __attribute__((__unused__)))
189 const char *h =
"0123456789abcdef";
190 static char buf[128];
192 char *bufend = buf +
sizeof(buf) - 3;
194 while(*req && urlenc < bufend)
197 || *req ==
'-' || *req ==
'_' || *req ==
'.')
202 *urlenc++ = h[*req >> 4];
203 *urlenc++ = h[*req & 0x0f];
211 static const char *
geturl(
const char *url,
struct Args *args)
213 static char buf[1000];
214 static char *Buffer = buf;
215 static char *Bufend = buf+
sizeof(buf);
216 const char *h =
"0123456789abcdef";
218 if(strncmp(
"ntrip:", url, 6))
219 return "URL must start with 'ntrip:'.";
222 if(*url !=
'@' && *url !=
'/')
228 while(*url && *url !=
'@' && *url !=
';' && *url !=
'/' && Buffer != Bufend)
229 *(Buffer++) = *(url++);
233 while(*url && *url !=
'@' && *url !=
'/' && Buffer != Bufend)
235 if(isalnum(*url) || *url ==
'-' || *url ==
'_' || *url ==
'.')
240 *Buffer++ = h[*url >> 4];
241 *Buffer++ = h[*url & 0x0f];
246 if(Buffer == args->
data)
247 return "Mountpoint required.";
248 else if(Buffer >= Bufend-1)
249 return "Parsing buffer too short.";
257 while(*url && *url !=
'@' && *url !=
';' && *url !=
':' && Buffer != Bufend)
258 *(Buffer++) = *(url++);
259 if(Buffer == args->
user)
260 return "Username cannot be empty.";
261 else if(Buffer >= Bufend-1)
262 return "Parsing buffer too short.";
265 if(*url ==
':') ++url;
268 while(*url && *url !=
'@' && *url !=
';' && Buffer != Bufend)
269 *(Buffer++) = *(url++);
271 return "Password cannot be empty.";
272 else if(Buffer >= Bufend-1)
273 return "Parsing buffer too short.";
280 if(*url !=
'@' && *url !=
':')
283 while(*url && *url !=
'@' && *url !=
':' && *url !=
';' && Buffer != Bufend)
284 *(Buffer++) = *(url++);
285 if(Buffer == args->
server)
286 return "Servername cannot be empty.";
287 else if(Buffer >= Bufend-1)
288 return "Parsing buffer too short.";
296 while(*url && *url !=
'@' && *url !=
';' && Buffer != Bufend)
297 *(Buffer++) = *(url++);
298 if(Buffer == args->
port)
299 return "Port cannot be empty.";
300 else if(Buffer >= Bufend-1)
301 return "Parsing buffer too short.";
309 while(*url && *url !=
':' && *url !=
';' && Buffer != Bufend)
310 *(Buffer++) = *(url++);
312 return "Proxy servername cannot be empty.";
313 else if(Buffer >= Bufend-1)
314 return "Parsing buffer too short.";
321 while(*url && *url !=
';' && Buffer != Bufend)
322 *(Buffer++) = *(url++);
324 return "Proxy port cannot be empty.";
325 else if(Buffer >= Bufend-1)
326 return "Parsing buffer too short.";
338 return *url ?
"Garbage at end of server string." : 0;
348 args->
server =
"rtk.ntrip.qxwz.com";
372 switch((getoptr = getopt(argc, argv,
ARGOPT)))
374 switch((getoptr = getopt_long(argc, argv,
ARGOPT,
opts, 0)))
377 case 's': args->
server = optarg;
break;
378 case 'u': args->
user = optarg;
break;
379 case 'p': args->
password = optarg;
break;
381 fprintf(stderr,
"Option -d or --data is deprecated. Use -m instead.\n");
383 if(optarg && *optarg ==
'?')
390 int i = strtol(optarg, 0, 10);
407 fprintf(stderr,
"Baudrate '%s' unknown\n", optarg);
418 fprintf(stderr,
"Stopbits '%s' unknown\n", optarg);
429 fprintf(stderr,
"Databits '%s' unknown\n", optarg);
439 fprintf(stderr,
"Protocol '%s' unknown\n", optarg);
450 fprintf(stderr,
"Parity '%s' unknown\n", optarg);
455 case 'D': args->
serdevice = optarg;
break;
457 case 'I': args->
initudp = 1;
break;
458 case 'P': args->
udpport = strtol(optarg, 0, 10);
break;
459 case 'n': args->
nmea = optarg;
break;
460 case 'b': args->
bitrate = 1;
break;
461 case 'h':
help=1;
break;
462 case 'r': args->
port = optarg;
break;
463 case 'S': args->
proxyhost = optarg;
break;
464 case 'R': args->
proxyport = optarg;
break;
467 if (!strcmp(optarg,
"n") || !strcmp(optarg,
"ntrip1"))
469 else if(!strcmp(optarg,
"h") || !strcmp(optarg,
"http"))
471 else if(!strcmp(optarg,
"r") || !strcmp(optarg,
"rtsp"))
473 else if(!strcmp(optarg,
"u") || !strcmp(optarg,
"udp"))
475 else if(!strcmp(optarg,
"a") || !strcmp(optarg,
"auto"))
477 else args->
mode = atoi(optarg);
480 fprintf(stderr,
"Mode %s unknown\n", optarg);
487 if((err =
geturl(optarg, args)))
489 fprintf(stderr,
"%s\n\n", err);
496 }
while(getoptr != -1 && res);
514 fprintf(stderr,
"Version %s (%s) GPL" COMPILEDATE "\nUsage:\n%s -s server -u user ...\n" 515 " -m " LONG_OPT(
"--mountpoint ")
"the requested data set or sourcetable filtering criteria\n" 516 " -s " LONG_OPT(
"--server ")
"the server name or address\n" 517 " -p " LONG_OPT(
"--password ")
"the login password\n" 518 " -r " LONG_OPT(
"--port ")
"the server port number (default 2101)\n" 519 " -u " LONG_OPT(
"--user ")
"the user name\n" 520 " -M " LONG_OPT(
"--mode ")
"mode for data request\n" 521 " Valid modes are:\n" 522 " 1, h, http NTRIP Version 2.0 Caster in TCP/IP mode\n" 523 " 2, r, rtsp NTRIP Version 2.0 Caster in RTSP/RTP mode\n" 524 " 3, n, ntrip1 NTRIP Version 1.0 Caster\n" 525 " 4, a, auto automatic detection (default)\n" 526 " 5, u, udp NTRIP Version 2.0 Caster in UDP mode\n" 527 "or using an URL:\n%s ntrip:mountpoint[/user[:password]][@[server][:port][@proxyhost[:proxyport]]][;nmea]\n" 528 "\nExpert options:\n" 529 " -n " LONG_OPT(
"--nmea ")
"NMEA string for sending to server\n" 530 " -b " LONG_OPT(
"--bitrate ")
"output bitrate\n" 531 " -I " LONG_OPT(
"--initudp ")
"send initial UDP packet for firewall handling\n" 532 " -P " LONG_OPT(
"--udpport ")
"set the local UDP port\n" 533 " -S " LONG_OPT(
"--proxyhost ")
"proxy name or address\n" 534 " -R " LONG_OPT(
"--proxyport ")
"proxy port, optional (default 2101)\n" 535 "\nSerial input/output:\n" 536 " -D " LONG_OPT(
"--serdevice ")
"serial device for output\n" 537 " -B " LONG_OPT(
"--baud ")
"baudrate for serial device\n" 538 " -T " LONG_OPT(
"--stopbits ")
"stopbits for serial device\n" 539 " -C " LONG_OPT(
"--protocol ")
"protocol for serial device\n" 540 " -Y " LONG_OPT(
"--parity ")
"parity for serial device\n" 541 " -A " LONG_OPT(
"--databits ")
"databits for serial device\n" 542 " -l " LONG_OPT(
"--serlogfile ")
"logfile for serial data\n" 550 'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
551 'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
'a',
'b',
'c',
'd',
'e',
'f',
552 'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
553 'w',
'x',
'y',
'z',
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'+',
'/' 558 static int encode(
char *buf,
int size,
const char *user,
const char *pwd)
560 unsigned char inbuf[3];
562 int i, sep = 0, fill = 0, bytes = 0;
567 while(i < 3 && *user) inbuf[i++] = *(user++);
568 if(i < 3 && !sep) {inbuf[i++] =
':'; ++sep; }
569 while(i < 3 && *pwd) inbuf[i++] = *(pwd++);
570 while(i < 3) {inbuf[i++] = 0; ++fill; }
572 *(out++) = encodingTable[(inbuf [0] & 0xFC) >> 2];
574 *(out++) = encodingTable[((inbuf [0] & 0x03) << 4)
575 | ((inbuf [1] & 0xF0) >> 4)];
581 *(out++) = encodingTable[((inbuf [1] & 0x0F) << 2)
582 | ((inbuf [2] & 0xC0) >> 6)];
589 *(out++) = encodingTable[inbuf [2] & 0x3F];
615 char nmeabuffer[200] =
"$GPGGA,";
616 size_t nmeabufpos = 0;
617 size_t nmeastarpos = 0;
625 fprintf(stderr,
"%s\n", e);
633 fprintf(stderr,
"Could not open serial logfile.\n");
644 struct sockaddr_in their_addr;
647 const char *server, *port, *proxyserver = 0;
653 #ifdef WINDOWSVERSION 654 Sleep(sleeptime*1000);
664 #ifndef WINDOWSVERSION 670 if((i = strtol(args->
port, &b, 10)) && (!b || !*b))
672 else if(!(se = getservbyname(args->
port, 0)))
674 fprintf(stderr,
"Can't resolve port %s.", args->
port);
679 p = ntohs(se->s_port);
681 if(!args->
stop && !error)
683 snprintf(proxyport,
sizeof(proxyport),
"%d", p);
685 proxyserver = args->
server;
694 if(!args->
stop && !error)
696 memset(&their_addr, 0,
sizeof(
struct sockaddr_in));
697 if((i = strtol(port, &b, 10)) && (!b || !*b))
698 their_addr.sin_port = htons(i);
699 else if(!(se = getservbyname(port, 0)))
701 fprintf(stderr,
"Can't resolve port %s.", port);
706 their_addr.sin_port = se->s_port;
708 if(!args->
stop && !error)
710 if(!(he=gethostbyname(server)))
712 fprintf(stderr,
"Server name lookup failed for '%s'.\n", server);
715 else if((sockfd = socket(AF_INET, (args->
mode ==
UDP ? SOCK_DGRAM :
716 SOCK_STREAM), 0)) == -1)
723 their_addr.sin_family = AF_INET;
724 their_addr.sin_addr = *((
struct in_addr *)he->h_addr);
728 if(!args->
stop && !error)
732 unsigned int session;
747 rtpbuf[2] = (seq>>8)&0xFF;
748 rtpbuf[3] = (seq)&0xFF;
749 rtpbuf[4] = (tim>>24)&0xFF;
750 rtpbuf[5] = (tim>>16)&0xFF;
751 rtpbuf[6] = (tim>>8)&0xFF;
752 rtpbuf[7] = (tim)&0xFF;
754 rtpbuf[8] = (session>>24)&0xFF;
755 rtpbuf[9] = (session>>16)&0xFF;
756 rtpbuf[10] = (session>>8)&0xFF;
757 rtpbuf[11] = (session)&0xFF;
760 j = snprintf(rtpbuf+i,
sizeof(rtpbuf)-i-40,
761 "GET /%s HTTP/1.1\r\n" 763 "Ntrip-Version: Ntrip/2.0\r\n" 764 "User-Agent: %s/%s\r\n" 766 "Connection: close%s",
768 args->
nmea ?
"Ntrip-GGA: " :
"", args->
nmea ? args->
nmea :
"",
769 args->
nmea ?
"\r\n" :
"",
770 (*args->
user || *args->
password) ?
"\r\nAuthorization: Basic " :
"");
772 if(i > (
int)
sizeof(rtpbuf)-40 || j < 0)
774 fprintf(stderr,
"Requested data too long\n");
780 if(i > (
int)
sizeof(rtpbuf)-4)
782 fprintf(stderr,
"Username and/or password too long\n");
787 struct sockaddr_in local;
797 memset(&local, 0,
sizeof(local));
798 local.sin_family = AF_INET;
799 local.sin_port = htons(args->
udpport);
800 local.sin_addr.s_addr = htonl(INADDR_ANY);
804 if((bind(sockfd, (
struct sockaddr *)&local, len)) < 0)
809 else if(connect(sockfd, (
struct sockaddr *)&their_addr,
810 sizeof(
struct sockaddr)) == -1)
815 else if(send(sockfd, rtpbuf, i, 0) != i)
817 myperror(
"Could not send UDP packet");
822 if((numbytes=recv(sockfd, rtpbuf,
sizeof(rtpbuf)-1, 0)) > 0)
824 int sn = 0x10000, ts=0;
827 rtpbuf[numbytes] = 0;
828 if(numbytes > 17+12 &&
829 (!strncmp(rtpbuf+12,
"HTTP/1.1 200 OK\r\n", 17) ||
830 !strncmp(rtpbuf+12,
"HTTP/1.0 200 OK\r\n", 17)))
832 const char *sessioncheck =
"session: ";
833 const char *datacheck =
"Content-Type: gnss/data\r\n";
834 const char *sourcetablecheck =
"Content-Type: gnss/sourcetable\r\n";
835 const char *contentlengthcheck =
"Content-Length: ";
836 const char *httpresponseend =
"\r\n\r\n";
837 int contentlength = 0, httpresponselength = 0;
839 int l = strlen(datacheck)-1;
841 for(i = 12; j != l && i < numbytes-l; ++i)
843 for(j = 0; j < l && rtpbuf[i+j] == datacheck[j]; ++j)
849 l = strlen(sessioncheck)-1;
851 for(i = 12; j != l && i < numbytes-l; ++i)
853 for(j = 0; j < l && tolower(rtpbuf[i+j]) == sessioncheck[j]; ++j)
860 while(i < numbytes && rtpbuf[i] >=
'0' && rtpbuf[i] <=
'9')
861 session = session * 10 + rtpbuf[i++]-
'0';
862 if(rtpbuf[i] !=
'\r')
864 fprintf(stderr,
"Could not extract session number\n");
872 l = strlen(sourcetablecheck)-1;
874 for(i = 12; j != l && i < numbytes-l; ++i)
876 for(j = 0; j < l && rtpbuf[i+j] == sourcetablecheck[j]; ++j)
881 fprintf(stderr,
"No 'Content-Type: gnss/data' or" 882 " 'Content-Type: gnss/sourcetable' found\n");
888 l = strlen(httpresponseend)-1;
890 for(i = 12; j != l && i < numbytes-l; ++i)
892 for(j = 0; j < l && rtpbuf[i+j] == httpresponseend[j]; ++j)
897 httpresponselength = i+3-12;
900 l = strlen(contentlengthcheck)-1;
902 for(i = 12; j != l && i < numbytes-l; ++i)
904 for(j = 0; j < l && rtpbuf[i+j] == contentlengthcheck[j]; ++j)
911 while(i < numbytes && rtpbuf[i] >=
'0' && rtpbuf[i] <=
'9')
912 contentlength = contentlength * 10 + rtpbuf[i++]-
'0';
913 if(rtpbuf[i] ==
'\r')
915 contentlength += httpresponselength;
918 fwrite(rtpbuf+12, (
size_t)numbytes-12, 1, stdout);
919 if((contentlength -= (numbytes-12)) == 0)
925 numbytes = recv(sockfd, rtpbuf,
sizeof(rtpbuf), 0);
927 }
while((numbytes >12) && (!args->
stop));
931 fprintf(stderr,
"Could not extract content length\n");
941 fprintf(stderr,
"Could not get the requested data: ");
942 for(k = 12; k < numbytes && rtpbuf[k] !=
'\n' && rtpbuf[k] !=
'\r'; ++k)
944 fprintf(stderr,
"%c", isprint(rtpbuf[k]) ? rtpbuf[k] :
'.');
946 fprintf(stderr,
"\n");
949 while(!args->
stop && !error)
951 struct timeval tv = {1,0};
957 FD_SET(sockfd, &fdr);
958 FD_SET(sockfd, &fde);
959 if(select(sockfd+1,&fdr,0,&fde,&tv) < 0)
961 fprintf(stderr,
"Select problem.\n");
965 i = recv(sockfd, rtpbuf,
sizeof(rtpbuf), 0);
966 #ifndef WINDOWSVERSION 969 if(i >= 12 && (
unsigned char)rtpbuf[0] == (2 << 6)
970 && rtpbuf[1] >= 96 && rtpbuf[1] <= 98)
975 u = ((
unsigned char)rtpbuf[2]<<8)+(
unsigned char)rtpbuf[3];
976 v = ((
unsigned char)rtpbuf[4]<<24)+((
unsigned char)rtpbuf[5]<<16)
977 +((
unsigned char)rtpbuf[6]<<8)+(
unsigned char)rtpbuf[7];
978 w = ((
unsigned char)rtpbuf[8]<<24)+((
unsigned char)rtpbuf[9]<<16)
979 +((
unsigned char)rtpbuf[10]<<8)+(
unsigned char)rtpbuf[11];
981 if(sn == 0x10000) {sn = u-1;ts=v-1;}
982 else if(u < -30000 && sn > 30000) sn -= 0xFFFF;
983 if(session != w || ts > v)
985 fprintf(stderr,
"Illegal UDP data received.\n");
992 fprintf(stderr,
"Connection closed.\n");
996 else if((rtpbuf[1] == 96) && (i>12))
998 fwrite(rtpbuf+12, (
size_t)i-12, 1, stdout);
1012 rtpbuf[2] = (seq>>8)&0xFF;
1013 rtpbuf[3] = (seq)&0xFF;
1014 rtpbuf[4] = (tim>>24)&0xFF;
1015 rtpbuf[5] = (tim>>16)&0xFF;
1016 rtpbuf[6] = (tim>>8)&0xFF;
1017 rtpbuf[7] = (tim)&0xFF;
1019 rtpbuf[8] = (session>>24)&0xFF;
1020 rtpbuf[9] = (session>>16)&0xFF;
1021 rtpbuf[10] = (session>>8)&0xFF;
1022 rtpbuf[11] = (session)&0xFF;
1026 if(send(sockfd, rtpbuf, 12, 0) != 12)
1035 fprintf(stderr,
"Illegal UDP header.\n");
1046 rtpbuf[2] = (seq>>8)&0xFF;
1047 rtpbuf[3] = (seq)&0xFF;
1048 rtpbuf[4] = (tim>>24)&0xFF;
1049 rtpbuf[5] = (tim>>16)&0xFF;
1050 rtpbuf[6] = (tim>>8)&0xFF;
1051 rtpbuf[7] = (tim)&0xFF;
1053 rtpbuf[8] = (session>>24)&0xFF;
1054 rtpbuf[9] = (session>>16)&0xFF;
1055 rtpbuf[10] = (session>>8)&0xFF;
1056 rtpbuf[11] = (session)&0xFF;
1058 send(sockfd, rtpbuf, 12, 0);
1065 struct sockaddr_in local;
1071 if((sockudp = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
1076 if(!args->
stop && !error)
1079 memset(&local, 0,
sizeof(local));
1080 local.sin_family = AF_INET;
1081 local.sin_port = htons(args->
udpport);
1082 local.sin_addr.s_addr = htonl(INADDR_ANY);
1083 len =
sizeof(local);
1085 if((bind(sockudp, (
struct sockaddr *)&local, len)) < 0)
1090 else if((getsockname(sockudp, (
struct sockaddr*)&local, &len)) == -1)
1095 else if(connect(sockfd, (
struct sockaddr *)&their_addr,
1096 sizeof(
struct sockaddr)) == -1)
1101 localport = ntohs(local.sin_port);
1103 if(!args->
stop && !error)
1106 "SETUP rtsp://%s%s%s/%s RTSP/1.0\r\n" 1108 "Ntrip-Version: Ntrip/2.0\r\n" 1109 "Ntrip-Component: Ntripclient\r\n" 1110 "User-Agent: %s/%s\r\n" 1112 "Transport: RTP/GNSS;unicast;client_port=%u%s",
1113 args->
server, proxyserver ?
":" :
"", proxyserver ? args->
port :
"",
1115 args->
nmea ?
"Ntrip-GGA: " :
"", args->
nmea ? args->
nmea :
"",
1116 args->
nmea ?
"\r\n" :
"",
1118 (*args->
user || *args->
password) ?
"\r\nAuthorization: Basic " :
"");
1121 fprintf(stderr,
"Requested data too long\n");
1127 fprintf(stderr,
"Username and/or password too long\n");
1135 if(!args->
stop && !error)
1137 if(send(sockfd, buf, (
size_t)i, 0) != i)
1142 else if((numbytes=recv(sockfd, buf,
MAXDATASIZE-1, 0)) == -1)
1147 else if(numbytes >= 17 && !strncmp(buf,
"RTSP/1.0 200 OK\r\n", 17))
1149 int serverport = 0, session = 0;
1150 const char *portcheck =
"server_port=";
1151 const char *sessioncheck =
"session: ";
1152 int l = strlen(portcheck)-1;
1154 for(i = 0; j != l && i < numbytes-l; ++i)
1156 for(j = 0; j < l && tolower(buf[i+j]) == portcheck[j]; ++j)
1161 fprintf(stderr,
"No server port number found\n");
1167 while(i < numbytes && buf[i] >=
'0' && buf[i] <=
'9')
1168 serverport = serverport * 10 + buf[i++]-
'0';
1169 if(buf[i] !=
'\r' && buf[i] !=
';')
1171 fprintf(stderr,
"Could not extract server port\n");
1175 if(!args->
stop && !error)
1177 l = strlen(sessioncheck)-1;
1179 for(i = 0; j != l && i < numbytes-l; ++i)
1181 for(j = 0; j < l && tolower(buf[i+j]) == sessioncheck[j]; ++j)
1186 fprintf(stderr,
"No session number found\n");
1192 while(i < numbytes && buf[i] >=
'0' && buf[i] <=
'9')
1193 session = session * 10 + buf[i++]-
'0';
1196 fprintf(stderr,
"Could not extract session number\n");
1203 printf(
"Sending initial UDP packet\n");
1204 struct sockaddr_in casterRTP;
1207 rtpbuffer[0] = (2<<6);
1218 rtpbuffer[8] = (session>>24)&0xFF;
1219 rtpbuffer[9] = (session>>16)&0xFF;
1220 rtpbuffer[10] = (session>>8)&0xFF;
1221 rtpbuffer[11] = (session)&0xFF;
1223 memset(&casterRTP, 0,
sizeof(casterRTP));
1224 casterRTP.sin_family = AF_INET;
1225 casterRTP.sin_port = htons(serverport);
1226 casterRTP.sin_addr = *((
struct in_addr *)he->h_addr);
1228 if((i = sendto(sockudp, rtpbuffer, 12, 0,
1229 (
struct sockaddr *) &casterRTP,
sizeof(casterRTP))) != 12)
1230 myperror(
"WARNING: could not send initial UDP packet");
1232 if(!args->
stop && !error)
1235 "PLAY rtsp://%s%s%s/%s RTSP/1.0\r\n" 1239 args->
server, proxyserver ?
":" :
"", proxyserver ? args->
port :
"",
1240 args->
data, cseq++, session);
1244 fprintf(stderr,
"Requested data too long\n");
1247 else if(send(sockfd, buf, (
size_t)i, 0) != i)
1252 else if((numbytes=recv(sockfd, buf,
MAXDATASIZE-1, 0)) != -1)
1254 if(numbytes >= 17 && !strncmp(buf,
"RTSP/1.0 200 OK\r\n", 17))
1258 struct sockaddr_in addrRTP;
1259 #ifdef WINDOWSVERSION 1260 u_long blockmode = 1;
1261 if(ioctlsocket(sockudp, FIONBIO, &blockmode)
1262 || ioctlsocket(sockfd, FIONBIO, &blockmode))
1264 if(fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0
1265 || fcntl(sockudp, F_SETFL, O_NONBLOCK) < 0)
1268 fprintf(stderr,
"Could not set nonblocking mode\n");
1273 memset(&addrRTP, 0,
sizeof(addrRTP));
1274 addrRTP.sin_family = AF_INET;
1275 addrRTP.sin_port = htons(serverport);
1276 their_addr.sin_addr = *((
struct in_addr *)he->h_addr);
1277 len =
sizeof(addrRTP);
1279 while(!args->
stop && !error)
1281 char rtpbuffer[1526];
1282 struct timeval tv = {1,0};
1289 FD_SET(sockudp, &fdr);
1290 FD_SET(sockfd, &fdr);
1291 FD_SET(sockudp, &fde);
1292 FD_SET(sockfd, &fde);
1293 if(select((sockudp>sockfd?sockudp:sockfd)+1,
1294 &fdr,0,&fde,&tv) < 0)
1296 fprintf(stderr,
"Select problem.\n");
1300 i = recvfrom(sockudp, rtpbuffer,
sizeof(rtpbuffer), 0,
1301 (
struct sockaddr*) &addrRTP, &len);
1302 #ifndef WINDOWSVERSION 1305 if(i >= 12+1 && (
unsigned char)rtpbuffer[0] == (2 << 6) && rtpbuffer[1] == 0x60)
1308 u = ((
unsigned char)rtpbuffer[2]<<8)+(
unsigned char)rtpbuffer[3];
1309 v = ((
unsigned char)rtpbuffer[4]<<24)+((
unsigned char)rtpbuffer[5]<<16)
1310 +((
unsigned char)rtpbuffer[6]<<8)+(
unsigned char)rtpbuffer[7];
1311 w = ((
unsigned char)rtpbuffer[8]<<24)+((
unsigned char)rtpbuffer[9]<<16)
1312 +((
unsigned char)rtpbuffer[10]<<8)+(
unsigned char)rtpbuffer[11];
1317 if(u < -30000 && sn > 30000) sn -= 0xFFFF;
1318 if(session != w || ts > v)
1320 fprintf(stderr,
"Illegal UDP data received.\n");
1324 fwrite(rtpbuffer+12, (
size_t)i-12, 1, stdout);
1329 "GET_PARAMETER rtsp://%s%s%s/%s RTSP/1.0\r\n" 1333 args->
server, proxyserver ?
":" :
"", proxyserver
1334 ? args->
port :
"", args->
data, cseq++, session);
1337 fprintf(stderr,
"Requested data too long\n");
1340 else if(send(sockfd, buf, (
size_t)i, 0) != i)
1356 fprintf(stderr,
"Illegal UDP header.\n");
1362 #ifdef WINDOWSVERSION 1363 if(WSAGetLastError() != WSAEWOULDBLOCK)
1368 fprintf(stderr,
"Control connection closed\n");
1374 fprintf(stderr,
"Control connection read error\n");
1380 "TEARDOWN rtsp://%s%s%s/%s RTSP/1.0\r\n" 1384 args->
server, proxyserver ?
":" :
"", proxyserver ? args->
port :
"",
1385 args->
data, cseq++, session);
1389 fprintf(stderr,
"Requested data too long\n");
1392 else if(send(sockfd, buf, (
size_t)i, 0) != i)
1400 fprintf(stderr,
"Could not start data stream.\n");
1407 fprintf(stderr,
"Could not setup initial control connection.\n");
1416 if(connect(sockfd, (
struct sockaddr *)&their_addr,
1417 sizeof(
struct sockaddr)) == -1)
1422 if(!args->
stop && !error)
1427 "GET %s%s%s%s/ HTTP/1.1\r\n" 1429 "User-Agent: %s/%s\r\n" 1430 "Connection: close\r\n" 1432 , proxyserver ?
"http://" :
"", proxyserver ? proxyserver :
"",
1433 proxyserver ?
":" :
"", proxyserver ? proxyport :
"",
1439 const char *nmeahead = (args->
nmea && args->
mode ==
HTTP) ? args->
nmea : 0;
1442 "GET %s%s%s%s/%s HTTP/1.1\r\n" 1444 "User-Agent: %s/%s\r\n" 1446 "Connection: close%s" 1447 , proxyserver ?
"http://" :
"", proxyserver ? proxyserver :
"",
1448 proxyserver ?
":" :
"", proxyserver ? proxyport :
"",
1450 args->
mode ==
NTRIP1 ?
"" :
"Ntrip-Version: Ntrip/2.0\r\n",
1452 nmeahead ?
"Ntrip-GGA: " :
"", nmeahead ? nmeahead :
"",
1453 nmeahead ?
"\r\n" :
"",
1454 (*args->
user || *args->
password) ?
"\r\nAuthorization: Basic " :
"");
1457 fprintf(stderr,
"Requested data too long\n");
1465 fprintf(stderr,
"Username and/or password too long\n");
1474 if(args->
nmea && !nmeahead)
1481 fprintf(stderr,
"NMEA string too long\n");
1489 if(!args->
stop && !error)
1491 if(send(sockfd, buf, (
size_t)i, 0) != i)
1496 else if(args->
data && *args->
data !=
'%')
1500 int starttime = time(0);
1501 int lastout = starttime;
1507 while(!args->
stop && !error &&
1508 (numbytes=recv(sockfd, buf,
MAXDATASIZE-1, 0)) > 0)
1510 #ifndef WINDOWSVERSION 1516 if( numbytes > 17 &&
1517 !strstr(buf,
"ICY 200 OK") &&
1518 (!strncmp(buf,
"HTTP/1.1 200 OK\r\n", 17) ||
1519 !strncmp(buf,
"HTTP/1.0 200 OK\r\n", 17)) )
1521 const char *datacheck =
"Content-Type: gnss/data\r\n";
1522 const char *chunkycheck =
"Transfer-Encoding: chunked\r\n";
1523 int l = strlen(datacheck)-1;
1525 for(i = 0; j != l && i < numbytes-l; ++i)
1527 for(j = 0; j < l && buf[i+j] == datacheck[j]; ++j)
1532 fprintf(stderr,
"No 'Content-Type: gnss/data' found\n");
1535 l = strlen(chunkycheck)-1;
1537 for(i = 0; j != l && i < numbytes-l; ++i)
1539 for(j = 0; j < l && buf[i+j] == chunkycheck[j]; ++j)
1545 else if(!strstr(buf,
"ICY 200 OK"))
1547 fprintf(stderr,
"Could not get the requested data: ");
1548 for(k = 0; k < numbytes && buf[k] !=
'\n' && buf[k] !=
'\r'; ++k)
1550 fprintf(stderr,
"%c", isprint(buf[k]) ? buf[k] :
'.');
1552 fprintf(stderr,
"\n");
1557 fprintf(stderr,
"NTRIP version 2 HTTP connection failed%s.\n",
1558 args->
mode ==
AUTO ?
", falling back to NTRIP1" :
"");
1567 char *ep = strstr(buf,
"\r\n\r\n");
1568 if(!ep || ep+4 == buf+numbytes)
1571 memmove(buf, ep, numbytes-(ep-buf));
1572 numbytes -= (ep-buf);
1580 while(!args->
stop && !cstop && !error && pos < numbytes)
1589 if(i >=
'0' && i <=
'9') chunksize = chunksize*16+i-
'0';
1590 else if(i >=
'a' && i <=
'f') chunksize = chunksize*16+i-
'a'+10;
1591 else if(i >=
'A' && i <=
'F') chunksize = chunksize*16+i-
'A'+10;
1592 else if(i ==
'\r') ++chunkymode;
1593 else if(i ==
';') chunkymode = 5;
1597 if(buf[pos++] ==
'\n') chunkymode = chunksize ? 4 : 1;
1602 if(i > chunksize) i = chunksize;
1606 while(i > ofs && !cstop && !args->
stop && !error)
1611 fprintf(stderr,
"Could not access serial device\n");
1619 fwrite(buf+pos, (
size_t)i, 1, stdout);
1627 if(i ==
'\r') chunkymode = 3;
1633 fprintf(stderr,
"Error in chunky transfer encoding\n");
1639 totalbytes += numbytes;
1643 while(numbytes > ofs && !args->
stop)
1648 fprintf(stderr,
"Could not access serial device\n");
1656 fwrite(buf, (
size_t)numbytes, 1, stdout);
1662 starttime = time(0);
1663 lastout = starttime;
1668 while(doloop && !args->
stop)
1673 fprintf(stderr,
"Could not access serial device\n");
1679 if(i < 200) doloop = 0;
1682 fwrite(buf, i, 1, ser);
1689 if(nmeabuffer[nmeabufpos] != buf[j])
1691 if(nmeabufpos) nmeabufpos = 0;
1700 else if((nmeastarpos && nmeabufpos == nmeastarpos + 3)
1701 || buf[j] ==
'\r' || buf[j] ==
'\n')
1704 nmeabuffer[nmeabufpos++] =
'\r';
1705 nmeabuffer[nmeabufpos++] =
'\n';
1706 if(send(sockfd, nmeabuffer, nmeabufpos, 0)
1709 fprintf(stderr,
"Could not send NMEA\n");
1714 else if(nmeabufpos >
sizeof(nmeabuffer)-10 ||
1719 if(buf[j] ==
'*') nmeastarpos = nmeabufpos;
1720 nmeabuffer[nmeabufpos++] = buf[j++];
1729 if(t > lastout + 60)
1732 fprintf(stderr,
"Bitrate is %dbyte/s (%d seconds accumulated).\n",
1733 totalbytes/(t-starttime), t-starttime);
1741 while(!args->
stop && (numbytes=recv(sockfd, buf,
MAXDATASIZE-1, 0)) > 0)
1743 #ifndef WINDOWSVERSION 1746 fwrite(buf, (
size_t)numbytes, 1, stdout);
1755 }
while(args->
data && *args->
data !=
'%' && !args->
stop);
static int encode(char *buf, int size, const char *user, const char *pwd)
void appendNMEA(char *buf, int i)
int SerialRead(struct serial *sn, char *buffer, size_t size)
void init(const M_string &remappings)
static enum SerialProtocol SerialGetProtocol(const char *buf, int *ressize)
const char * SerialInit(struct serial *sn, const char *Device, enum SerialBaud Baud, enum SerialStopbits StopBits, enum SerialProtocol Protocol, enum SerialParity Parity, enum SerialDatabits DataBits, int dowrite)
static const char encodingTable[64]
void ntrip_client(Args *const args)
enum SerialProtocol protocol
enum SerialDatabits databits
static const char * encodeurl(const char *req)
static char revisionstr[]
static const char * geturl(const char *url, struct Args *args)
void SerialFree(struct serial *sn)
static void sighandler_alarm(int sig)
#define closesocket(sock)
enum SerialStopbits stopbits
static int getargs(int argc, char **argv, struct Args *args)
int SerialWrite(struct serial *sn, const char *buffer, size_t size)
static enum SerialParity SerialGetParity(const char *buf, int *ressize)
static struct option opts[]