ntripserver.c 72 KB

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