Changeset 914 in ntrip


Ignore:
Timestamp:
May 15, 2008, 6:51:04 PM (16 years ago)
Author:
stoecker
Message:

added keep-alive packets, some NTRIP2 fixes and better RTSP/UDP error control

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ntripclient/ntripclient.c

    r842 r914  
    11/*
    22  NTRIP client for POSIX.
    3   $Id: ntripclient.c,v 1.43 2008/04/15 13:27:49 stoecker Exp $
     3  $Id: ntripclient.c,v 1.44 2008/04/22 14:26:44 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.43 $";
    62 static char datestr[]     = "$Date: 2008/04/15 13:27:49 $";
     61static char revisionstr[] = "$Revision: 1.44 $";
     62static char datestr[]     = "$Date: 2008/04/22 14:26:44 $";
    6363
    6464enum MODE { HTTP = 1, RTSP = 2, NTRIP1 = 3, AUTO = 4, END };
     
    121121int stop = 0;
    122122#ifndef WINDOWSVERSION
     123int sigstop = 0;
    123124#ifdef __GNUC__
    124125static __attribute__ ((noreturn)) void sighandler_alarm(
     
    128129#endif /* __GNUC__ */
    129130{
    130   fprintf(stderr, "ERROR: more than %d seconds no activity\n", ALARMTIME);
     131  if(!sigstop)
     132    fprintf(stderr, "ERROR: more than %d seconds no activity\n", ALARMTIME);
     133  else
     134    fprintf(stderr, "ERROR: user break\n");
    131135  exit(1);
    132136}
     
    138142#endif /* __GNUC__ */
    139143{
     144  sigstop = 1;
    140145  alarm(2);
    141146  stop = 1;
     
    889894                  if(numbytes >= 17 && !strncmp(buf, "RTSP/1.0 200 OK\r\n", 17))
    890895                  {
     896                    int ts = 0, sn = 0;
     897                    time_t init = 0;
    891898                    struct sockaddr_in addrRTP;
     899#ifdef WINDOWSVERSION
     900                    u_long blockmode = 1;
     901                    if(ioctlsocket(sockudp, FIONBIO, &blockmode)
     902                    || ioctlsocket(sockfd, FIONBIO, &blockmode))
     903#else /* WINDOWSVERSION */
     904                    if(fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0
     905                    || fcntl(sockudp, F_SETFL, O_NONBLOCK) < 0)
     906#endif /* WINDOWSVERSION */
     907                    {
     908                      fprintf(stderr, "Could not set nonblocking mode\n");
     909                      error = 1;
     910                    }
     911
    892912                    /* fill structure with caster address information for UDP */
    893913                    memset(&addrRTP, 0, sizeof(addrRTP));
     
    896916                    their_addr.sin_addr = *((struct in_addr *)he->h_addr);
    897917                    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)
     918
     919                    while(!stop && !error)
    905920                    {
     921                      struct timeval tv = {1,0};
     922                      fd_set fdr;
     923                      fd_set fde;
     924                      int r;
     925
     926                      FD_ZERO(&fdr);
     927                      FD_ZERO(&fde);
     928                      FD_SET(sockudp, &fdr);
     929                      FD_SET(sockfd, &fdr);
     930                      FD_SET(sockudp, &fde);
     931                      FD_SET(sockfd, &fde);
     932                      if(select((sockudp>sockfd?sockudp:sockfd)+1,
     933                      &fdr,0,&fde,&tv) < 0)
     934                      {
     935                        fprintf(stderr, "Select problem.\n");
     936                        error = 1;
     937                        continue;
     938                      }
     939                      i = recvfrom(sockudp, buf, 1526, 0,
     940                      (struct sockaddr*) &addrRTP, &len);
    906941#ifndef WINDOWSVERSION
    907942                      alarm(ALARMTIME);
     
    909944                      if(i >= 12+1 && (unsigned char)buf[0] == (2 << 6) && buf[1] == 0x60)
    910945                      {
    911                         u= ((unsigned char)buf[2]<<8)+(unsigned char)buf[3];
     946                        int u,v,w;
     947                        u = ((unsigned char)buf[2]<<8)+(unsigned char)buf[3];
    912948                        v = ((unsigned char)buf[4]<<24)+((unsigned char)buf[5]<<16)
    913949                        +((unsigned char)buf[6]<<8)+(unsigned char)buf[7];
     
    917953                        if(init)
    918954                        {
     955                          time_t ct;
    919956                          if(u < -30000 && sn > 30000) sn -= 0xFFFF;
    920                           if(ssrc != w || ts > v)
     957                          if(session != w || ts > v)
    921958                          {
    922959                            fprintf(stderr, "Illegal UDP data received.\n");
     
    925962                          else if(u > sn) /* don't show out-of-order packets */
    926963                            fwrite(buf+12, (size_t)i-12, 1, stdout);
     964                          ct = time(0);
     965                          if(ct-init > 15)
     966                          {
     967                            i = snprintf(buf, MAXDATASIZE,
     968                            "GET_PARAMETER rtsp://%s%s%s/%s RTSP/1.0\r\n"
     969                            "CSeq: %d\r\n"
     970                            "Session: %d\r\n"
     971                            "\r\n",
     972                            args.server, proxyserver ? ":" : "", proxyserver
     973                            ? args.port : "", args.data, cseq++, session);
     974                            if(i > MAXDATASIZE || i < 0)
     975                            {
     976                              fprintf(stderr, "Requested data too long\n");
     977                              stop = 1;
     978                            }
     979                            else if(send(sockfd, buf, (size_t)i, 0) != i)
     980                            {
     981                              perror("send");
     982                              error = 1;
     983                            }
     984                            init = ct;
     985                          }
    927986                        }
    928                         sn = u; ts = v; ssrc = w; init = 1;
     987                        else
     988                        {
     989                          init = time(0);
     990                        }
     991                        sn = u; ts = v;
    929992                      }
    930                       else
     993                      else if(i >= 0)
    931994                      {
    932995                        fprintf(stderr, "Illegal UDP header.\n");
    933996                        continue;
     997                      }
     998                      /* ignore RTSP server replies */
     999                      if((r=recv(sockfd, buf, MAXDATASIZE-1, 0)) < 0)
     1000                      {
     1001#ifdef WINDOWSVERSION
     1002                        if(WSAGetLastError() != WSAEWOULDBLOCK)
     1003#else /* WINDOWSVERSION */
     1004                        if(errno != EAGAIN)
     1005#endif /* WINDOWSVERSION */
     1006                        {
     1007                          fprintf(stderr, "Control connection closed\n");
     1008                          error = 1;
     1009                        }
     1010                      }
     1011                      else if(!r)
     1012                      {
     1013                        fprintf(stderr, "Control connection read error\n");
     1014                        error = 1;
    9341015                      }
    9351016                    }
Note: See TracChangeset for help on using the changeset viewer.