Changeset 842 in ntrip for trunk/ntripclient/ntripclient.c


Ignore:
Timestamp:
Apr 22, 2008, 4:26:44 PM (16 years ago)
Author:
stoecker
Message:

added serial logfile and reconnects

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ntripclient/ntripclient.c

    r834 r842  
    11/*
    22  NTRIP client for POSIX.
    3   $Id: ntripclient.c,v 1.42 2008/04/07 11:49:13 stoecker Exp $
     3  $Id: ntripclient.c,v 1.43 2008/04/15 13:27:49 stoecker Exp $
    44  Copyright (C) 2003-2008 by Dirk Stöcker <soft@dstoecker.de>
    55
     
    5959
    6060/* CVS revision and version */
    61 static char revisionstr[] = "$Revision: 1.42 $";
    62 static char datestr[]     = "$Date: 2008/04/07 11:49:13 $";
     61static char revisionstr[] = "$Revision: 1.43 $";
     62static char datestr[]     = "$Date: 2008/04/15 13:27:49 $";
    6363
    6464enum MODE { HTTP = 1, RTSP = 2, NTRIP1 = 3, AUTO = 4, END };
     
    8585  enum SerialProtocol protocol;
    8686  const char *serdevice;
     87  const char *serlogfile;
    8788};
    8889
     
    112113{ "parity",     required_argument, 0, 'Y'},
    113114{ "databits",   required_argument, 0, 'A'},
     115{ "serlogfile", required_argument, 0, 'l'},
    114116{ "help",       no_argument,       0, 'h'},
    115117{0,0,0,0}};
    116118#endif
    117 #define ARGOPT "-d:m:bhp:r:s:u:n:S:R:M:IP:D:B:T:C:Y:A:"
     119#define ARGOPT "-d:m:bhp:r:s:u:n:S:R:M:IP:D:B:T:C:Y:A:l:"
    118120
    119121int stop = 0;
     
    150152  while(*req && urlenc < bufend)
    151153  {
    152     if(isalnum(*req) 
     154    if(isalnum(*req)
    153155    || *req == '-' || *req == '_' || *req == '.')
    154156      *urlenc++ = *req++;
     
    187189    else
    188190    {
    189        while(*url && *url != '@' &&  *url != '/' && Buffer != Bufend) 
     191       while(*url && *url != '@' &&  *url != '/' && Buffer != Bufend)
    190192       {
    191193          if(isalnum(*url) || *url == '-' || *url == '_' || *url == '.')
     
    320322  args->baud = SPABAUD_9600;
    321323  args->serdevice = 0;
     324  args->serlogfile = 0;
    322325  help = 0;
    323326
     
    333336    case 'u': args->user = optarg; break;
    334337    case 'p': args->password = optarg; break;
    335     case 'd':
     338    case 'd': /* legacy option, may get removed in future */
     339      fprintf(stderr, "Option -d or --data is deprecated. Use -m instead.\n");
    336340    case 'm':
    337       if(optarg && *optarg == '?') 
     341      if(optarg && *optarg == '?')
    338342        args->data = encodeurl(optarg);
    339       else 
    340         args->data = optarg; 
     343      else
     344        args->data = optarg;
    341345      break;
    342346    case 'B':
     
    408412      break;
    409413    case 'D': args->serdevice = optarg; break;
     414    case 'l': args->serlogfile = optarg; break;
    410415    case 'I': args->initudp = 1; break;
    411416    case 'P': args->udpport = strtol(optarg, 0, 10); break;
     
    469474    " -r " LONG_OPT("--port       ") "the server port number (default 2101)\n"
    470475    " -u " LONG_OPT("--user       ") "the user name\n"
    471     " -n " LONG_OPT("--nmea       ") "NMEA string for sending to server\n"
    472     " -b " LONG_OPT("--bitrate    ") "output bitrate\n"
    473     " -I " LONG_OPT("--initudp    ") "send initial UDP packet for firewall handling\n"
    474     " -P " LONG_OPT("--udpport    ") "set the local UDP port\n"
    475     " -S " LONG_OPT("--proxyhost  ") "proxy name or address\n"
    476     " -R " LONG_OPT("--proxyport  ") "proxy port, optional (default 2101)\n"
    477     " -D " LONG_OPT("--serdevice  ") "serial device for output\n"
    478     " -B " LONG_OPT("--baud       ") "baudrate for serial device\n"
    479     " -T " LONG_OPT("--stopbits   ") "stopbits for serial device\n"
    480     " -C " LONG_OPT("--protocol   ") "protocol for serial device\n"
    481     " -Y " LONG_OPT("--parity     ") "parity for serial device\n"
    482     " -A " LONG_OPT("--databits   ") "databits for serial device\n"
    483476    " -M " LONG_OPT("--mode       ") "mode for data request\n"
    484477    "     Valid modes are:\n"
     
    488481    "     4, a, auto     automatic detection (default)\n"
    489482    "or using an URL:\n%s ntrip:mountpoint[/user[:password]][@[server][:port][@proxyhost[:proxyport]]][;nmea]\n"
     483    "\nExpert options:\n"
     484    " -n " LONG_OPT("--nmea       ") "NMEA string for sending to server\n"
     485    " -b " LONG_OPT("--bitrate    ") "output bitrate\n"
     486    " -I " LONG_OPT("--initudp    ") "send initial UDP packet for firewall handling\n"
     487    " -P " LONG_OPT("--udpport    ") "set the local UDP port\n"
     488    " -S " LONG_OPT("--proxyhost  ") "proxy name or address\n"
     489    " -R " LONG_OPT("--proxyport  ") "proxy port, optional (default 2101)\n"
     490    "\nSerial input/output:\n"
     491    " -D " LONG_OPT("--serdevice  ") "serial device for output\n"
     492    " -B " LONG_OPT("--baud       ") "baudrate for serial device\n"
     493    " -T " LONG_OPT("--stopbits   ") "stopbits for serial device\n"
     494    " -C " LONG_OPT("--protocol   ") "protocol for serial device\n"
     495    " -Y " LONG_OPT("--parity     ") "parity for serial device\n"
     496    " -A " LONG_OPT("--databits   ") "databits for serial device\n"
     497    " -l " LONG_OPT("--serlogfile ") "logfile for serial data\n"
    490498    , revisionstr, datestr, argv[0], argv[0]);
    491499    exit(1);
     
    566574  {
    567575    struct serial sx;
     576    FILE *ser = 0;
    568577    char nmeabuffer[200] = "$GPGGA,"; /* our start string */
    569578    size_t nmeabufpos = 0;
     
    579588        return 20;
    580589      }
     590      if(args.serlogfile)
     591      {
     592        if(!(ser = fopen(args.serlogfile, "a+")))
     593        {
     594          SerialFree(&sx);
     595          fprintf(stderr, "Could not open serial logfile.\n");
     596          return 20;
     597        }
     598      }
    581599    }
    582600    do
    583601    {
    584       sockettype sockfd;
    585       int numbytes; 
     602      int error = 0;
     603      sockettype sockfd = 0;
     604      int numbytes;
    586605      char buf[MAXDATASIZE];
    587606      struct sockaddr_in their_addr; /* connector's address information */
     
    616635        {
    617636          fprintf(stderr, "Can't resolve port %s.", args.port);
    618           exit(1);
     637          stop = 1;
    619638        }
    620639        else
     
    622641          p = ntohs(se->s_port);
    623642        }
    624         snprintf(proxyport, sizeof(proxyport), "%d", p);
    625         port = args.proxyport;
    626         proxyserver = args.server;
    627         server = args.proxyhost;
     643        if(!stop && !error)
     644        {
     645          snprintf(proxyport, sizeof(proxyport), "%d", p);
     646          port = args.proxyport;
     647          proxyserver = args.server;
     648          server = args.proxyhost;
     649        }
    628650      }
    629651      else
     
    632654        port = args.port;
    633655      }
    634       memset(&their_addr, 0, sizeof(struct sockaddr_in));
    635       if((i = strtol(port, &b, 10)) && (!b || !*b))
    636         their_addr.sin_port = htons(i);
    637       else if(!(se = getservbyname(port, 0)))
    638       {
    639         fprintf(stderr, "Can't resolve port %s.", port);
    640         exit(1);
    641       }
    642       else
    643       {
    644         their_addr.sin_port = se->s_port;
    645       }
    646       if(!(he=gethostbyname(server)))
    647       {
    648         fprintf(stderr, "Server name lookup failed for '%s'.\n", server);
    649         exit(1);
    650       }
    651       if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    652       {
    653         perror("socket");
    654         exit(1);
    655       }
    656       their_addr.sin_family = AF_INET;
    657       their_addr.sin_addr = *((struct in_addr *)he->h_addr);
    658 
    659       if(args.data && *args.data != '%' && args.mode == RTSP)
    660       {
    661         struct sockaddr_in local;
    662         int sockudp, localport;
    663         int cseq = 1;
    664         socklen_t len;
    665 
    666         if((sockudp = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
     656      if(!stop && !error)
     657      {
     658        memset(&their_addr, 0, sizeof(struct sockaddr_in));
     659        if((i = strtol(port, &b, 10)) && (!b || !*b))
     660          their_addr.sin_port = htons(i);
     661        else if(!(se = getservbyname(port, 0)))
    667662        {
    668           perror("socket");
    669           exit(1);
    670         }
    671         /* fill structure with local address information for UDP */
    672         memset(&local, 0, sizeof(local));
    673         local.sin_family = AF_INET;
    674         local.sin_port = htons(args.udpport);
    675         local.sin_addr.s_addr = htonl(INADDR_ANY);
    676         len = sizeof(local);
    677         /* bind() in order to get a random RTP client_port */
    678         if((bind(sockudp, (struct sockaddr *)&local, len)) < 0)
    679         {
    680           perror("bind");
    681           exit(1);
    682         }
    683         if((getsockname(sockudp, (struct sockaddr*)&local, &len)) != -1)
    684         {
    685           localport = ntohs(local.sin_port);
     663          fprintf(stderr, "Can't resolve port %s.", port);
     664          stop = 1;
    686665        }
    687666        else
    688667        {
    689           perror("local access failed");
    690           exit(1);
     668          their_addr.sin_port = se->s_port;
    691669        }
    692         if(connect(sockfd, (struct sockaddr *)&their_addr,
    693         sizeof(struct sockaddr)) == -1)
     670        if(!stop && !error)
    694671        {
    695           perror("connect");
    696           exit(1);
    697         }
    698         i=snprintf(buf, MAXDATASIZE-40, /* leave some space for login */
    699         "SETUP rtsp://%s%s%s/%s RTSP/1.0\r\n"           
    700         "CSeq: %d\r\n"         
    701         "Ntrip-Version: Ntrip/2.0\r\n"
    702         "Ntrip-Component: Ntripclient\r\n"
    703         "User-Agent: %s/%s\r\n"
    704         "Transport: RTP/GNSS;unicast;client_port=%u\r\n"
    705         "Authorization: Basic ",
    706         args.server, proxyserver ? ":" : "", proxyserver ? args.port : "",
    707         args.data, cseq++, AGENTSTRING, revisionstr, localport);
    708         if(i > MAXDATASIZE-40 || i < 0) /* second check for old glibc */
    709         {
    710           fprintf(stderr, "Requested data too long\n");
    711           exit(1);
    712         }
    713         i += encode(buf+i, MAXDATASIZE-i-4, args.user, args.password);
    714         if(i > MAXDATASIZE-4)
    715         {
    716           fprintf(stderr, "Username and/or password too long\n");
    717           exit(1);
    718         }
    719         buf[i++] = '\r';
    720         buf[i++] = '\n';
    721         buf[i++] = '\r';
    722         buf[i++] = '\n';
    723         if(args.nmea)
    724         {
    725           int j = snprintf(buf+i, MAXDATASIZE-i, "%s\r\n", args.nmea);
    726           if(j >= 0 && j < MAXDATASIZE-i)
    727             i += j;
     672          if(!(he=gethostbyname(server)))
     673          {
     674            fprintf(stderr, "Server name lookup failed for '%s'.\n", server);
     675            error = 1;
     676          }
     677          else if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
     678          {
     679            perror("socket");
     680            error = 1;
     681          }
    728682          else
    729683          {
    730             fprintf(stderr, "NMEA string too long\n");
    731             exit(1);
     684            their_addr.sin_family = AF_INET;
     685            their_addr.sin_addr = *((struct in_addr *)he->h_addr);
    732686          }
    733687        }
    734         if(send(sockfd, buf, (size_t)i, 0) != i)
     688      }
     689      if(!stop && !error)
     690      {
     691        if(args.data && *args.data != '%' && args.mode == RTSP)
    735692        {
    736           perror("send");
    737           exit(1);
    738         }
    739         if((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) != -1)
    740         {
    741           if(numbytes >= 17 && !strncmp(buf, "RTSP/1.0 200 OK\r\n", 17))
     693          struct sockaddr_in local;
     694          sockettype sockudp = 0;
     695          int localport;
     696          int cseq = 1;
     697          socklen_t len;
     698
     699          if((sockudp = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
    742700          {
    743             int serverport = 0, session = 0;
    744             const char *portcheck = "server_port=";
    745             const char *sessioncheck = "session: ";
    746             int l = strlen(portcheck)-1;
    747             int j=0;
    748             for(i = 0; j != l && i < numbytes-l; ++i)
    749             {
    750               for(j = 0; j < l && tolower(buf[i+j]) == portcheck[j]; ++j)
    751                 ;
    752             }
    753             if(i == numbytes-l)
    754             {
    755               fprintf(stderr, "No server port number found\n");
    756               exit(1);
    757             }
    758             else
    759             {
    760               i+=l;
    761               while(i < numbytes && buf[i] >= '0' && buf[i] <= '9')
    762                 serverport = serverport * 10 + buf[i++]-'0';
    763               if(buf[i] != '\r' && buf[i] != ';')
     701            perror("socket");
     702            error = 1;
     703          }
     704          if(!stop && !error)
     705          {
     706            /* fill structure with local address information for UDP */
     707            memset(&local, 0, sizeof(local));
     708            local.sin_family = AF_INET;
     709            local.sin_port = htons(args.udpport);
     710            local.sin_addr.s_addr = htonl(INADDR_ANY);
     711            len = sizeof(local);
     712            /* bind() in order to get a random RTP client_port */
     713            if((bind(sockudp, (struct sockaddr *)&local, len)) < 0)
     714            {
     715              perror("bind");
     716              error = 1;
     717            }
     718            else if((getsockname(sockudp, (struct sockaddr*)&local, &len)) == -1)
     719            {
     720              perror("local access failed");
     721              error = 1;
     722            }
     723            else if(connect(sockfd, (struct sockaddr *)&their_addr,
     724            sizeof(struct sockaddr)) == -1)
     725            {
     726              perror("connect");
     727              error = 1;
     728            }
     729            localport = ntohs(local.sin_port);
     730          }
     731          if(!stop && !error)
     732          {
     733            i=snprintf(buf, MAXDATASIZE-40, /* leave some space for login */
     734            "SETUP rtsp://%s%s%s/%s RTSP/1.0\r\n"
     735            "CSeq: %d\r\n"
     736            "Ntrip-Version: Ntrip/2.0\r\n"
     737            "Ntrip-Component: Ntripclient\r\n"
     738            "User-Agent: %s/%s\r\n"
     739            "Transport: RTP/GNSS;unicast;client_port=%u\r\n"
     740            "Authorization: Basic ",
     741            args.server, proxyserver ? ":" : "", proxyserver ? args.port : "",
     742            args.data, cseq++, AGENTSTRING, revisionstr, localport);
     743            if(i > MAXDATASIZE-40 || i < 0) /* second check for old glibc */
     744            {
     745              fprintf(stderr, "Requested data too long\n");
     746              stop = 1;
     747            }
     748            i += encode(buf+i, MAXDATASIZE-i-4, args.user, args.password);
     749            if(i > MAXDATASIZE-4)
     750            {
     751              fprintf(stderr, "Username and/or password too long\n");
     752              stop = 1;
     753            }
     754            buf[i++] = '\r';
     755            buf[i++] = '\n';
     756            buf[i++] = '\r';
     757            buf[i++] = '\n';
     758            if(args.nmea)
     759            {
     760              int j = snprintf(buf+i, MAXDATASIZE-i, "%s\r\n", args.nmea);
     761              if(j >= 0 && j < MAXDATASIZE-i)
     762                i += j;
     763              else
    764764              {
    765                 fprintf(stderr, "Could not extract server port\n");
    766                 exit(1);
     765                fprintf(stderr, "NMEA string too long\n");
     766                stop = 1;
    767767              }
    768768            }
    769             l = strlen(sessioncheck)-1;
    770             j=0;
    771             for(i = 0; j != l && i < numbytes-l; ++i)
    772             {
    773               for(j = 0; j < l && tolower(buf[i+j]) == sessioncheck[j]; ++j)
    774                 ;
    775             }
    776             if(i == numbytes-l)
    777             {
    778               fprintf(stderr, "No session number found\n");
    779               exit(1);
    780             }
    781             else
    782             {
    783               i+=l;
    784               while(i < numbytes && buf[i] >= '0' && buf[i] <= '9')
    785                 session = session * 10 + buf[i++]-'0';
    786               if(buf[i] != '\r')
     769          }
     770          if(!stop && !error)
     771          {
     772            if(send(sockfd, buf, (size_t)i, 0) != i)
     773            {
     774              perror("send");
     775              error = 1;
     776            }
     777            else if((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1)
     778            {
     779              perror("recv");
     780              error = 1;
     781            }
     782            else if(numbytes >= 17 && !strncmp(buf, "RTSP/1.0 200 OK\r\n", 17))
     783            {
     784              int serverport = 0, session = 0;
     785              const char *portcheck = "server_port=";
     786              const char *sessioncheck = "session: ";
     787              int l = strlen(portcheck)-1;
     788              int j=0;
     789              for(i = 0; j != l && i < numbytes-l; ++i)
    787790              {
    788                 fprintf(stderr, "Could not extract session number\n");
    789                 exit(1);
     791                for(j = 0; j < l && tolower(buf[i+j]) == portcheck[j]; ++j)
     792                  ;
    790793              }
    791             }
    792             if(args.initudp)
    793             {
    794               printf("Sending initial UDP packet\n");
    795               struct sockaddr_in casterRTP;
    796               char rtpbuffer[12];
    797               int i;
    798               rtpbuffer[0] = (2<<6);
    799               /* padding, extension, csrc are empty */
    800               rtpbuffer[1] = 96;
    801               /* marker is empty */
    802               rtpbuffer[2] = 0;
    803               rtpbuffer[3] = 0;
    804               rtpbuffer[4] = 0;
    805               rtpbuffer[5] = 0;
    806               rtpbuffer[6] = 0;
    807               rtpbuffer[7] = 0;
    808               /* sequence and timestamp are empty */
    809               rtpbuffer[8] = (session>>24)&0xFF;
    810               rtpbuffer[9] = (session>>16)&0xFF;
    811               rtpbuffer[10] = (session>>8)&0xFF;
    812               rtpbuffer[11] = (session)&0xFF;
    813               /* fill structure with caster address information for UDP */
    814               memset(&casterRTP, 0, sizeof(casterRTP));
    815               casterRTP.sin_family = AF_INET;
    816               casterRTP.sin_port   = htons(serverport);
    817               casterRTP.sin_addr   = *((struct in_addr *)he->h_addr);
    818 
    819               if((i = sendto(sockudp, rtpbuffer, 12, 0,
    820               (struct sockaddr *) &casterRTP, sizeof(casterRTP))) != 12)
    821                 perror("WARNING: could not send initial UDP packet");
    822             }
    823 
    824             i = snprintf(buf, MAXDATASIZE,
    825             "PLAY rtsp://%s%s%s/%s RTSP/1.0\r\n"               
    826             "CSeq: %d\r\n"
    827             "Session: %d\r\n"
    828             "\r\n",
    829             args.server, proxyserver ? ":" : "", proxyserver ? args.port : "",
    830             args.data, cseq++, session);
    831 
    832             if(i > MAXDATASIZE || i < 0) /* second check for old glibc */
    833             {
    834               fprintf(stderr, "Requested data too long\n");
    835               exit(1);
    836             }
    837             if(send(sockfd, buf, (size_t)i, 0) != i)
    838             {
    839               perror("send");
    840               exit(1);
    841             }
    842             if((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) != -1)
    843             {
    844               if(numbytes >= 17 && !strncmp(buf, "RTSP/1.0 200 OK\r\n", 17))
     794              if(i == numbytes-l)
    845795              {
    846                 struct sockaddr_in addrRTP;
    847                 /* fill structure with caster address information for UDP */
    848                 memset(&addrRTP, 0, sizeof(addrRTP));
    849                 addrRTP.sin_family = AF_INET; 
    850                 addrRTP.sin_port   = htons(serverport);
    851                 their_addr.sin_addr = *((struct in_addr *)he->h_addr);
    852                 len = sizeof(addrRTP);
    853                 int ts = 0;
    854                 int sn = 0;
    855                 int ssrc = 0;
    856                 int init = 0;
    857                 int u, v, w;
    858                 while(!stop && (i = recvfrom(sockudp, buf, 1526, 0,
    859                 (struct sockaddr*) &addrRTP, &len)) > 0)
     796                fprintf(stderr, "No server port number found\n");
     797                stop = 1;
     798              }
     799              else
     800              {
     801                i+=l;
     802                while(i < numbytes && buf[i] >= '0' && buf[i] <= '9')
     803                  serverport = serverport * 10 + buf[i++]-'0';
     804                if(buf[i] != '\r' && buf[i] != ';')
    860805                {
    861 #ifndef WINDOWSVERSION
    862                   alarm(ALARMTIME);
    863 #endif
    864                   if(i >= 12+1 && (unsigned char)buf[0] == (2 << 6) && buf[1] == 0x60)
     806                  fprintf(stderr, "Could not extract server port\n");
     807                  stop = 1;
     808                }
     809              }
     810              if(!stop && !error)
     811              {
     812                l = strlen(sessioncheck)-1;
     813                j=0;
     814                for(i = 0; j != l && i < numbytes-l; ++i)
     815                {
     816                  for(j = 0; j < l && tolower(buf[i+j]) == sessioncheck[j]; ++j)
     817                    ;
     818                }
     819                if(i == numbytes-l)
     820                {
     821                  fprintf(stderr, "No session number found\n");
     822                  stop = 1;
     823                }
     824                else
     825                {
     826                  i+=l;
     827                  while(i < numbytes && buf[i] >= '0' && buf[i] <= '9')
     828                    session = session * 10 + buf[i++]-'0';
     829                  if(buf[i] != '\r')
    865830                  {
    866                     u= ((unsigned char)buf[2]<<8)+(unsigned char)buf[3];
    867                     v = ((unsigned char)buf[4]<<24)+((unsigned char)buf[5]<<16)
    868                     +((unsigned char)buf[6]<<8)+(unsigned char)buf[7];
    869                     w = ((unsigned char)buf[8]<<24)+((unsigned char)buf[9]<<16)
    870                     +((unsigned char)buf[10]<<8)+(unsigned char)buf[11];
    871 
    872                     if(init)
    873                     {
    874                       if(u < -30000 && sn > 30000) sn -= 0xFFFF;
    875                       if(ssrc != w || ts > v)
    876                       {
    877                         fprintf(stderr, "Illegal UDP data received.\n");
    878                         exit(1);
    879                       }
    880                       if(u > sn) /* don't show out-of-order packets */
    881                         fwrite(buf+12, (size_t)i-12, 1, stdout);
    882                     }
    883                     sn = u; ts = v; ssrc = w; init = 1;
    884                   }
    885                   else
    886                   {
    887                     fprintf(stderr, "Illegal UDP header.\n");
    888                     exit(1);
     831                    fprintf(stderr, "Could not extract session number\n");
     832                    stop = 1;
    889833                  }
    890834                }
    891835              }
    892               i = snprintf(buf, MAXDATASIZE,
    893               "TEARDOWN rtsp://%s%s%s/%s RTSP/1.0\r\n"         
    894               "CSeq: %d\r\n"
    895               "Session: %d\r\n"
    896               "\r\n",
    897               args.server, proxyserver ? ":" : "", proxyserver ? args.port : "",
    898               args.data, cseq++, session);
    899 
    900               if(i > MAXDATASIZE || i < 0) /* second check for old glibc */
     836              if(!stop && !error && args.initudp)
    901837              {
    902                 fprintf(stderr, "Requested data too long\n");
    903                 exit(1);
     838                printf("Sending initial UDP packet\n");
     839                struct sockaddr_in casterRTP;
     840                char rtpbuffer[12];
     841                int i;
     842                rtpbuffer[0] = (2<<6);
     843                /* padding, extension, csrc are empty */
     844                rtpbuffer[1] = 96;
     845                /* marker is empty */
     846                rtpbuffer[2] = 0;
     847                rtpbuffer[3] = 0;
     848                rtpbuffer[4] = 0;
     849                rtpbuffer[5] = 0;
     850                rtpbuffer[6] = 0;
     851                rtpbuffer[7] = 0;
     852                /* sequence and timestamp are empty */
     853                rtpbuffer[8] = (session>>24)&0xFF;
     854                rtpbuffer[9] = (session>>16)&0xFF;
     855                rtpbuffer[10] = (session>>8)&0xFF;
     856                rtpbuffer[11] = (session)&0xFF;
     857                /* fill structure with caster address information for UDP */
     858                memset(&casterRTP, 0, sizeof(casterRTP));
     859                casterRTP.sin_family = AF_INET;
     860                casterRTP.sin_port   = htons(serverport);
     861                casterRTP.sin_addr   = *((struct in_addr *)he->h_addr);
     862
     863                if((i = sendto(sockudp, rtpbuffer, 12, 0,
     864                (struct sockaddr *) &casterRTP, sizeof(casterRTP))) != 12)
     865                  perror("WARNING: could not send initial UDP packet");
    904866              }
    905               if(send(sockfd, buf, (size_t)i, 0) != i)
     867              if(!stop && !error)
    906868              {
    907                 perror("send");
    908                 exit(1);
     869                i = snprintf(buf, MAXDATASIZE,
     870                "PLAY rtsp://%s%s%s/%s RTSP/1.0\r\n"
     871                "CSeq: %d\r\n"
     872                "Session: %d\r\n"
     873                "\r\n",
     874                args.server, proxyserver ? ":" : "", proxyserver ? args.port : "",
     875                args.data, cseq++, session);
     876
     877                if(i > MAXDATASIZE || i < 0) /* second check for old glibc */
     878                {
     879                  fprintf(stderr, "Requested data too long\n");
     880                  stop=1;
     881                }
     882                else if(send(sockfd, buf, (size_t)i, 0) != i)
     883                {
     884                  perror("send");
     885                  error = 1;
     886                }
     887                else if((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) != -1)
     888                {
     889                  if(numbytes >= 17 && !strncmp(buf, "RTSP/1.0 200 OK\r\n", 17))
     890                  {
     891                    struct sockaddr_in addrRTP;
     892                    /* fill structure with caster address information for UDP */
     893                    memset(&addrRTP, 0, sizeof(addrRTP));
     894                    addrRTP.sin_family = AF_INET;
     895                    addrRTP.sin_port   = htons(serverport);
     896                    their_addr.sin_addr = *((struct in_addr *)he->h_addr);
     897                    len = sizeof(addrRTP);
     898                    int ts = 0;
     899                    int sn = 0;
     900                    int ssrc = 0;
     901                    int init = 0;
     902                    int u, v, w;
     903                    while(!stop && !error && (i = recvfrom(sockudp, buf, 1526, 0,
     904                    (struct sockaddr*) &addrRTP, &len)) > 0)
     905                    {
     906#ifndef WINDOWSVERSION
     907                      alarm(ALARMTIME);
     908#endif
     909                      if(i >= 12+1 && (unsigned char)buf[0] == (2 << 6) && buf[1] == 0x60)
     910                      {
     911                        u= ((unsigned char)buf[2]<<8)+(unsigned char)buf[3];
     912                        v = ((unsigned char)buf[4]<<24)+((unsigned char)buf[5]<<16)
     913                        +((unsigned char)buf[6]<<8)+(unsigned char)buf[7];
     914                        w = ((unsigned char)buf[8]<<24)+((unsigned char)buf[9]<<16)
     915                        +((unsigned char)buf[10]<<8)+(unsigned char)buf[11];
     916
     917                        if(init)
     918                        {
     919                          if(u < -30000 && sn > 30000) sn -= 0xFFFF;
     920                          if(ssrc != w || ts > v)
     921                          {
     922                            fprintf(stderr, "Illegal UDP data received.\n");
     923                            continue;
     924                          }
     925                          else if(u > sn) /* don't show out-of-order packets */
     926                            fwrite(buf+12, (size_t)i-12, 1, stdout);
     927                        }
     928                        sn = u; ts = v; ssrc = w; init = 1;
     929                      }
     930                      else
     931                      {
     932                        fprintf(stderr, "Illegal UDP header.\n");
     933                        continue;
     934                      }
     935                    }
     936                  }
     937                  i = snprintf(buf, MAXDATASIZE,
     938                  "TEARDOWN rtsp://%s%s%s/%s RTSP/1.0\r\n"
     939                  "CSeq: %d\r\n"
     940                  "Session: %d\r\n"
     941                  "\r\n",
     942                  args.server, proxyserver ? ":" : "", proxyserver ? args.port : "",
     943                  args.data, cseq++, session);
     944
     945                  if(i > MAXDATASIZE || i < 0) /* second check for old glibc */
     946                  {
     947                    fprintf(stderr, "Requested data too long\n");
     948                    stop = 1;
     949                  }
     950                  else if(send(sockfd, buf, (size_t)i, 0) != i)
     951                  {
     952                    perror("send");
     953                    error = 1;
     954                  }
     955                }
     956                else
     957                {
     958                  fprintf(stderr, "Could not start data stream.\n");
     959                  error = 1;
     960                }
    909961              }
    910962            }
    911963            else
    912964            {
    913               fprintf(stderr, "Could not start data stream.\n");
    914               exit(1);
    915             }
    916           }
    917           else
    918           {
    919             fprintf(stderr, "Could not setup initial control connection.\n");
    920             exit(1);
     965              fprintf(stderr, "Could not setup initial control connection.\n");
     966              error = 1;
     967            }
     968            if(sockudp)
     969              closesocket(sockudp);
    921970          }
    922971        }
    923972        else
    924973        {
    925           perror("recv");
    926           exit(1);
    927         }
    928       }
    929       else
    930       {
    931         if(connect(sockfd, (struct sockaddr *)&their_addr,
    932         sizeof(struct sockaddr)) == -1)
    933         {
    934           perror("connect");
    935           exit(1);
    936         }
    937         if(!args.data)
    938         {
    939           i = snprintf(buf, MAXDATASIZE,
    940           "GET %s%s%s%s/ HTTP/1.0\r\n"
    941           "Host: %s\r\n%s"
    942           "User-Agent: %s/%s\r\n"
    943           "Connection: close\r\n"
    944           "\r\n"
    945           , proxyserver ? "http://" : "", proxyserver ? proxyserver : "",
    946           proxyserver ? ":" : "", proxyserver ? proxyport : "",
    947           args.server, args.mode == NTRIP1 ? "" : "Ntrip-Version: Ntrip/2.0\r\n",
    948           AGENTSTRING, revisionstr);
    949         }
    950         else
    951         {
    952           i=snprintf(buf, MAXDATASIZE-40, /* leave some space for login */
    953           "GET %s%s%s%s/%s HTTP/1.0\r\n"
    954           "Host: %s\r\n%s"
    955           "User-Agent: %s/%s\r\n"
    956           "Connection: close\r\n"
    957           "Authorization: Basic "
    958           , proxyserver ? "http://" : "", proxyserver ? proxyserver : "",
    959           proxyserver ? ":" : "", proxyserver ? proxyport : "",
    960           args.data, args.server,
    961           args.mode == NTRIP1 ? "" : "Ntrip-Version: Ntrip/2.0\r\n",
    962           AGENTSTRING, revisionstr);
    963           if(i > MAXDATASIZE-40 || i < 0) /* second check for old glibc */
     974          if(connect(sockfd, (struct sockaddr *)&their_addr,
     975          sizeof(struct sockaddr)) == -1)
    964976          {
    965             fprintf(stderr, "Requested data too long\n");
    966             exit(1);
     977            perror("connect");
     978            error = 1;
    967979          }
    968           i += encode(buf+i, MAXDATASIZE-i-4, args.user, args.password);
    969           if(i > MAXDATASIZE-4)
     980          if(!stop && !error)
    970981          {
    971             fprintf(stderr, "Username and/or password too long\n");
    972             exit(1);
     982            if(!args.data)
     983            {
     984              i = snprintf(buf, MAXDATASIZE,
     985              "GET %s%s%s%s/ HTTP/1.0\r\n"
     986              "Host: %s\r\n%s"
     987              "User-Agent: %s/%s\r\n"
     988              "Connection: close\r\n"
     989              "\r\n"
     990              , proxyserver ? "http://" : "", proxyserver ? proxyserver : "",
     991              proxyserver ? ":" : "", proxyserver ? proxyport : "",
     992              args.server, args.mode == NTRIP1 ? "" : "Ntrip-Version: Ntrip/2.0\r\n",
     993              AGENTSTRING, revisionstr);
     994            }
     995            else
     996            {
     997              i=snprintf(buf, MAXDATASIZE-40, /* leave some space for login */
     998              "GET %s%s%s%s/%s HTTP/1.0\r\n"
     999              "Host: %s\r\n%s"
     1000              "User-Agent: %s/%s\r\n"
     1001              "Connection: close\r\n"
     1002              "Authorization: Basic "
     1003              , proxyserver ? "http://" : "", proxyserver ? proxyserver : "",
     1004              proxyserver ? ":" : "", proxyserver ? proxyport : "",
     1005              args.data, args.server,
     1006              args.mode == NTRIP1 ? "" : "Ntrip-Version: Ntrip/2.0\r\n",
     1007              AGENTSTRING, revisionstr);
     1008              if(i > MAXDATASIZE-40 || i < 0) /* second check for old glibc */
     1009              {
     1010                fprintf(stderr, "Requested data too long\n");
     1011                stop = 1;
     1012              }
     1013              else
     1014              {
     1015                i += encode(buf+i, MAXDATASIZE-i-4, args.user, args.password);
     1016                if(i > MAXDATASIZE-4)
     1017                {
     1018                  fprintf(stderr, "Username and/or password too long\n");
     1019                  stop = 1;
     1020                }
     1021                else
     1022                {
     1023                  buf[i++] = '\r';
     1024                  buf[i++] = '\n';
     1025                  buf[i++] = '\r';
     1026                  buf[i++] = '\n';
     1027                  if(args.nmea)
     1028                  {
     1029                    int j = snprintf(buf+i, MAXDATASIZE-i, "%s\r\n", args.nmea);
     1030                    if(j >= 0 && j < MAXDATASIZE-i)
     1031                      i += j;
     1032                    else
     1033                    {
     1034                      fprintf(stderr, "NMEA string too long\n");
     1035                      stop = 1;
     1036                    }
     1037                  }
     1038                }
     1039              }
     1040            }
    9731041          }
    974           buf[i++] = '\r';
    975           buf[i++] = '\n';
    976           buf[i++] = '\r';
    977           buf[i++] = '\n';
    978           if(args.nmea)
     1042          if(!stop && !error)
    9791043          {
    980             int j = snprintf(buf+i, MAXDATASIZE-i, "%s\r\n", args.nmea);
    981             if(j >= 0 && j < MAXDATASIZE-i)
    982               i += j;
    983             else
    984             {
    985               fprintf(stderr, "NMEA string too long\n");
    986               exit(1);
    987             }
    988           }
    989         }
    990         if(send(sockfd, buf, (size_t)i, 0) != i)
    991         {
    992           perror("send");
    993           exit(1);
    994         }
    995         if(args.data && *args.data != '%')
    996         {
    997           int k = 0;
    998           int chunkymode = 0;
    999           int starttime = time(0);
    1000           int lastout = starttime;
    1001           int totalbytes = 0;
    1002           int chunksize = 0;
    1003 
    1004           while(!stop && (numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) > 0)
    1005           {
     1044            if(send(sockfd, buf, (size_t)i, 0) != i)
     1045            {
     1046              perror("send");
     1047              error = 1;
     1048            }
     1049            else if(args.data && *args.data != '%')
     1050            {
     1051              int k = 0;
     1052              int chunkymode = 0;
     1053              int starttime = time(0);
     1054              int lastout = starttime;
     1055              int totalbytes = 0;
     1056              int chunksize = 0;
     1057
     1058              while(!stop && !error &&
     1059              (numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) > 0)
     1060              {
    10061061#ifndef WINDOWSVERSION
    1007             alarm(ALARMTIME);
     1062                alarm(ALARMTIME);
    10081063#endif
    1009             if(!k)
    1010             {
    1011               if( numbytes > 17 &&
    1012                  !strstr(buf, "ICY 200 OK")  &&  /* case 'proxy & ntrip 1.0 caster' */
    1013                  (!strncmp(buf, "HTTP/1.1 200 OK\r\n", 17) ||
    1014                   !strncmp(buf, "HTTP/1.0 200 OK\r\n", 17)) )
    1015               {
    1016                 const char *datacheck = "Content-Type: gnss/data\r\n";
    1017                 const char *chunkycheck = "Transfer-Encoding: chunked\r\n";
    1018                 int l = strlen(datacheck)-1;
    1019                 int j=0;
    1020                 for(i = 0; j != l && i < numbytes-l; ++i)
     1064                if(!k)
    10211065                {
    1022                   for(j = 0; j < l && buf[i+j] == datacheck[j]; ++j)
    1023                     ;
     1066                  if( numbytes > 17 &&
     1067                    !strstr(buf, "ICY 200 OK")  &&  /* case 'proxy & ntrip 1.0 caster' */
     1068                    (!strncmp(buf, "HTTP/1.1 200 OK\r\n", 17) ||
     1069                    !strncmp(buf, "HTTP/1.0 200 OK\r\n", 17)) )
     1070                  {
     1071                    const char *datacheck = "Content-Type: gnss/data\r\n";
     1072                    const char *chunkycheck = "Transfer-Encoding: chunked\r\n";
     1073                    int l = strlen(datacheck)-1;
     1074                    int j=0;
     1075                    for(i = 0; j != l && i < numbytes-l; ++i)
     1076                    {
     1077                      for(j = 0; j < l && buf[i+j] == datacheck[j]; ++j)
     1078                        ;
     1079                    }
     1080                    if(i == numbytes-l)
     1081                    {
     1082                      fprintf(stderr, "No 'Content-Type: gnss/data' found\n");
     1083                      error = 1;
     1084                    }
     1085                    l = strlen(chunkycheck)-1;
     1086                    j=0;
     1087                    for(i = 0; j != l && i < numbytes-l; ++i)
     1088                    {
     1089                      for(j = 0; j < l && buf[i+j] == chunkycheck[j]; ++j)
     1090                        ;
     1091                    }
     1092                    if(i < numbytes-l)
     1093                      chunkymode = 1;
     1094                  }
     1095                  else if(!strstr(buf, "ICY 200 OK"))
     1096                  {
     1097                    fprintf(stderr, "Could not get the requested data: ");
     1098                    for(k = 0; k < numbytes && buf[k] != '\n' && buf[k] != '\r'; ++k)
     1099                    {
     1100                      fprintf(stderr, "%c", isprint(buf[k]) ? buf[k] : '.');
     1101                    }
     1102                    fprintf(stderr, "\n");
     1103                    error = 1;
     1104                  }
     1105                  else if(args.mode != NTRIP1)
     1106                  {
     1107                    fprintf(stderr, "NTRIP version 2 HTTP connection failed%s.\n",
     1108                    args.mode == AUTO ? ", falling back to NTRIP1" : "");
     1109                    if(args.mode == HTTP)
     1110                      stop = 1;
     1111                  }
     1112                  ++k;
    10241113                }
    1025                 if(i == numbytes-l)
     1114                else
    10261115                {
    1027                   fprintf(stderr, "No 'Content-Type: gnss/data' found\n");
    1028                   exit(1);
    1029                 }
    1030                 l = strlen(chunkycheck)-1;
    1031                 j=0;
    1032                 for(i = 0; j != l && i < numbytes-l; ++i)
    1033                 {
    1034                   for(j = 0; j < l && buf[i+j] == chunkycheck[j]; ++j)
    1035                     ;
    1036                 }
    1037                 if(i < numbytes-l)
    1038                   chunkymode = 1;
    1039               }
    1040               else if(!strstr(buf, "ICY 200 OK"))
    1041               {
    1042                 fprintf(stderr, "Could not get the requested data: ");
    1043                 for(k = 0; k < numbytes && buf[k] != '\n' && buf[k] != '\r'; ++k)
    1044                 {
    1045                   fprintf(stderr, "%c", isprint(buf[k]) ? buf[k] : '.');
    1046                 }
    1047                 fprintf(stderr, "\n");
    1048                 exit(1);
    1049               }
    1050               else if(args.mode != NTRIP1)
    1051               {
    1052                 fprintf(stderr, "NTRIP version 2 HTTP connection failed%s.\n",
    1053                 args.mode == AUTO ? ", falling back to NTRIP1" : "");
    1054                 if(args.mode == HTTP)
    1055                   exit(1);
    1056               }
    1057               ++k;
    1058             }
    1059             else
    1060             {
    1061               sleeptime = 0;
    1062               if(chunkymode)
    1063               {
    1064                 int stop = 0;
    1065                 int pos = 0;
    1066                 while(!stop && pos < numbytes)
    1067                 {
    1068                   switch(chunkymode)
     1116                  sleeptime = 0;
     1117                  if(chunkymode)
    10691118                  {
    1070                   case 1: /* reading number starts */
    1071                     chunksize = 0;
    1072                     ++chunkymode; /* no break */
    1073                   case 2: /* during reading number */
    1074                     i = buf[pos++];
    1075                     if(i >= '0' && i <= '9') chunksize = chunksize*16+i-'0';
    1076                     else if(i >= 'a' && i <= 'f') chunksize = chunksize*16+i-'a'+10;
    1077                     else if(i >= 'A' && i <= 'F') chunksize = chunksize*16+i-'A'+10;
    1078                     else if(i == '\r') ++chunkymode;
    1079                     else if(i == ';') chunkymode = 5;
    1080                     else stop = 1;
    1081                     break;
    1082                   case 3: /* scanning for return */
    1083                     if(buf[pos++] == '\n') chunkymode = chunksize ? 4 : 1;
    1084                     else stop = 1;
    1085                     break;
    1086                   case 4: /* output data */
    1087                     i = numbytes-pos;
    1088                     if(i > chunksize) i = chunksize;
     1119                    int cstop = 0;
     1120                    int pos = 0;
     1121                    while(!stop && !cstop && !error && pos < numbytes)
     1122                    {
     1123                      switch(chunkymode)
     1124                      {
     1125                      case 1: /* reading number starts */
     1126                        chunksize = 0;
     1127                        ++chunkymode; /* no break */
     1128                      case 2: /* during reading number */
     1129                        i = buf[pos++];
     1130                        if(i >= '0' && i <= '9') chunksize = chunksize*16+i-'0';
     1131                        else if(i >= 'a' && i <= 'f') chunksize = chunksize*16+i-'a'+10;
     1132                        else if(i >= 'A' && i <= 'F') chunksize = chunksize*16+i-'A'+10;
     1133                        else if(i == '\r') ++chunkymode;
     1134                        else if(i == ';') chunkymode = 5;
     1135                        else cstop = 1;
     1136                        break;
     1137                      case 3: /* scanning for return */
     1138                        if(buf[pos++] == '\n') chunkymode = chunksize ? 4 : 1;
     1139                        else cstop = 1;
     1140                        break;
     1141                      case 4: /* output data */
     1142                        i = numbytes-pos;
     1143                        if(i > chunksize) i = chunksize;
     1144                        if(args.serdevice)
     1145                        {
     1146                          int ofs = 0;
     1147                          while(i > ofs && !cstop && !stop && !error)
     1148                          {
     1149                            int j = SerialWrite(&sx, buf+pos+ofs, i-ofs);
     1150                            if(j < 0)
     1151                            {
     1152                              fprintf(stderr, "Could not access serial device\n");
     1153                              stop = 1;
     1154                            }
     1155                            else
     1156                              ofs += j;
     1157                          }
     1158                        }
     1159                        else
     1160                          fwrite(buf+pos, (size_t)i, 1, stdout);
     1161                        totalbytes += i;
     1162                        chunksize -= i;
     1163                        pos += i;
     1164                        if(!chunksize)
     1165                          chunkymode = 1;
     1166                        break;
     1167                      case 5:
     1168                        if(i == '\r') chunkymode = 3;
     1169                        break;
     1170                      }
     1171                    }
     1172                    if(cstop)
     1173                    {
     1174                      fprintf(stderr, "Error in chunky transfer encoding\n");
     1175                      error = 1;
     1176                    }
     1177                  }
     1178                  else
     1179                  {
     1180                    totalbytes += numbytes;
    10891181                    if(args.serdevice)
    10901182                    {
    10911183                      int ofs = 0;
    1092                       while(i > ofs && !stop)
     1184                      while(numbytes > ofs && !stop)
    10931185                      {
    1094                         int j = SerialWrite(&sx, buf+pos+ofs, i-ofs);
    1095                         if(j < 0)
     1186                        int i = SerialWrite(&sx, buf+ofs, numbytes-ofs);
     1187                        if(i < 0)
    10961188                        {
    10971189                          fprintf(stderr, "Could not access serial device\n");
     
    10991191                        }
    11001192                        else
    1101                           ofs += j;
     1193                          ofs += i;
    11021194                      }
    11031195                    }
    11041196                    else
    1105                       fwrite(buf+pos, (size_t)i, 1, stdout);
    1106                     totalbytes += i;
    1107                     chunksize -= i;
    1108                     pos += i;
    1109                     if(!chunksize)
    1110                       chunkymode = 1;
    1111                     break;
    1112                   case 5:
    1113                     if(i == '\r') chunkymode = 3;
    1114                     break;
     1197                      fwrite(buf, (size_t)numbytes, 1, stdout);
    11151198                  }
    1116                 }
    1117                 if(stop)
    1118                 {
    1119                   fprintf(stderr, "Error in chunky transfer encoding\n");
    1120                   break;
    1121                 }
    1122               }
    1123               else
    1124               {
    1125                 totalbytes += numbytes;
    1126                 if(args.serdevice)
    1127                 {
    1128                   int ofs = 0;
    1129                   while(numbytes > ofs && !stop)
     1199                  fflush(stdout);
     1200                  if(totalbytes < 0) /* overflow */
    11301201                  {
    1131                     int i = SerialWrite(&sx, buf+ofs, numbytes-ofs);
    1132                     if(i < 0)
     1202                    totalbytes = 0;
     1203                    starttime = time(0);
     1204                    lastout = starttime;
     1205                  }
     1206                  if(args.serdevice && !stop)
     1207                  {
     1208                    int doloop = 1;
     1209                    while(doloop && !stop)
    11331210                    {
    1134                       fprintf(stderr, "Could not access serial device\n");
    1135                       stop = 1;
    1136                     }
    1137                     else
    1138                       ofs += i;
    1139                   }
    1140                 }
    1141                 else
    1142                   fwrite(buf, (size_t)numbytes, 1, stdout);
    1143               }
    1144               fflush(stdout);
    1145               if(totalbytes < 0) /* overflow */
    1146               {
    1147                 totalbytes = 0;
    1148                 starttime = time(0);
    1149                 lastout = starttime;
    1150               }
    1151               if(args.serdevice && !stop)
    1152               {
    1153                 int doloop = 1;
    1154                 while(doloop && !stop)
    1155                 {
    1156                   int i = SerialRead(&sx, buf, 200);
    1157                   if(i < 0)
    1158                   {
    1159                     fprintf(stderr, "Could not access serial device\n");
    1160                     stop = 1;
    1161                   }
    1162                   else
    1163                   {
    1164                     int j = 0;
    1165                     if(i < 200) doloop = 0;
    1166                     fwrite(buf, i, 1, stdout);
    1167                     while(j < i)
    1168                     {
    1169                       if(nmeabufpos < 6)
     1211                      int i = SerialRead(&sx, buf, 200);
     1212                      if(i < 0)
    11701213                      {
    1171                         if(nmeabuffer[nmeabufpos] != buf[j])
     1214                        fprintf(stderr, "Could not access serial device\n");
     1215                        stop = 1;
     1216                      }
     1217                      else
     1218                      {
     1219                        int j = 0;
     1220                        if(i < 200) doloop = 0;
     1221                        fwrite(buf, i, 1, stdout);
     1222                        if(ser)
     1223                          fwrite(buf, i, 1, ser);
     1224                        while(j < i)
    11721225                        {
    1173                           if(nmeabufpos) nmeabufpos = 0;
    1174                           else ++j;
    1175                         }
    1176                         else
    1177                         {
    1178                           nmeastarpos = 0;
    1179                           ++j; ++nmeabufpos;
     1226                          if(nmeabufpos < 6)
     1227                          {
     1228                            if(nmeabuffer[nmeabufpos] != buf[j])
     1229                            {
     1230                              if(nmeabufpos) nmeabufpos = 0;
     1231                              else ++j;
     1232                            }
     1233                            else
     1234                            {
     1235                              nmeastarpos = 0;
     1236                              ++j; ++nmeabufpos;
     1237                            }
     1238                          }
     1239                          else if((nmeastarpos && nmeabufpos == nmeastarpos + 3)
     1240                          || buf[j] == '\r' || buf[j] == '\n')
     1241                          {
     1242                            doloop = 0;
     1243                            nmeabuffer[nmeabufpos++] = '\r';
     1244                            nmeabuffer[nmeabufpos++] = '\n';
     1245                            if(send(sockfd, nmeabuffer, nmeabufpos, 0)
     1246                            != (int)nmeabufpos)
     1247                            {
     1248                              fprintf(stderr, "Could not send NMEA\n");
     1249                              error = 1;
     1250                            }
     1251                            nmeabufpos = 0;
     1252                          }
     1253                          else if(nmeabufpos > sizeof(nmeabuffer)-10 ||
     1254                          buf[j] == '$')
     1255                            nmeabufpos = 0;
     1256                          else
     1257                          {
     1258                            if(buf[j] == '*') nmeastarpos = nmeabufpos;
     1259                            nmeabuffer[nmeabufpos++] = buf[j++];
     1260                          }
    11801261                        }
    11811262                      }
    1182                       else if((nmeastarpos && nmeabufpos == nmeastarpos + 3)
    1183                       || buf[j] == '\r' || buf[j] == '\n')
    1184                       {
    1185                         doloop = 0;
    1186                         nmeabuffer[nmeabufpos++] = '\r';
    1187                         nmeabuffer[nmeabufpos++] = '\n';
    1188                         if(send(sockfd, nmeabuffer, nmeabufpos, 0)
    1189                         != (int)nmeabufpos)
    1190                         {
    1191                           fprintf(stderr, "Could not send NMEA\n");
    1192                           stop = 1;
    1193                         }
    1194                         nmeabufpos = 0;
    1195                       }
    1196                       else if(nmeabufpos > sizeof(nmeabuffer)-10 ||
    1197                       buf[j] == '$')
    1198                         nmeabufpos = 0;
    1199                       else
    1200                       {
    1201                         if(buf[j] == '*') nmeastarpos = nmeabufpos;
    1202                         nmeabuffer[nmeabufpos++] = buf[j++];
    1203                       }
     1263                    }
     1264                  }
     1265                  if(args.bitrate)
     1266                  {
     1267                    int t = time(0);
     1268                    if(t > lastout + 60)
     1269                    {
     1270                      lastout = t;
     1271                      fprintf(stderr, "Bitrate is %dbyte/s (%d seconds accumulated).\n",
     1272                      totalbytes/(t-starttime), t-starttime);
    12041273                    }
    12051274                  }
    12061275                }
    12071276              }
    1208               if(args.bitrate)
     1277            }
     1278            else
     1279            {
     1280              sleeptime = 0;
     1281              while(!stop && (numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) > 0)
    12091282              {
    1210                 int t = time(0);
    1211                 if(t > lastout + 60)
    1212                 {
    1213                   lastout = t;
    1214                   fprintf(stderr, "Bitrate is %dbyte/s (%d seconds accumulated).\n",
    1215                   totalbytes/(t-starttime), t-starttime);
    1216                 }
     1283  #ifndef WINDOWSVERSION
     1284                alarm(ALARMTIME);
     1285  #endif
     1286                fwrite(buf, (size_t)numbytes, 1, stdout);
    12171287              }
    12181288            }
    12191289          }
    12201290        }
    1221         else
    1222         {
    1223           sleeptime = 0;
    1224           while(!stop && (numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) > 0)
    1225           {
    1226 #ifndef WINDOWSVERSION
    1227             alarm(ALARMTIME);
    1228 #endif
    1229             fwrite(buf, (size_t)numbytes, 1, stdout);
    1230           }
    1231         }
     1291      }
     1292      if(sockfd)
    12321293        closesocket(sockfd);
    1233       }
    12341294    } while(args.data && *args.data != '%' && !stop);
    12351295    if(args.serdevice)
     
    12371297      SerialFree(&sx);
    12381298    }
     1299    if(ser)
     1300      fclose(ser);
    12391301  }
    12401302  return 0;
Note: See TracChangeset for help on using the changeset viewer.