ntripclient.c 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737
  1. /*
  2. NTRIP client for POSIX.
  3. $Id: ntripclient.c,v 1.51 2009/09/11 09:49:19 stoecker Exp $
  4. Copyright (C) 2003-2008 by Dirk Stöcker <[email protected]>
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. or read http://www.gnu.org/licenses/gpl.txt
  17. */
  18. #include <ctype.h>
  19. #include <getopt.h>
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <errno.h>
  23. #include <string.h>
  24. #include <time.h>
  25. #include "serial.c"
  26. #ifdef WINDOWSVERSION
  27. #include <winsock.h>
  28. typedef SOCKET sockettype;
  29. typedef u_long in_addr_t;
  30. typedef size_t socklen_t;
  31. void myperror(char *s)
  32. {
  33. fprintf(stderr, "%s: %d\n", s, WSAGetLastError());
  34. }
  35. #else
  36. typedef int sockettype;
  37. #include <signal.h>
  38. #include <fcntl.h>
  39. #include <unistd.h>
  40. #include <arpa/inet.h>
  41. #include <sys/socket.h>
  42. #include <netinet/in.h>
  43. #include <netdb.h>
  44. #define closesocket(sock) close(sock)
  45. #define ALARMTIME (2*60)
  46. #define myperror perror
  47. #endif
  48. #ifndef COMPILEDATE
  49. #define COMPILEDATE " built " __DATE__
  50. #endif
  51. /* The string, which is send as agent in HTTP request */
  52. #define AGENTSTRING "NTRIP NtripClientPOSIX"
  53. #define TIME_RESOLUTION 125
  54. #define MAXDATASIZE 1000 /* max number of bytes we can get at once */
  55. /* CVS revision and version */
  56. static char revisionstr[] = "$Revision: 1.51 $";
  57. static char datestr[] = "$Date: 2009/09/11 09:49:19 $";
  58. enum MODE { HTTP = 1, RTSP = 2, NTRIP1 = 3, AUTO = 4, UDP = 5, END };
  59. struct Args
  60. {
  61. const char *server;
  62. const char *port;
  63. const char *user;
  64. const char *proxyhost;
  65. const char *proxyport;
  66. const char *password;
  67. const char *nmea;
  68. const char *data;
  69. int bitrate;
  70. int mode;
  71. int udpport;
  72. int initudp;
  73. enum SerialBaud baud;
  74. enum SerialDatabits databits;
  75. enum SerialStopbits stopbits;
  76. enum SerialParity parity;
  77. enum SerialProtocol protocol;
  78. const char *serdevice;
  79. const char *serlogfile;
  80. };
  81. /* option parsing */
  82. #ifdef NO_LONG_OPTS
  83. #define LONG_OPT(a)
  84. #else
  85. #define LONG_OPT(a) a
  86. static struct option opts[] = {
  87. { "bitrate", no_argument, 0, 'b'},
  88. { "data", required_argument, 0, 'd'}, /* compatibility */
  89. { "mountpoint", required_argument, 0, 'm'},
  90. { "initudp", no_argument, 0, 'I'},
  91. { "udpport", required_argument, 0, 'P'},
  92. { "server", required_argument, 0, 's'},
  93. { "password", required_argument, 0, 'p'},
  94. { "port", required_argument, 0, 'r'},
  95. { "proxyport", required_argument, 0, 'R'},
  96. { "proxyhost", required_argument, 0, 'S'},
  97. { "user", required_argument, 0, 'u'},
  98. { "nmea", required_argument, 0, 'n'},
  99. { "mode", required_argument, 0, 'M'},
  100. { "serdevice", required_argument, 0, 'D'},
  101. { "baud", required_argument, 0, 'B'},
  102. { "stopbits", required_argument, 0, 'T'},
  103. { "protocol", required_argument, 0, 'C'},
  104. { "parity", required_argument, 0, 'Y'},
  105. { "databits", required_argument, 0, 'A'},
  106. { "serlogfile", required_argument, 0, 'l'},
  107. { "help", no_argument, 0, 'h'},
  108. {0,0,0,0}};
  109. #endif
  110. #define ARGOPT "-d:m:bhp:r:s:u:n:S:R:M:IP:D:B:T:C:Y:A:l:"
  111. int stop = 0;
  112. #ifndef WINDOWSVERSION
  113. int sigstop = 0;
  114. #ifdef __GNUC__
  115. static __attribute__ ((noreturn)) void sighandler_alarm(
  116. int sig __attribute__((__unused__)))
  117. #else /* __GNUC__ */
  118. static void sighandler_alarm(int sig)
  119. #endif /* __GNUC__ */
  120. {
  121. if(!sigstop)
  122. fprintf(stderr, "ERROR: more than %d seconds no activity\n", ALARMTIME);
  123. else
  124. fprintf(stderr, "ERROR: user break\n");
  125. exit(1);
  126. }
  127. #ifdef __GNUC__
  128. static void sighandler_int(int sig __attribute__((__unused__)))
  129. #else /* __GNUC__ */
  130. static void sighandler_alarm(int sig)
  131. #endif /* __GNUC__ */
  132. {
  133. sigstop = 1;
  134. alarm(2);
  135. stop = 1;
  136. }
  137. #endif /* WINDOWSVERSION */
  138. static const char *encodeurl(const char *req)
  139. {
  140. char *h = "0123456789abcdef";
  141. static char buf[128];
  142. char *urlenc = buf;
  143. char *bufend = buf + sizeof(buf) - 3;
  144. while(*req && urlenc < bufend)
  145. {
  146. if(isalnum(*req)
  147. || *req == '-' || *req == '_' || *req == '.')
  148. *urlenc++ = *req++;
  149. else
  150. {
  151. *urlenc++ = '%';
  152. *urlenc++ = h[*req >> 4];
  153. *urlenc++ = h[*req & 0x0f];
  154. req++;
  155. }
  156. }
  157. *urlenc = 0;
  158. return buf;
  159. }
  160. static const char *geturl(const char *url, struct Args *args)
  161. {
  162. static char buf[1000];
  163. static char *Buffer = buf;
  164. static char *Bufend = buf+sizeof(buf);
  165. char *h = "0123456789abcdef";
  166. if(strncmp("ntrip:", url, 6))
  167. return "URL must start with 'ntrip:'.";
  168. url += 6; /* skip ntrip: */
  169. if(*url != '@' && *url != '/')
  170. {
  171. /* scan for mountpoint */
  172. args->data = Buffer;
  173. if(*url != '?')
  174. {
  175. while(*url && *url != '@' && *url != ';' && *url != '/' && Buffer != Bufend)
  176. *(Buffer++) = *(url++);
  177. }
  178. else
  179. {
  180. while(*url && *url != '@' && *url != '/' && Buffer != Bufend)
  181. {
  182. if(isalnum(*url) || *url == '-' || *url == '_' || *url == '.')
  183. *Buffer++ = *url++;
  184. else
  185. {
  186. *Buffer++ = '%';
  187. *Buffer++ = h[*url >> 4];
  188. *Buffer++ = h[*url & 0x0f];
  189. url++;
  190. }
  191. }
  192. }
  193. if(Buffer == args->data)
  194. return "Mountpoint required.";
  195. else if(Buffer >= Bufend-1)
  196. return "Parsing buffer too short.";
  197. *(Buffer++) = 0;
  198. }
  199. if(*url == '/') /* username and password */
  200. {
  201. ++url;
  202. args->user = Buffer;
  203. while(*url && *url != '@' && *url != ';' && *url != ':' && Buffer != Bufend)
  204. *(Buffer++) = *(url++);
  205. if(Buffer == args->user)
  206. return "Username cannot be empty.";
  207. else if(Buffer >= Bufend-1)
  208. return "Parsing buffer too short.";
  209. *(Buffer++) = 0;
  210. if(*url == ':') ++url;
  211. args->password = Buffer;
  212. while(*url && *url != '@' && *url != ';' && Buffer != Bufend)
  213. *(Buffer++) = *(url++);
  214. if(Buffer == args->password)
  215. return "Password cannot be empty.";
  216. else if(Buffer >= Bufend-1)
  217. return "Parsing buffer too short.";
  218. *(Buffer++) = 0;
  219. }
  220. if(*url == '@') /* server */
  221. {
  222. ++url;
  223. if(*url != '@' && *url != ':')
  224. {
  225. args->server = Buffer;
  226. while(*url && *url != '@' && *url != ':' && *url != ';' && Buffer != Bufend)
  227. *(Buffer++) = *(url++);
  228. if(Buffer == args->server)
  229. return "Servername cannot be empty.";
  230. else if(Buffer >= Bufend-1)
  231. return "Parsing buffer too short.";
  232. *(Buffer++) = 0;
  233. }
  234. if(*url == ':')
  235. {
  236. ++url;
  237. args->port = Buffer;
  238. while(*url && *url != '@' && *url != ';' && Buffer != Bufend)
  239. *(Buffer++) = *(url++);
  240. if(Buffer == args->port)
  241. return "Port cannot be empty.";
  242. else if(Buffer >= Bufend-1)
  243. return "Parsing buffer too short.";
  244. *(Buffer++) = 0;
  245. }
  246. if(*url == '@') /* proxy */
  247. {
  248. ++url;
  249. args->proxyhost = Buffer;
  250. while(*url && *url != ':' && *url != ';' && Buffer != Bufend)
  251. *(Buffer++) = *(url++);
  252. if(Buffer == args->proxyhost)
  253. return "Proxy servername cannot be empty.";
  254. else if(Buffer >= Bufend-1)
  255. return "Parsing buffer too short.";
  256. *(Buffer++) = 0;
  257. if(*url == ':')
  258. {
  259. ++url;
  260. args->proxyport = Buffer;
  261. while(*url && *url != ';' && Buffer != Bufend)
  262. *(Buffer++) = *(url++);
  263. if(Buffer == args->proxyport)
  264. return "Proxy port cannot be empty.";
  265. else if(Buffer >= Bufend-1)
  266. return "Parsing buffer too short.";
  267. *(Buffer++) = 0;
  268. }
  269. }
  270. }
  271. if(*url == ';') /* NMEA */
  272. {
  273. args->nmea = ++url;
  274. while(*url)
  275. ++url;
  276. }
  277. return *url ? "Garbage at end of server string." : 0;
  278. }
  279. static int getargs(int argc, char **argv, struct Args *args)
  280. {
  281. int res = 1;
  282. int getoptr;
  283. char *a;
  284. int i = 0, help = 0;
  285. args->server = "www.euref-ip.net";
  286. args->port = "2101";
  287. args->user = "";
  288. args->password = "";
  289. args->nmea = 0;
  290. args->data = 0;
  291. args->bitrate = 0;
  292. args->proxyhost = 0;
  293. args->proxyport = "2101";
  294. args->mode = AUTO;
  295. args->initudp = 0;
  296. args->udpport = 0;
  297. args->protocol = SPAPROTOCOL_NONE;
  298. args->parity = SPAPARITY_NONE;
  299. args->stopbits = SPASTOPBITS_1;
  300. args->databits = SPADATABITS_8;
  301. args->baud = SPABAUD_9600;
  302. args->serdevice = 0;
  303. args->serlogfile = 0;
  304. help = 0;
  305. do
  306. {
  307. #ifdef NO_LONG_OPTS
  308. switch((getoptr = getopt(argc, argv, ARGOPT)))
  309. #else
  310. switch((getoptr = getopt_long(argc, argv, ARGOPT, opts, 0)))
  311. #endif
  312. {
  313. case 's': args->server = optarg; break;
  314. case 'u': args->user = optarg; break;
  315. case 'p': args->password = optarg; break;
  316. case 'd': /* legacy option, may get removed in future */
  317. fprintf(stderr, "Option -d or --data is deprecated. Use -m instead.\n");
  318. case 'm':
  319. if(optarg && *optarg == '?')
  320. args->data = encodeurl(optarg);
  321. else
  322. args->data = optarg;
  323. break;
  324. case 'B':
  325. {
  326. int i = strtol(optarg, 0, 10);
  327. switch(i)
  328. {
  329. case 50: args->baud = SPABAUD_50; break;
  330. case 110: args->baud = SPABAUD_110; break;
  331. case 300: args->baud = SPABAUD_300; break;
  332. case 600: args->baud = SPABAUD_600; break;
  333. case 1200: args->baud = SPABAUD_1200; break;
  334. case 2400: args->baud = SPABAUD_2400; break;
  335. case 4800: args->baud = SPABAUD_4800; break;
  336. case 9600: args->baud = SPABAUD_9600; break;
  337. case 19200: args->baud = SPABAUD_19200; break;
  338. case 38400: args->baud = SPABAUD_38400; break;
  339. case 57600: args->baud = SPABAUD_57600; break;
  340. case 115200: args->baud = SPABAUD_115200; break;
  341. default:
  342. fprintf(stderr, "Baudrate '%s' unknown\n", optarg);
  343. res = 0;
  344. break;
  345. }
  346. }
  347. break;
  348. case 'T':
  349. if(!strcmp(optarg, "1")) args->stopbits = SPASTOPBITS_1;
  350. else if(!strcmp(optarg, "2")) args->stopbits = SPASTOPBITS_2;
  351. else
  352. {
  353. fprintf(stderr, "Stopbits '%s' unknown\n", optarg);
  354. res = 0;
  355. }
  356. break;
  357. case 'A':
  358. if(!strcmp(optarg, "5")) args->databits = SPADATABITS_5;
  359. else if(!strcmp(optarg, "6")) args->databits = SPADATABITS_6;
  360. else if(!strcmp(optarg, "7")) args->databits = SPADATABITS_7;
  361. else if(!strcmp(optarg, "8")) args->databits = SPADATABITS_8;
  362. else
  363. {
  364. fprintf(stderr, "Databits '%s' unknown\n", optarg);
  365. res = 0;
  366. }
  367. break;
  368. case 'C':
  369. {
  370. int i = 0;
  371. args->protocol = SerialGetProtocol(optarg, &i);
  372. if(!i)
  373. {
  374. fprintf(stderr, "Protocol '%s' unknown\n", optarg);
  375. res = 0;
  376. }
  377. }
  378. break;
  379. case 'Y':
  380. {
  381. int i = 0;
  382. args->parity = SerialGetParity(optarg, &i);
  383. if(!i)
  384. {
  385. fprintf(stderr, "Parity '%s' unknown\n", optarg);
  386. res = 0;
  387. }
  388. }
  389. break;
  390. case 'D': args->serdevice = optarg; break;
  391. case 'l': args->serlogfile = optarg; break;
  392. case 'I': args->initudp = 1; break;
  393. case 'P': args->udpport = strtol(optarg, 0, 10); break;
  394. case 'n': args->nmea = optarg; break;
  395. case 'b': args->bitrate = 1; break;
  396. case 'h': help=1; break;
  397. case 'r': args->port = optarg; break;
  398. case 'S': args->proxyhost = optarg; break;
  399. case 'R': args->proxyport = optarg; break;
  400. case 'M':
  401. args->mode = 0;
  402. if (!strcmp(optarg,"n") || !strcmp(optarg,"ntrip1"))
  403. args->mode = NTRIP1;
  404. else if(!strcmp(optarg,"h") || !strcmp(optarg,"http"))
  405. args->mode = HTTP;
  406. else if(!strcmp(optarg,"r") || !strcmp(optarg,"rtsp"))
  407. args->mode = RTSP;
  408. else if(!strcmp(optarg,"u") || !strcmp(optarg,"udp"))
  409. args->mode = UDP;
  410. else if(!strcmp(optarg,"a") || !strcmp(optarg,"auto"))
  411. args->mode = AUTO;
  412. else args->mode = atoi(optarg);
  413. if((args->mode == 0) || (args->mode >= END))
  414. {
  415. fprintf(stderr, "Mode %s unknown\n", optarg);
  416. res = 0;
  417. }
  418. break;
  419. case 1:
  420. {
  421. const char *err;
  422. if((err = geturl(optarg, args)))
  423. {
  424. fprintf(stderr, "%s\n\n", err);
  425. res = 0;
  426. }
  427. }
  428. break;
  429. case -1: break;
  430. }
  431. } while(getoptr != -1 && res);
  432. for(a = revisionstr+11; *a && *a != ' '; ++a)
  433. revisionstr[i++] = *a;
  434. revisionstr[i] = 0;
  435. datestr[0] = datestr[7];
  436. datestr[1] = datestr[8];
  437. datestr[2] = datestr[9];
  438. datestr[3] = datestr[10];
  439. datestr[5] = datestr[12];
  440. datestr[6] = datestr[13];
  441. datestr[8] = datestr[15];
  442. datestr[9] = datestr[16];
  443. datestr[4] = datestr[7] = '-';
  444. datestr[10] = 0;
  445. if(!res || help)
  446. {
  447. fprintf(stderr, "Version %s (%s) GPL" COMPILEDATE "\nUsage:\n%s -s server -u user ...\n"
  448. " -m " LONG_OPT("--mountpoint ") "the requested data set or sourcetable filtering criteria\n"
  449. " -s " LONG_OPT("--server ") "the server name or address\n"
  450. " -p " LONG_OPT("--password ") "the login password\n"
  451. " -r " LONG_OPT("--port ") "the server port number (default 2101)\n"
  452. " -u " LONG_OPT("--user ") "the user name\n"
  453. " -M " LONG_OPT("--mode ") "mode for data request\n"
  454. " Valid modes are:\n"
  455. " 1, h, http NTRIP Version 2.0 Caster in TCP/IP mode\n"
  456. " 2, r, rtsp NTRIP Version 2.0 Caster in RTSP/RTP mode\n"
  457. " 3, n, ntrip1 NTRIP Version 1.0 Caster\n"
  458. " 4, a, auto automatic detection (default)\n"
  459. " 5, u, udp NTRIP Version 2.0 Caster in UDP mode\n"
  460. "or using an URL:\n%s ntrip:mountpoint[/user[:password]][@[server][:port][@proxyhost[:proxyport]]][;nmea]\n"
  461. "\nExpert options:\n"
  462. " -n " LONG_OPT("--nmea ") "NMEA string for sending to server\n"
  463. " -b " LONG_OPT("--bitrate ") "output bitrate\n"
  464. " -I " LONG_OPT("--initudp ") "send initial UDP packet for firewall handling\n"
  465. " -P " LONG_OPT("--udpport ") "set the local UDP port\n"
  466. " -S " LONG_OPT("--proxyhost ") "proxy name or address\n"
  467. " -R " LONG_OPT("--proxyport ") "proxy port, optional (default 2101)\n"
  468. "\nSerial input/output:\n"
  469. " -D " LONG_OPT("--serdevice ") "serial device for output\n"
  470. " -B " LONG_OPT("--baud ") "baudrate for serial device\n"
  471. " -T " LONG_OPT("--stopbits ") "stopbits for serial device\n"
  472. " -C " LONG_OPT("--protocol ") "protocol for serial device\n"
  473. " -Y " LONG_OPT("--parity ") "parity for serial device\n"
  474. " -A " LONG_OPT("--databits ") "databits for serial device\n"
  475. " -l " LONG_OPT("--serlogfile ") "logfile for serial data\n"
  476. , revisionstr, datestr, argv[0], argv[0]);
  477. exit(1);
  478. }
  479. return res;
  480. }
  481. static const char encodingTable [64] = {
  482. 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
  483. 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
  484. 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
  485. 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
  486. };
  487. /* does not buffer overrun, but breaks directly after an error */
  488. /* returns the number of required bytes */
  489. static int encode(char *buf, int size, const char *user, const char *pwd)
  490. {
  491. unsigned char inbuf[3];
  492. char *out = buf;
  493. int i, sep = 0, fill = 0, bytes = 0;
  494. while(*user || *pwd)
  495. {
  496. i = 0;
  497. while(i < 3 && *user) inbuf[i++] = *(user++);
  498. if(i < 3 && !sep) {inbuf[i++] = ':'; ++sep; }
  499. while(i < 3 && *pwd) inbuf[i++] = *(pwd++);
  500. while(i < 3) {inbuf[i++] = 0; ++fill; }
  501. if(out-buf < size-1)
  502. *(out++) = encodingTable[(inbuf [0] & 0xFC) >> 2];
  503. if(out-buf < size-1)
  504. *(out++) = encodingTable[((inbuf [0] & 0x03) << 4)
  505. | ((inbuf [1] & 0xF0) >> 4)];
  506. if(out-buf < size-1)
  507. {
  508. if(fill == 2)
  509. *(out++) = '=';
  510. else
  511. *(out++) = encodingTable[((inbuf [1] & 0x0F) << 2)
  512. | ((inbuf [2] & 0xC0) >> 6)];
  513. }
  514. if(out-buf < size-1)
  515. {
  516. if(fill >= 1)
  517. *(out++) = '=';
  518. else
  519. *(out++) = encodingTable[inbuf [2] & 0x3F];
  520. }
  521. bytes += 4;
  522. }
  523. if(out-buf < size)
  524. *out = 0;
  525. return bytes;
  526. }
  527. int main(int argc, char **argv)
  528. {
  529. struct Args args;
  530. setbuf(stdout, 0);
  531. setbuf(stdin, 0);
  532. setbuf(stderr, 0);
  533. #ifndef WINDOWSVERSION
  534. signal(SIGALRM,sighandler_alarm);
  535. signal(SIGINT,sighandler_int);
  536. alarm(ALARMTIME);
  537. #else
  538. WSADATA wsaData;
  539. if(WSAStartup(MAKEWORD(1,1),&wsaData))
  540. {
  541. fprintf(stderr, "Could not init network access.\n");
  542. return 20;
  543. }
  544. #endif
  545. if(getargs(argc, argv, &args))
  546. {
  547. struct serial sx;
  548. FILE *ser = 0;
  549. char nmeabuffer[200] = "$GPGGA,"; /* our start string */
  550. size_t nmeabufpos = 0;
  551. size_t nmeastarpos = 0;
  552. int sleeptime = 0;
  553. if(args.serdevice)
  554. {
  555. const char *e = SerialInit(&sx, args.serdevice, args.baud,
  556. args.stopbits, args.protocol, args.parity, args.databits, 1);
  557. if(e)
  558. {
  559. fprintf(stderr, "%s\n", e);
  560. return 20;
  561. }
  562. if(args.serlogfile)
  563. {
  564. if(!(ser = fopen(args.serlogfile, "a+")))
  565. {
  566. SerialFree(&sx);
  567. fprintf(stderr, "Could not open serial logfile.\n");
  568. return 20;
  569. }
  570. }
  571. }
  572. do
  573. {
  574. int error = 0;
  575. sockettype sockfd = 0;
  576. int numbytes;
  577. char buf[MAXDATASIZE];
  578. struct sockaddr_in their_addr; /* connector's address information */
  579. struct hostent *he;
  580. struct servent *se;
  581. const char *server, *port, *proxyserver = 0;
  582. char proxyport[6];
  583. char *b;
  584. long i;
  585. if(sleeptime)
  586. {
  587. #ifdef WINDOWSVERSION
  588. Sleep(sleeptime*1000);
  589. #else
  590. sleep(sleeptime);
  591. #endif
  592. sleeptime += 2;
  593. }
  594. else
  595. {
  596. sleeptime = 1;
  597. }
  598. #ifndef WINDOWSVERSION
  599. alarm(ALARMTIME);
  600. #endif
  601. if(args.proxyhost)
  602. {
  603. int p;
  604. if((i = strtol(args.port, &b, 10)) && (!b || !*b))
  605. p = i;
  606. else if(!(se = getservbyname(args.port, 0)))
  607. {
  608. fprintf(stderr, "Can't resolve port %s.", args.port);
  609. stop = 1;
  610. }
  611. else
  612. {
  613. p = ntohs(se->s_port);
  614. }
  615. if(!stop && !error)
  616. {
  617. snprintf(proxyport, sizeof(proxyport), "%d", p);
  618. port = args.proxyport;
  619. proxyserver = args.server;
  620. server = args.proxyhost;
  621. }
  622. }
  623. else
  624. {
  625. server = args.server;
  626. port = args.port;
  627. }
  628. if(!stop && !error)
  629. {
  630. memset(&their_addr, 0, sizeof(struct sockaddr_in));
  631. if((i = strtol(port, &b, 10)) && (!b || !*b))
  632. their_addr.sin_port = htons(i);
  633. else if(!(se = getservbyname(port, 0)))
  634. {
  635. fprintf(stderr, "Can't resolve port %s.", port);
  636. stop = 1;
  637. }
  638. else
  639. {
  640. their_addr.sin_port = se->s_port;
  641. }
  642. if(!stop && !error)
  643. {
  644. if(!(he=gethostbyname(server)))
  645. {
  646. fprintf(stderr, "Server name lookup failed for '%s'.\n", server);
  647. error = 1;
  648. }
  649. else if((sockfd = socket(AF_INET, (args.mode == UDP ? SOCK_DGRAM :
  650. SOCK_STREAM), 0)) == -1)
  651. {
  652. myperror("socket");
  653. error = 1;
  654. }
  655. else
  656. {
  657. their_addr.sin_family = AF_INET;
  658. their_addr.sin_addr = *((struct in_addr *)he->h_addr);
  659. }
  660. }
  661. }
  662. if(!stop && !error)
  663. {
  664. if(args.mode == UDP)
  665. {
  666. unsigned int session;
  667. int tim, seq, init;
  668. char rtpbuf[1526];
  669. int i=12, j;
  670. init = time(0);
  671. srand(init);
  672. session = rand();
  673. tim = rand();
  674. seq = rand();
  675. rtpbuf[0] = (2<<6);
  676. /* padding, extension, csrc are empty */
  677. rtpbuf[1] = 97;
  678. /* marker is empty */
  679. rtpbuf[2] = (seq>>8)&0xFF;
  680. rtpbuf[3] = (seq)&0xFF;
  681. rtpbuf[4] = (tim>>24)&0xFF;
  682. rtpbuf[5] = (tim>>16)&0xFF;
  683. rtpbuf[6] = (tim>>8)&0xFF;
  684. rtpbuf[7] = (tim)&0xFF;
  685. /* sequence and timestamp are empty */
  686. rtpbuf[8] = (session>>24)&0xFF;
  687. rtpbuf[9] = (session>>16)&0xFF;
  688. rtpbuf[10] = (session>>8)&0xFF;
  689. rtpbuf[11] = (session)&0xFF;
  690. ++seq;
  691. j = snprintf(rtpbuf+i, sizeof(rtpbuf)-i-40, /* leave some space for login */
  692. "GET /%s HTTP/1.1\r\n"
  693. "Host: %s\r\n"
  694. "Ntrip-Version: Ntrip/2.0\r\n"
  695. "User-Agent: %s/%s\r\n"
  696. "%s%s%s"
  697. "Connection: close%s",
  698. args.data ? args.data : "", args.server, AGENTSTRING, revisionstr,
  699. args.nmea ? "Ntrip-GGA: " : "", args.nmea ? args.nmea : "",
  700. args.nmea ? "\r\n" : "",
  701. (*args.user || *args.password) ? "\r\nAuthorization: Basic " : "");
  702. i += j;
  703. if(i > (int)sizeof(rtpbuf)-40 || j < 0) /* second check for old glibc */
  704. {
  705. fprintf(stderr, "Requested data too long\n");
  706. stop = 1;
  707. }
  708. else
  709. {
  710. i += encode(rtpbuf+i, sizeof(rtpbuf)-i-4, args.user, args.password);
  711. if(i > (int)sizeof(rtpbuf)-4)
  712. {
  713. fprintf(stderr, "Username and/or password too long\n");
  714. stop = 1;
  715. }
  716. else
  717. {
  718. struct sockaddr_in local;
  719. socklen_t len;
  720. rtpbuf[i++] = '\r';
  721. rtpbuf[i++] = '\n';
  722. rtpbuf[i++] = '\r';
  723. rtpbuf[i++] = '\n';
  724. /* fill structure with local address information for UDP */
  725. memset(&local, 0, sizeof(local));
  726. local.sin_family = AF_INET;
  727. local.sin_port = htons(args.udpport);
  728. local.sin_addr.s_addr = htonl(INADDR_ANY);
  729. len = sizeof(local);
  730. /* bind() in order to get a random RTP client_port */
  731. if((bind(sockfd, (struct sockaddr *)&local, len)) < 0)
  732. {
  733. myperror("bind");
  734. error = 1;
  735. }
  736. else if(connect(sockfd, (struct sockaddr *)&their_addr,
  737. sizeof(struct sockaddr)) == -1)
  738. {
  739. myperror("connect");
  740. error = 1;
  741. }
  742. else if(send(sockfd, rtpbuf, i, 0) != i)
  743. {
  744. myperror("Could not send UDP packet");
  745. stop = 1;
  746. }
  747. else
  748. {
  749. if((numbytes=recv(sockfd, rtpbuf, sizeof(rtpbuf)-1, 0)) > 0)
  750. {
  751. int sn = 0x10000, ts=0;
  752. /* we don't expect message longer than 1513, so we cut the last
  753. byte for security reasons to prevent buffer overrun */
  754. rtpbuf[numbytes] = 0;
  755. if(numbytes > 17+12 &&
  756. (!strncmp(rtpbuf+12, "HTTP/1.1 200 OK\r\n", 17) ||
  757. !strncmp(rtpbuf+12, "HTTP/1.0 200 OK\r\n", 17)))
  758. {
  759. const char *sessioncheck = "session: ";
  760. const char *datacheck = "Content-Type: gnss/data\r\n";
  761. const char *sourcetablecheck = "Content-Type: gnss/sourcetable\r\n";
  762. const char *contentlengthcheck = "Content-Length: ";
  763. const char *httpresponseend = "\r\n\r\n";
  764. int contentlength = 0, httpresponselength = 0;
  765. /* datacheck */
  766. int l = strlen(datacheck)-1;
  767. int j=0;
  768. for(i = 12; j != l && i < numbytes-l; ++i)
  769. {
  770. for(j = 0; j < l && rtpbuf[i+j] == datacheck[j]; ++j)
  771. ;
  772. }
  773. if(i != numbytes-l)
  774. {
  775. /* check for Session */
  776. l = strlen(sessioncheck)-1;
  777. j=0;
  778. for(i = 12; j != l && i < numbytes-l; ++i)
  779. {
  780. for(j = 0; j < l && tolower(rtpbuf[i+j]) == sessioncheck[j]; ++j)
  781. ;
  782. }
  783. if(i != numbytes-l) /* found a session number */
  784. {
  785. i+=l;
  786. session = 0;
  787. while(i < numbytes && rtpbuf[i] >= '0' && rtpbuf[i] <= '9')
  788. session = session * 10 + rtpbuf[i++]-'0';
  789. if(rtpbuf[i] != '\r')
  790. {
  791. fprintf(stderr, "Could not extract session number\n");
  792. stop = 1;
  793. }
  794. }
  795. }
  796. else
  797. {
  798. /* sourcetablecheck */
  799. l = strlen(sourcetablecheck)-1;
  800. j=0;
  801. for(i = 12; j != l && i < numbytes-l; ++i)
  802. {
  803. for(j = 0; j < l && rtpbuf[i+j] == sourcetablecheck[j]; ++j)
  804. ;
  805. }
  806. if(i == numbytes-l)
  807. {
  808. fprintf(stderr, "No 'Content-Type: gnss/data' or"
  809. " 'Content-Type: gnss/sourcetable' found\n");
  810. error = 1;
  811. }
  812. else
  813. {
  814. /* check for http response end */
  815. l = strlen(httpresponseend)-1;
  816. j=0;
  817. for(i = 12; j != l && i < numbytes-l; ++i)
  818. {
  819. for(j = 0; j < l && rtpbuf[i+j] == httpresponseend[j]; ++j)
  820. ;
  821. }
  822. if(i != numbytes-l) /* found http response end */
  823. {
  824. httpresponselength = i+3-12;
  825. }
  826. /* check for content length */
  827. l = strlen(contentlengthcheck)-1;
  828. j=0;
  829. for(i = 12; j != l && i < numbytes-l; ++i)
  830. {
  831. for(j = 0; j < l && rtpbuf[i+j] == contentlengthcheck[j]; ++j)
  832. ;
  833. }
  834. if(i != numbytes-l) /* found content length */
  835. {
  836. i+=l;
  837. contentlength = 0;
  838. while(i < numbytes && rtpbuf[i] >= '0' && rtpbuf[i] <= '9')
  839. contentlength = contentlength * 10 + rtpbuf[i++]-'0';
  840. if(rtpbuf[i] == '\r')
  841. {
  842. contentlength += httpresponselength;
  843. do
  844. {
  845. fwrite(rtpbuf+12, (size_t)numbytes-12, 1, stdout);
  846. if((contentlength -= (numbytes-12)) == 0)
  847. {
  848. stop = 1;
  849. }
  850. else
  851. {
  852. numbytes = recv(sockfd, rtpbuf, sizeof(rtpbuf), 0);
  853. }
  854. }while((numbytes >12) && (!stop));
  855. }
  856. else
  857. {
  858. fprintf(stderr, "Could not extract content length\n");
  859. stop = 1;
  860. }
  861. }
  862. }
  863. }
  864. }
  865. else
  866. {
  867. int k;
  868. fprintf(stderr, "Could not get the requested data: ");
  869. for(k = 12; k < numbytes && rtpbuf[k] != '\n' && rtpbuf[k] != '\r'; ++k)
  870. {
  871. fprintf(stderr, "%c", isprint(rtpbuf[k]) ? rtpbuf[k] : '.');
  872. }
  873. fprintf(stderr, "\n");
  874. error = 1;
  875. }
  876. while(!stop && !error)
  877. {
  878. struct timeval tv = {1,0};
  879. fd_set fdr;
  880. fd_set fde;
  881. FD_ZERO(&fdr);
  882. FD_ZERO(&fde);
  883. FD_SET(sockfd, &fdr);
  884. FD_SET(sockfd, &fde);
  885. if(select(sockfd+1,&fdr,0,&fde,&tv) < 0)
  886. {
  887. fprintf(stderr, "Select problem.\n");
  888. error = 1;
  889. continue;
  890. }
  891. i = recv(sockfd, rtpbuf, sizeof(rtpbuf), 0);
  892. #ifndef WINDOWSVERSION
  893. alarm(ALARMTIME);
  894. #endif
  895. if(i >= 12 && (unsigned char)rtpbuf[0] == (2 << 6)
  896. && rtpbuf[1] >= 96 && rtpbuf[1] <= 98)
  897. {
  898. time_t ct;
  899. int u,v;
  900. unsigned int w;
  901. u = ((unsigned char)rtpbuf[2]<<8)+(unsigned char)rtpbuf[3];
  902. v = ((unsigned char)rtpbuf[4]<<24)+((unsigned char)rtpbuf[5]<<16)
  903. +((unsigned char)rtpbuf[6]<<8)+(unsigned char)rtpbuf[7];
  904. w = ((unsigned char)rtpbuf[8]<<24)+((unsigned char)rtpbuf[9]<<16)
  905. +((unsigned char)rtpbuf[10]<<8)+(unsigned char)rtpbuf[11];
  906. if(sn == 0x10000) {sn = u-1;ts=v-1;}
  907. else if(u < -30000 && sn > 30000) sn -= 0xFFFF;
  908. if(session != w || ts > v)
  909. {
  910. fprintf(stderr, "Illegal UDP data received.\n");
  911. continue;
  912. }
  913. else if(u > sn) /* don't show out-of-order packets */
  914. {
  915. if(rtpbuf[1] == 98)
  916. {
  917. fprintf(stderr, "Connection closed.\n");
  918. error = 1;
  919. continue;
  920. }
  921. else if((rtpbuf[1] == 96) && (i>12))
  922. {
  923. fwrite(rtpbuf+12, (size_t)i-12, 1, stdout);
  924. }
  925. }
  926. sn = u; ts = v;
  927. /* Keep Alive */
  928. ct = time(0);
  929. if(ct-init > 15)
  930. {
  931. tim += (ct-init)*1000000/TIME_RESOLUTION;
  932. rtpbuf[0] = (2<<6);
  933. /* padding, extension, csrc are empty */
  934. rtpbuf[1] = 96;
  935. /* marker is empty */
  936. rtpbuf[2] = (seq>>8)&0xFF;
  937. rtpbuf[3] = (seq)&0xFF;
  938. rtpbuf[4] = (tim>>24)&0xFF;
  939. rtpbuf[5] = (tim>>16)&0xFF;
  940. rtpbuf[6] = (tim>>8)&0xFF;
  941. rtpbuf[7] = (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. ++seq;
  948. init = ct;
  949. if(send(sockfd, rtpbuf, 12, 0) != 12)
  950. {
  951. myperror("send");
  952. error = 1;
  953. }
  954. }
  955. }
  956. else if(i >= 0)
  957. {
  958. fprintf(stderr, "Illegal UDP header.\n");
  959. continue;
  960. }
  961. }
  962. }
  963. /* send connection close always to allow nice session closing */
  964. tim += (time(0)-init)*1000000/TIME_RESOLUTION;
  965. rtpbuf[0] = (2<<6);
  966. /* padding, extension, csrc are empty */
  967. rtpbuf[1] = 98;
  968. /* marker is empty */
  969. rtpbuf[2] = (seq>>8)&0xFF;
  970. rtpbuf[3] = (seq)&0xFF;
  971. rtpbuf[4] = (tim>>24)&0xFF;
  972. rtpbuf[5] = (tim>>16)&0xFF;
  973. rtpbuf[6] = (tim>>8)&0xFF;
  974. rtpbuf[7] = (tim)&0xFF;
  975. /* sequence and timestamp are empty */
  976. rtpbuf[8] = (session>>24)&0xFF;
  977. rtpbuf[9] = (session>>16)&0xFF;
  978. rtpbuf[10] = (session>>8)&0xFF;
  979. rtpbuf[11] = (session)&0xFF;
  980. send(sockfd, rtpbuf, 12, 0); /* cleanup */
  981. }
  982. }
  983. }
  984. }
  985. else if(args.data && *args.data != '%' && args.mode == RTSP)
  986. {
  987. struct sockaddr_in local;
  988. sockettype sockudp = 0;
  989. int localport;
  990. int cseq = 1;
  991. socklen_t len;
  992. if((sockudp = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
  993. {
  994. myperror("socket");
  995. error = 1;
  996. }
  997. if(!stop && !error)
  998. {
  999. /* fill structure with local address information for UDP */
  1000. memset(&local, 0, sizeof(local));
  1001. local.sin_family = AF_INET;
  1002. local.sin_port = htons(args.udpport);
  1003. local.sin_addr.s_addr = htonl(INADDR_ANY);
  1004. len = sizeof(local);
  1005. /* bind() in order to get a random RTP client_port */
  1006. if((bind(sockudp, (struct sockaddr *)&local, len)) < 0)
  1007. {
  1008. myperror("bind");
  1009. error = 1;
  1010. }
  1011. else if((getsockname(sockudp, (struct sockaddr*)&local, &len)) == -1)
  1012. {
  1013. myperror("local access failed");
  1014. error = 1;
  1015. }
  1016. else if(connect(sockfd, (struct sockaddr *)&their_addr,
  1017. sizeof(struct sockaddr)) == -1)
  1018. {
  1019. myperror("connect");
  1020. error = 1;
  1021. }
  1022. localport = ntohs(local.sin_port);
  1023. }
  1024. if(!stop && !error)
  1025. {
  1026. i=snprintf(buf, MAXDATASIZE-40, /* leave some space for login */
  1027. "SETUP rtsp://%s%s%s/%s RTSP/1.0\r\n"
  1028. "CSeq: %d\r\n"
  1029. "Ntrip-Version: Ntrip/2.0\r\n"
  1030. "Ntrip-Component: Ntripclient\r\n"
  1031. "User-Agent: %s/%s\r\n"
  1032. "%s%s%s"
  1033. "Transport: RTP/GNSS;unicast;client_port=%u%s",
  1034. args.server, proxyserver ? ":" : "", proxyserver ? args.port : "",
  1035. args.data, cseq++, AGENTSTRING, revisionstr,
  1036. args.nmea ? "Ntrip-GGA: " : "", args.nmea ? args.nmea : "",
  1037. args.nmea ? "\r\n" : "",
  1038. localport,
  1039. (*args.user || *args.password) ? "\r\nAuthorization: Basic " : "");
  1040. if(i > MAXDATASIZE-40 || i < 0) /* second check for old glibc */
  1041. {
  1042. fprintf(stderr, "Requested data too long\n");
  1043. stop = 1;
  1044. }
  1045. i += encode(buf+i, MAXDATASIZE-i-4, args.user, args.password);
  1046. if(i > MAXDATASIZE-4)
  1047. {
  1048. fprintf(stderr, "Username and/or password too long\n");
  1049. stop = 1;
  1050. }
  1051. buf[i++] = '\r';
  1052. buf[i++] = '\n';
  1053. buf[i++] = '\r';
  1054. buf[i++] = '\n';
  1055. }
  1056. if(!stop && !error)
  1057. {
  1058. if(send(sockfd, buf, (size_t)i, 0) != i)
  1059. {
  1060. myperror("send");
  1061. error = 1;
  1062. }
  1063. else if((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1)
  1064. {
  1065. myperror("recv");
  1066. error = 1;
  1067. }
  1068. else if(numbytes >= 17 && !strncmp(buf, "RTSP/1.0 200 OK\r\n", 17))
  1069. {
  1070. int serverport = 0, session = 0;
  1071. const char *portcheck = "server_port=";
  1072. const char *sessioncheck = "session: ";
  1073. int l = strlen(portcheck)-1;
  1074. int j=0;
  1075. for(i = 0; j != l && i < numbytes-l; ++i)
  1076. {
  1077. for(j = 0; j < l && tolower(buf[i+j]) == portcheck[j]; ++j)
  1078. ;
  1079. }
  1080. if(i == numbytes-l)
  1081. {
  1082. fprintf(stderr, "No server port number found\n");
  1083. stop = 1;
  1084. }
  1085. else
  1086. {
  1087. i+=l;
  1088. while(i < numbytes && buf[i] >= '0' && buf[i] <= '9')
  1089. serverport = serverport * 10 + buf[i++]-'0';
  1090. if(buf[i] != '\r' && buf[i] != ';')
  1091. {
  1092. fprintf(stderr, "Could not extract server port\n");
  1093. stop = 1;
  1094. }
  1095. }
  1096. if(!stop && !error)
  1097. {
  1098. l = strlen(sessioncheck)-1;
  1099. j=0;
  1100. for(i = 0; j != l && i < numbytes-l; ++i)
  1101. {
  1102. for(j = 0; j < l && tolower(buf[i+j]) == sessioncheck[j]; ++j)
  1103. ;
  1104. }
  1105. if(i == numbytes-l)
  1106. {
  1107. fprintf(stderr, "No session number found\n");
  1108. stop = 1;
  1109. }
  1110. else
  1111. {
  1112. i+=l;
  1113. while(i < numbytes && buf[i] >= '0' && buf[i] <= '9')
  1114. session = session * 10 + buf[i++]-'0';
  1115. if(buf[i] != '\r')
  1116. {
  1117. fprintf(stderr, "Could not extract session number\n");
  1118. stop = 1;
  1119. }
  1120. }
  1121. }
  1122. if(!stop && !error && args.initudp)
  1123. {
  1124. printf("Sending initial UDP packet\n");
  1125. struct sockaddr_in casterRTP;
  1126. char rtpbuffer[12];
  1127. int i;
  1128. rtpbuffer[0] = (2<<6);
  1129. /* padding, extension, csrc are empty */
  1130. rtpbuffer[1] = 96;
  1131. /* marker is empty */
  1132. rtpbuffer[2] = 0;
  1133. rtpbuffer[3] = 0;
  1134. rtpbuffer[4] = 0;
  1135. rtpbuffer[5] = 0;
  1136. rtpbuffer[6] = 0;
  1137. rtpbuffer[7] = 0;
  1138. /* sequence and timestamp are empty */
  1139. rtpbuffer[8] = (session>>24)&0xFF;
  1140. rtpbuffer[9] = (session>>16)&0xFF;
  1141. rtpbuffer[10] = (session>>8)&0xFF;
  1142. rtpbuffer[11] = (session)&0xFF;
  1143. /* fill structure with caster address information for UDP */
  1144. memset(&casterRTP, 0, sizeof(casterRTP));
  1145. casterRTP.sin_family = AF_INET;
  1146. casterRTP.sin_port = htons(serverport);
  1147. casterRTP.sin_addr = *((struct in_addr *)he->h_addr);
  1148. if((i = sendto(sockudp, rtpbuffer, 12, 0,
  1149. (struct sockaddr *) &casterRTP, sizeof(casterRTP))) != 12)
  1150. myperror("WARNING: could not send initial UDP packet");
  1151. }
  1152. if(!stop && !error)
  1153. {
  1154. i = snprintf(buf, MAXDATASIZE,
  1155. "PLAY rtsp://%s%s%s/%s RTSP/1.0\r\n"
  1156. "CSeq: %d\r\n"
  1157. "Session: %u\r\n"
  1158. "\r\n",
  1159. args.server, proxyserver ? ":" : "", proxyserver ? args.port : "",
  1160. args.data, cseq++, session);
  1161. if(i > MAXDATASIZE || i < 0) /* second check for old glibc */
  1162. {
  1163. fprintf(stderr, "Requested data too long\n");
  1164. stop=1;
  1165. }
  1166. else if(send(sockfd, buf, (size_t)i, 0) != i)
  1167. {
  1168. myperror("send");
  1169. error = 1;
  1170. }
  1171. else if((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) != -1)
  1172. {
  1173. if(numbytes >= 17 && !strncmp(buf, "RTSP/1.0 200 OK\r\n", 17))
  1174. {
  1175. int ts = 0, sn = 0;
  1176. time_t init = 0;
  1177. struct sockaddr_in addrRTP;
  1178. #ifdef WINDOWSVERSION
  1179. u_long blockmode = 1;
  1180. if(ioctlsocket(sockudp, FIONBIO, &blockmode)
  1181. || ioctlsocket(sockfd, FIONBIO, &blockmode))
  1182. #else /* WINDOWSVERSION */
  1183. if(fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0
  1184. || fcntl(sockudp, F_SETFL, O_NONBLOCK) < 0)
  1185. #endif /* WINDOWSVERSION */
  1186. {
  1187. fprintf(stderr, "Could not set nonblocking mode\n");
  1188. error = 1;
  1189. }
  1190. /* fill structure with caster address information for UDP */
  1191. memset(&addrRTP, 0, sizeof(addrRTP));
  1192. addrRTP.sin_family = AF_INET;
  1193. addrRTP.sin_port = htons(serverport);
  1194. their_addr.sin_addr = *((struct in_addr *)he->h_addr);
  1195. len = sizeof(addrRTP);
  1196. while(!stop && !error)
  1197. {
  1198. char rtpbuffer[1526];
  1199. struct timeval tv = {1,0};
  1200. fd_set fdr;
  1201. fd_set fde;
  1202. int r;
  1203. FD_ZERO(&fdr);
  1204. FD_ZERO(&fde);
  1205. FD_SET(sockudp, &fdr);
  1206. FD_SET(sockfd, &fdr);
  1207. FD_SET(sockudp, &fde);
  1208. FD_SET(sockfd, &fde);
  1209. if(select((sockudp>sockfd?sockudp:sockfd)+1,
  1210. &fdr,0,&fde,&tv) < 0)
  1211. {
  1212. fprintf(stderr, "Select problem.\n");
  1213. error = 1;
  1214. continue;
  1215. }
  1216. i = recvfrom(sockudp, rtpbuffer, sizeof(rtpbuffer), 0,
  1217. (struct sockaddr*) &addrRTP, &len);
  1218. #ifndef WINDOWSVERSION
  1219. alarm(ALARMTIME);
  1220. #endif
  1221. if(i >= 12+1 && (unsigned char)rtpbuffer[0] == (2 << 6) && rtpbuffer[1] == 0x60)
  1222. {
  1223. int u,v,w;
  1224. u = ((unsigned char)rtpbuffer[2]<<8)+(unsigned char)rtpbuffer[3];
  1225. v = ((unsigned char)rtpbuffer[4]<<24)+((unsigned char)rtpbuffer[5]<<16)
  1226. +((unsigned char)rtpbuffer[6]<<8)+(unsigned char)rtpbuffer[7];
  1227. w = ((unsigned char)rtpbuffer[8]<<24)+((unsigned char)rtpbuffer[9]<<16)
  1228. +((unsigned char)rtpbuffer[10]<<8)+(unsigned char)rtpbuffer[11];
  1229. if(init)
  1230. {
  1231. time_t ct;
  1232. if(u < -30000 && sn > 30000) sn -= 0xFFFF;
  1233. if(session != w || ts > v)
  1234. {
  1235. fprintf(stderr, "Illegal UDP data received.\n");
  1236. continue;
  1237. }
  1238. else if(u > sn) /* don't show out-of-order packets */
  1239. fwrite(rtpbuffer+12, (size_t)i-12, 1, stdout);
  1240. ct = time(0);
  1241. if(ct-init > 15)
  1242. {
  1243. i = snprintf(buf, MAXDATASIZE,
  1244. "GET_PARAMETER rtsp://%s%s%s/%s RTSP/1.0\r\n"
  1245. "CSeq: %d\r\n"
  1246. "Session: %u\r\n"
  1247. "\r\n",
  1248. args.server, proxyserver ? ":" : "", proxyserver
  1249. ? args.port : "", args.data, cseq++, session);
  1250. if(i > MAXDATASIZE || i < 0)
  1251. {
  1252. fprintf(stderr, "Requested data too long\n");
  1253. stop = 1;
  1254. }
  1255. else if(send(sockfd, buf, (size_t)i, 0) != i)
  1256. {
  1257. myperror("send");
  1258. error = 1;
  1259. }
  1260. init = ct;
  1261. }
  1262. }
  1263. else
  1264. {
  1265. init = time(0);
  1266. }
  1267. sn = u; ts = v;
  1268. }
  1269. else if(i >= 0)
  1270. {
  1271. fprintf(stderr, "Illegal UDP header.\n");
  1272. continue;
  1273. }
  1274. /* ignore RTSP server replies */
  1275. if((r=recv(sockfd, buf, MAXDATASIZE-1, 0)) < 0)
  1276. {
  1277. #ifdef WINDOWSVERSION
  1278. if(WSAGetLastError() != WSAEWOULDBLOCK)
  1279. #else /* WINDOWSVERSION */
  1280. if(errno != EAGAIN)
  1281. #endif /* WINDOWSVERSION */
  1282. {
  1283. fprintf(stderr, "Control connection closed\n");
  1284. error = 1;
  1285. }
  1286. }
  1287. else if(!r)
  1288. {
  1289. fprintf(stderr, "Control connection read error\n");
  1290. error = 1;
  1291. }
  1292. }
  1293. }
  1294. i = snprintf(buf, MAXDATASIZE,
  1295. "TEARDOWN rtsp://%s%s%s/%s RTSP/1.0\r\n"
  1296. "CSeq: %d\r\n"
  1297. "Session: %u\r\n"
  1298. "\r\n",
  1299. args.server, proxyserver ? ":" : "", proxyserver ? args.port : "",
  1300. args.data, cseq++, session);
  1301. if(i > MAXDATASIZE || i < 0) /* second check for old glibc */
  1302. {
  1303. fprintf(stderr, "Requested data too long\n");
  1304. stop = 1;
  1305. }
  1306. else if(send(sockfd, buf, (size_t)i, 0) != i)
  1307. {
  1308. myperror("send");
  1309. error = 1;
  1310. }
  1311. }
  1312. else
  1313. {
  1314. fprintf(stderr, "Could not start data stream.\n");
  1315. error = 1;
  1316. }
  1317. }
  1318. }
  1319. else
  1320. {
  1321. fprintf(stderr, "Could not setup initial control connection.\n");
  1322. error = 1;
  1323. }
  1324. if(sockudp)
  1325. closesocket(sockudp);
  1326. }
  1327. }
  1328. else
  1329. {
  1330. if(connect(sockfd, (struct sockaddr *)&their_addr,
  1331. sizeof(struct sockaddr)) == -1)
  1332. {
  1333. myperror("connect");
  1334. error = 1;
  1335. }
  1336. if(!stop && !error)
  1337. {
  1338. if(!args.data)
  1339. {
  1340. i = snprintf(buf, MAXDATASIZE,
  1341. "GET %s%s%s%s/ HTTP/1.1\r\n"
  1342. "Host: %s\r\n%s"
  1343. "User-Agent: %s/%s\r\n"
  1344. "Connection: close\r\n"
  1345. "\r\n"
  1346. , proxyserver ? "http://" : "", proxyserver ? proxyserver : "",
  1347. proxyserver ? ":" : "", proxyserver ? proxyport : "",
  1348. args.server, args.mode == NTRIP1 ? "" : "Ntrip-Version: Ntrip/2.0\r\n",
  1349. AGENTSTRING, revisionstr);
  1350. }
  1351. else
  1352. {
  1353. const char *nmeahead = (args.nmea && args.mode == HTTP) ? args.nmea : 0;
  1354. i=snprintf(buf, MAXDATASIZE-40, /* leave some space for login */
  1355. "GET %s%s%s%s/%s HTTP/1.1\r\n"
  1356. "Host: %s\r\n%s"
  1357. "User-Agent: %s/%s\r\n"
  1358. "%s%s%s"
  1359. "Connection: close%s"
  1360. , proxyserver ? "http://" : "", proxyserver ? proxyserver : "",
  1361. proxyserver ? ":" : "", proxyserver ? proxyport : "",
  1362. args.data, args.server,
  1363. args.mode == NTRIP1 ? "" : "Ntrip-Version: Ntrip/2.0\r\n",
  1364. AGENTSTRING, revisionstr,
  1365. nmeahead ? "Ntrip-GGA: " : "", nmeahead ? nmeahead : "",
  1366. nmeahead ? "\r\n" : "",
  1367. (*args.user || *args.password) ? "\r\nAuthorization: Basic " : "");
  1368. if(i > MAXDATASIZE-40 || i < 0) /* second check for old glibc */
  1369. {
  1370. fprintf(stderr, "Requested data too long\n");
  1371. stop = 1;
  1372. }
  1373. else
  1374. {
  1375. i += encode(buf+i, MAXDATASIZE-i-4, args.user, args.password);
  1376. if(i > MAXDATASIZE-4)
  1377. {
  1378. fprintf(stderr, "Username and/or password too long\n");
  1379. stop = 1;
  1380. }
  1381. else
  1382. {
  1383. buf[i++] = '\r';
  1384. buf[i++] = '\n';
  1385. buf[i++] = '\r';
  1386. buf[i++] = '\n';
  1387. if(args.nmea && !nmeahead)
  1388. {
  1389. int j = snprintf(buf+i, MAXDATASIZE-i, "%s\r\n", args.nmea);
  1390. if(j >= 0 && j < MAXDATASIZE-i)
  1391. i += j;
  1392. else
  1393. {
  1394. fprintf(stderr, "NMEA string too long\n");
  1395. stop = 1;
  1396. }
  1397. }
  1398. }
  1399. }
  1400. }
  1401. }
  1402. if(!stop && !error)
  1403. {
  1404. if(send(sockfd, buf, (size_t)i, 0) != i)
  1405. {
  1406. myperror("send");
  1407. error = 1;
  1408. }
  1409. else if(args.data && *args.data != '%')
  1410. {
  1411. int k = 0;
  1412. int chunkymode = 0;
  1413. int starttime = time(0);
  1414. int lastout = starttime;
  1415. int totalbytes = 0;
  1416. int chunksize = 0;
  1417. while(!stop && !error &&
  1418. (numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) > 0)
  1419. {
  1420. #ifndef WINDOWSVERSION
  1421. alarm(ALARMTIME);
  1422. #endif
  1423. if(!k)
  1424. {
  1425. buf[numbytes] = 0; /* latest end mark for strstr */
  1426. if( numbytes > 17 &&
  1427. !strstr(buf, "ICY 200 OK") && /* case 'proxy & ntrip 1.0 caster' */
  1428. (!strncmp(buf, "HTTP/1.1 200 OK\r\n", 17) ||
  1429. !strncmp(buf, "HTTP/1.0 200 OK\r\n", 17)) )
  1430. {
  1431. const char *datacheck = "Content-Type: gnss/data\r\n";
  1432. const char *chunkycheck = "Transfer-Encoding: chunked\r\n";
  1433. int l = strlen(datacheck)-1;
  1434. int j=0;
  1435. for(i = 0; j != l && i < numbytes-l; ++i)
  1436. {
  1437. for(j = 0; j < l && buf[i+j] == datacheck[j]; ++j)
  1438. ;
  1439. }
  1440. if(i == numbytes-l)
  1441. {
  1442. fprintf(stderr, "No 'Content-Type: gnss/data' found\n");
  1443. error = 1;
  1444. }
  1445. l = strlen(chunkycheck)-1;
  1446. j=0;
  1447. for(i = 0; j != l && i < numbytes-l; ++i)
  1448. {
  1449. for(j = 0; j < l && buf[i+j] == chunkycheck[j]; ++j)
  1450. ;
  1451. }
  1452. if(i < numbytes-l)
  1453. chunkymode = 1;
  1454. }
  1455. else if(!strstr(buf, "ICY 200 OK"))
  1456. {
  1457. fprintf(stderr, "Could not get the requested data: ");
  1458. for(k = 0; k < numbytes && buf[k] != '\n' && buf[k] != '\r'; ++k)
  1459. {
  1460. fprintf(stderr, "%c", isprint(buf[k]) ? buf[k] : '.');
  1461. }
  1462. fprintf(stderr, "\n");
  1463. error = 1;
  1464. }
  1465. else if(args.mode != NTRIP1)
  1466. {
  1467. fprintf(stderr, "NTRIP version 2 HTTP connection failed%s.\n",
  1468. args.mode == AUTO ? ", falling back to NTRIP1" : "");
  1469. if(args.mode == HTTP)
  1470. stop = 1;
  1471. }
  1472. k = 1;
  1473. if(args.mode == NTRIP1)
  1474. continue; /* skip old headers for NTRIP1 */
  1475. else
  1476. {
  1477. char *ep = strstr(buf, "\r\n\r\n");
  1478. if(!ep || ep+4 == buf+numbytes)
  1479. continue;
  1480. ep += 4;
  1481. memmove(buf, ep, numbytes-(ep-buf));
  1482. numbytes -= (ep-buf);
  1483. }
  1484. }
  1485. sleeptime = 0;
  1486. if(chunkymode)
  1487. {
  1488. int cstop = 0;
  1489. int pos = 0;
  1490. while(!stop && !cstop && !error && pos < numbytes)
  1491. {
  1492. switch(chunkymode)
  1493. {
  1494. case 1: /* reading number starts */
  1495. chunksize = 0;
  1496. ++chunkymode; /* no break */
  1497. case 2: /* during reading number */
  1498. i = buf[pos++];
  1499. if(i >= '0' && i <= '9') chunksize = chunksize*16+i-'0';
  1500. else if(i >= 'a' && i <= 'f') chunksize = chunksize*16+i-'a'+10;
  1501. else if(i >= 'A' && i <= 'F') chunksize = chunksize*16+i-'A'+10;
  1502. else if(i == '\r') ++chunkymode;
  1503. else if(i == ';') chunkymode = 5;
  1504. else cstop = 1;
  1505. break;
  1506. case 3: /* scanning for return */
  1507. if(buf[pos++] == '\n') chunkymode = chunksize ? 4 : 1;
  1508. else cstop = 1;
  1509. break;
  1510. case 4: /* output data */
  1511. i = numbytes-pos;
  1512. if(i > chunksize) i = chunksize;
  1513. if(args.serdevice)
  1514. {
  1515. int ofs = 0;
  1516. while(i > ofs && !cstop && !stop && !error)
  1517. {
  1518. int j = SerialWrite(&sx, buf+pos+ofs, i-ofs);
  1519. if(j < 0)
  1520. {
  1521. fprintf(stderr, "Could not access serial device\n");
  1522. stop = 1;
  1523. }
  1524. else
  1525. ofs += j;
  1526. }
  1527. }
  1528. else
  1529. fwrite(buf+pos, (size_t)i, 1, stdout);
  1530. totalbytes += i;
  1531. chunksize -= i;
  1532. pos += i;
  1533. if(!chunksize)
  1534. chunkymode = 1;
  1535. break;
  1536. case 5:
  1537. if(i == '\r') chunkymode = 3;
  1538. break;
  1539. }
  1540. }
  1541. if(cstop)
  1542. {
  1543. fprintf(stderr, "Error in chunky transfer encoding\n");
  1544. error = 1;
  1545. }
  1546. }
  1547. else
  1548. {
  1549. totalbytes += numbytes;
  1550. if(args.serdevice)
  1551. {
  1552. int ofs = 0;
  1553. while(numbytes > ofs && !stop)
  1554. {
  1555. int i = SerialWrite(&sx, buf+ofs, numbytes-ofs);
  1556. if(i < 0)
  1557. {
  1558. fprintf(stderr, "Could not access serial device\n");
  1559. stop = 1;
  1560. }
  1561. else
  1562. ofs += i;
  1563. }
  1564. }
  1565. else
  1566. fwrite(buf, (size_t)numbytes, 1, stdout);
  1567. }
  1568. fflush(stdout);
  1569. if(totalbytes < 0) /* overflow */
  1570. {
  1571. totalbytes = 0;
  1572. starttime = time(0);
  1573. lastout = starttime;
  1574. }
  1575. if(args.serdevice && !stop)
  1576. {
  1577. int doloop = 1;
  1578. while(doloop && !stop)
  1579. {
  1580. int i = SerialRead(&sx, buf, 200);
  1581. if(i < 0)
  1582. {
  1583. fprintf(stderr, "Could not access serial device\n");
  1584. stop = 1;
  1585. }
  1586. else
  1587. {
  1588. int j = 0;
  1589. if(i < 200) doloop = 0;
  1590. fwrite(buf, i, 1, stdout);
  1591. if(ser)
  1592. fwrite(buf, i, 1, ser);
  1593. while(j < i)
  1594. {
  1595. if(nmeabufpos < 6)
  1596. {
  1597. if(nmeabuffer[nmeabufpos] != buf[j])
  1598. {
  1599. if(nmeabufpos) nmeabufpos = 0;
  1600. else ++j;
  1601. }
  1602. else
  1603. {
  1604. nmeastarpos = 0;
  1605. ++j; ++nmeabufpos;
  1606. }
  1607. }
  1608. else if((nmeastarpos && nmeabufpos == nmeastarpos + 3)
  1609. || buf[j] == '\r' || buf[j] == '\n')
  1610. {
  1611. doloop = 0;
  1612. nmeabuffer[nmeabufpos++] = '\r';
  1613. nmeabuffer[nmeabufpos++] = '\n';
  1614. if(send(sockfd, nmeabuffer, nmeabufpos, 0)
  1615. != (int)nmeabufpos)
  1616. {
  1617. fprintf(stderr, "Could not send NMEA\n");
  1618. error = 1;
  1619. }
  1620. nmeabufpos = 0;
  1621. }
  1622. else if(nmeabufpos > sizeof(nmeabuffer)-10 ||
  1623. buf[j] == '$')
  1624. nmeabufpos = 0;
  1625. else
  1626. {
  1627. if(buf[j] == '*') nmeastarpos = nmeabufpos;
  1628. nmeabuffer[nmeabufpos++] = buf[j++];
  1629. }
  1630. }
  1631. }
  1632. }
  1633. }
  1634. if(args.bitrate)
  1635. {
  1636. int t = time(0);
  1637. if(t > lastout + 60)
  1638. {
  1639. lastout = t;
  1640. fprintf(stderr, "Bitrate is %dbyte/s (%d seconds accumulated).\n",
  1641. totalbytes/(t-starttime), t-starttime);
  1642. }
  1643. }
  1644. }
  1645. }
  1646. else
  1647. {
  1648. sleeptime = 0;
  1649. while(!stop && (numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) > 0)
  1650. {
  1651. #ifndef WINDOWSVERSION
  1652. alarm(ALARMTIME);
  1653. #endif
  1654. fwrite(buf, (size_t)numbytes, 1, stdout);
  1655. }
  1656. }
  1657. }
  1658. }
  1659. }
  1660. if(sockfd)
  1661. closesocket(sockfd);
  1662. sleep(10);
  1663. } while(args.data && *args.data != '%' && !stop);
  1664. if(args.serdevice)
  1665. {
  1666. SerialFree(&sx);
  1667. }
  1668. if(ser)
  1669. fclose(ser);
  1670. }
  1671. return 0;
  1672. }