Changeset 32 in ntrip for trunk/ntripserver


Ignore:
Timestamp:
Apr 27, 2006, 11:44:27 AM (16 years ago)
Author:
stoecker
Message:

added caster download

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ntripserver/NtripLinuxServer.c

    r30 r32  
    4141 */
    4242
    43 /* $Id: NtripLinuxServer.c,v 1.13 2005/06/07 14:47:52 stoecker Exp $
     43/* $Id: NtripLinuxServer.c,v 1.12 2005/06/02 09:33:11 stoecker Exp $
    4444 * Changes - Version 0.7
    4545 * Sep 22 2003  Steffen Tschirpke <St.Tschirpke@actina.de>
     
    7171 * Jun 07 2005  Dirk Stoecker <soft@dstoecker.de>
    7272 *           - added UDP bindmode
     73 *
     74 * Changes - Version 0.13
     75 * Apr 25 2006  Andrea Stuerze <andrea.stuerze@bkg.bund.de>
     76 *           - added stream retrieval from caster
     77 *
     78 * Changes - Version 0.14
     79 * Apr 27 2006  Dirk Stoecker <soft@dstoecker.de>
     80 *           - fixed some problems with caster download
     81 *
    7382 */
    7483
     
    96105#endif
    97106
    98 enum MODE { SERIAL = 1, TCPSOCKET = 2, INFILE = 3, SISNET = 4, UDPSOCKET = 5 };
    99 
    100 #define VERSION         "NTRIP NtripServerLinux/0.12"
     107enum MODE { SERIAL = 1, TCPSOCKET = 2, INFILE = 3, SISNET = 4, UDPSOCKET = 5,
     108CASTER = 6};
     109
     110#define VERSION         "NTRIP NtripServerLinux/0.13"
    101111#define BUFSZ           1024
    102112
     
    126136static void send_receive_loop(int sock, int fd, int sisnet);
    127137static void usage(int);
     138static int encode(char *buf, int size, const char *user, const char *pwd);
    128139
    129140#ifdef __GNUC__
     
    146157* Parameters:
    147158*     argc : integer        : Number of command-line arguments.
    148 *     argv : array of char  : Command-line arguments as an array of zero-terminated
    149 *                             pointers to strings.
     159*     argv : array of char  : Command-line arguments as an array of
     160*                             zero-terminated pointers to strings.
    150161*
    151162* Return Value:
     
    169180  const char *sisnetpassword = "";
    170181  const char *sisnetuser = "";
     182 
     183  const char *stream_name=0;
     184  const char *stream_user=0;
     185  const char *stream_password=0;
     186 
    171187  const char *initfile = NULL;
    172188  int bindmode = 0;
     
    185201    exit(1);
    186202  }
    187   while((c = getopt(argc, argv, "M:i:h:b:p:s:a:m:c:H:P:f:l:u:V:B")) != EOF)
     203  while((c = getopt(argc, argv, "M:i:h:b:p:s:a:m:c:H:P:f:l:u:V:D:U:W:B"))
     204  != EOF)
    188205  {
    189206    switch (c)
     
    195212      else if(!strcmp(optarg, "sisnet")) mode = 4;
    196213      else if(!strcmp(optarg, "udpsocket")) mode = 5;
     214      else if(!strcmp(optarg, "caster")) mode = 6;
    197215      else mode = atoi(optarg);
    198       if((mode == 0) || (mode > 5))
     216      if((mode == 0) || (mode > 6))
    199217      {
    200218        fprintf(stderr, "ERROR: can't convert %s to a valid mode\n", optarg);
     
    219237      if(ttybaud <= 1)
    220238      {
    221         fprintf(stderr, "ERROR: can't convert %s to valid serial speed\n", optarg);
     239        fprintf(stderr, "ERROR: can't convert %s to valid serial speed\n",
     240          optarg);
    222241        usage(1);
    223242      }
     
    230249      if(outport <= 1 || outport > 65535)
    231250      {
    232         fprintf(stderr, "ERROR: can't convert %s to a valid HTTP server port\n",
    233           optarg);
     251        fprintf(stderr,
     252          "ERROR: can't convert %s to a valid HTTP server port\n", optarg);
    234253        usage(1);
    235254      }
     
    265284      }
    266285      break;
     286    case 'D':
     287     stream_name=optarg;        /* desired stream from SourceCaster */
     288     break;
     289    case 'U':
     290     stream_user=optarg;        /* username for desired stream */
     291     break;
     292    case 'W':
     293     stream_password=optarg;    /* passwd for desired stream */
     294     break;
    267295    case 'h':                  /* help */
    268296    case '?':
     
    296324  if(!password[0])
    297325  {
    298     fprintf(stderr, "WARNING: Missing password argument - are you really sure?\n");
     326    fprintf(stderr,
     327      "WARNING: Missing password argument - are you really sure?\n");
     328  }
     329
     330  if(stream_name && (!stream_user || stream_password))
     331  {
     332    fprintf(stderr, "WARNING: Missing password argument for download"
     333      " - are you really sure?\n");
    299334  }
    300335
     
    312347        exit(1);
    313348      }
    314       /* set blocking mode in case it was not set (seems to be sometimes for fifo's) */
     349      /* set blocking mode in case it was not set
     350        (seems to be sometimes for fifo's) */
    315351      fcntl(gpsfd, F_SETFL, 0);
    316352      printf("file input: file = %s\n", filepath);
     
    327363    }
    328364    break;
    329   case TCPSOCKET: case UDPSOCKET: case SISNET:
     365  case TCPSOCKET: case UDPSOCKET: case SISNET: case CASTER:
    330366    {
    331367      if(mode == SISNET)
     
    334370        if(!inport) inport = SISNET_PORT;
    335371      }
    336       else
     372      else if(mode == CASTER)
     373      {
     374        if(!inport) inport = NTRIP_PORT;
     375        if(!inhost) inhost = NTRIP_CASTER;
     376      }
     377      else if((mode == TCPSOCKET) || (mode == UDPSOCKET))
    337378      {
    338379        if(!inport) inport = SERV_TCP_PORT;
    339380        if(!inhost) inhost = "127.0.0.1";
    340       }
     381      }     
    341382
    342383      if(!(he = gethostbyname(inhost)))
     
    346387      }
    347388
    348       if((gpsfd = socket(AF_INET, mode == UDPSOCKET ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0)
     389      if((gpsfd = socket(AF_INET, mode == UDPSOCKET
     390      ? SOCK_DGRAM : SOCK_STREAM, 0)) < 0)
    349391      {
    350392        fprintf(stderr, "ERROR: can't create socket\n");
     
    358400      addr.sin_port = htons(inport);
    359401
    360       printf("%s input: host = %s, port = %d%s%s%s\n", mode == SISNET ? "sisnet"
    361         : mode == TCPSOCKET ? "tcp socket" : "udp socket",
    362         bindmode ? "127.0.0.1" : inet_ntoa(addr.sin_addr), inport,
    363         initfile ? ", initfile = " : "",
    364         initfile ? initfile : "", bindmode ? " binding mode" : "");
     402      printf("%s input: host = %s, port = %d, %s%s%s%s%s\n",
     403      mode == CASTER ? "caster" : mode == SISNET ? "sisnet" :
     404      mode == TCPSOCKET ? "tcp socket" : "udp socket",
     405      bindmode ? "127.0.0.1" : inet_ntoa(addr.sin_addr),
     406      inport, stream_name ? "stream = " : "", stream_name ? stream_name : "",
     407      initfile ? ", initfile = " : "", initfile ? initfile : "",
     408      bindmode ? " binding mode" : "");
    365409
    366410      if(bindmode)
     
    378422        exit(1);
    379423      }
     424           
     425      if(stream_name) /* data stream from caster */
     426      {
     427        int init = 0;
     428
     429        /* set socket buffer size */
     430        setsockopt(gpsfd, SOL_SOCKET, SO_SNDBUF, (const char *) &size,
     431          sizeof(const char *));
     432        if(stream_user && stream_password)
     433        {
     434          /* leave some space for login */
     435          nBufferBytes=snprintf(szSendBuffer, sizeof(szSendBuffer)-40,
     436          "GET /%s HTTP/1.0\r\n"
     437          "User-Agent: %s\r\n"
     438          "Authorization: Basic ", stream_name, VERSION);
     439          /* second check for old glibc */
     440          if(nBufferBytes > (int)sizeof(szSendBuffer)-40 || nBufferBytes < 0)
     441          {
     442            fprintf(stderr, "Requested data too long\n");
     443            exit(1);
     444          }
     445          nBufferBytes += encode(szSendBuffer+nBufferBytes,
     446            sizeof(szSendBuffer)-nBufferBytes-5, stream_user, stream_password);
     447          if(nBufferBytes > (int)sizeof(szSendBuffer)-5)
     448          {
     449            fprintf(stderr, "Username and/or password too long\n");
     450            exit(1);
     451          }
     452          snprintf(szSendBuffer+nBufferBytes, 5, "\r\n\r\n");
     453          nBufferBytes += 5;
     454        }
     455        else
     456        {
     457          nBufferBytes = snprintf(szSendBuffer, sizeof(szSendBuffer),
     458          "GET /%s HTTP/1.0\r\n"
     459          "User-Agent: %s\r\n"
     460          "\r\n", stream_name, VERSION);
     461        }
     462        if((send(gpsfd, szSendBuffer, (size_t)nBufferBytes, 0))
     463        != nBufferBytes)
     464        {
     465          fprintf(stderr, "ERROR: could not send to caster\n");
     466          exit(1);
     467        }
     468        nBufferBytes = 0;
     469        /* check caster's response */
     470        while(!init && nBufferBytes < (int)sizeof(szSendBuffer)
     471        && (nBufferBytes += recv(gpsfd, szSendBuffer,
     472        sizeof(szSendBuffer)-nBufferBytes, 0)) > 0)
     473        {
     474          if(strstr(szSendBuffer, "\r\n"))
     475          {
     476            if(!strncmp(szSendBuffer, "ICY 200 OK\r\n", 10))
     477              init = 1;
     478            else
     479            {
     480              int k;
     481              fprintf(stderr, "Could not get the requested data: ");
     482              for(k = 0; k < nBufferBytes && szSendBuffer[k] != '\n'
     483              && szSendBuffer[k] != '\r'; ++k)
     484              {
     485                fprintf(stderr, "%c", isprint(szSendBuffer[k])
     486                ? szSendBuffer[k] : '.');
     487              }
     488              fprintf(stderr, "\n");
     489              exit(1);
     490            }
     491          }
     492        }
     493        if(!init)
     494        {
     495          fprintf(stderr, "Could not init caster download.");
     496          exit(1);
     497        }
     498      } /* end data stream from caster */
     499
    380500      if(initfile && mode != SISNET)
    381501      {
     
    413533      char buffer[1024];
    414534
    415       i = snprintf(buffer, sizeof(buffer), sisnetv3 ? "AUTH,%s,%s\r\n" : "AUTH,%s,%s",
    416       sisnetuser,sisnetpassword);
     535      i = snprintf(buffer, sizeof(buffer), sisnetv3 ? "AUTH,%s,%s\r\n"
     536        : "AUTH,%s,%s", sisnetuser, sisnetpassword);
    417537      if((send(gpsfd, buffer, (size_t)i, 0)) != i)
    418538      {
     
    543663      }
    544664      /* receiving data */
    545       nBufferBytes = read(fd, buffer, BUFSZ);
     665      nBufferBytes = read(fd, buffer, sizeof(buffer));
    546666      if(!nBufferBytes)
    547667      {
     
    554674        exit(1);
    555675      }
    556       /* we can compare the whole buffer, as the additional bytes remain unchanged */
    557       if(!memcmp(sisnetbackbuffer, buffer, sizeof(sisnetbackbuffer)))
     676      /* we can compare the whole buffer, as the additional bytes
     677         remain unchanged */
     678      if(sisnet && !memcmp(sisnetbackbuffer, buffer, sizeof(sisnetbackbuffer)))
    558679      {
    559680        nBufferBytes = 0;
     
    565686      /* send data */
    566687      if((i = send(sock, buffer, (size_t)nBufferBytes, MSG_DONTWAIT))
    567       != nBufferBytes)
     688        != nBufferBytes)
    568689      {
    569690        if(i < 0 && errno != EAGAIN)
     
    730851{
    731852  fprintf(stderr, "Usage: %s [OPTIONS]\n", VERSION);
    732   fprintf(stderr, "  Options are:\n");
    733   fprintf(stderr, "    -a caster name or address (default: %s)\n",
     853  fprintf(stderr, "  Options are: [-]           \n");
     854  fprintf(stderr, "    -a DestinationCaster name or address (default: %s)\n",
    734855    NTRIP_CASTER);
    735   fprintf(stderr, "    -p caster port (default: %d)\n", NTRIP_PORT);
    736   fprintf(stderr, "    -m caster mountpoint\n");
    737   fprintf(stderr, "    -c password for caster login\n");
     856  fprintf(stderr, "    -p DestinationCaster port (default: %d)\n", NTRIP_PORT);
     857  fprintf(stderr, "    -m DestinationCaster mountpoint\n");
     858  fprintf(stderr, "    -c DestinationCaster password\n");
    738859  fprintf(stderr, "    -h|? print this help screen\n");
    739   fprintf(stderr, "    -M <mode>  sets the mode\n");
    740   fprintf(stderr, "               (1=serial, 2=tcpsocket, 3=file, 4=sisnet, 5=udpsocket)\n");
     860  fprintf(stderr, "    -M <mode>  sets the input mode\n");
     861  fprintf(stderr, "               (1=serial, 2=tcpsocket, 3=file, 4=sisnet"
     862    ", 5=udpsocket, 6=caster)\n");
    741863  fprintf(stderr, "  Mode = file:\n");
    742864  fprintf(stderr, "    -s file, simulate data stream by reading log file\n");
     
    750872  fprintf(stderr, "  Mode = tcpsocket or udpsocket:\n");
    751873  fprintf(stderr, "    -P receiver port (default: %d)\n", SERV_TCP_PORT);
    752   fprintf(stderr, "    -H hostname of TCP server (default: %s)\n", SERV_HOST_ADDR);
     874  fprintf(stderr, "    -H hostname of TCP server (default: %s)\n",
     875    SERV_HOST_ADDR);
    753876  fprintf(stderr, "    -f initfile send to server\n");
    754   fprintf(stderr, "    -B bindmode (bind to incoming UDP stream)\n");
     877  fprintf(stderr, "    -B bindmode: bind to incoming UDP stream\n");
    755878  fprintf(stderr, "  Mode = sisnet:\n");
    756879  fprintf(stderr, "    -P receiver port (default: %d)\n", SISNET_PORT);
    757   fprintf(stderr, "    -H hostname of TCP server (default: %s)\n", SISNET_SERVER);
     880  fprintf(stderr, "    -H hostname of TCP server (default: %s)\n",
     881    SISNET_SERVER);
    758882  fprintf(stderr, "    -u username\n");
    759883  fprintf(stderr, "    -l password\n");
    760884  fprintf(stderr, "    -V version [2.1 or 3.0] (default: 2.1)\n");
     885  fprintf(stderr, "  Mode = caster:\n");
     886  fprintf(stderr, "    -P SourceCaster port (default: %d)\n", NTRIP_PORT);
     887  fprintf(stderr, "    -H SourceCaster hostname (default: %s)\n",
     888    NTRIP_CASTER);
     889  fprintf(stderr, "    -D SourceCaster mountpoint\n");
     890  fprintf(stderr, "    -U SourceCaster mountpoint username\n");
     891  fprintf(stderr, "    -W SourceCaster mountpoint password\n"); 
    761892  fprintf(stderr, "\n");
    762893  exit(rc);
    763894}
     895
     896static const char encodingTable [64] = {
     897  'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
     898  'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
     899  'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
     900  'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
     901};
     902
     903/* does not buffer overrun, but breaks directly after an error */
     904/* returns the number of required bytes */
     905static int encode(char *buf, int size, const char *user, const char *pwd)
     906{
     907  unsigned char inbuf[3];
     908  char *out = buf;
     909  int i, sep = 0, fill = 0, bytes = 0;
     910
     911  while(*user || *pwd)
     912  {
     913    i = 0;
     914    while(i < 3 && *user) inbuf[i++] = *(user++);
     915    if(i < 3 && !sep)    {inbuf[i++] = ':'; ++sep; }
     916    while(i < 3 && *pwd)  inbuf[i++] = *(pwd++);
     917    while(i < 3)         {inbuf[i++] = 0; ++fill; }
     918    if(out-buf < size-1)
     919      *(out++) = encodingTable[(inbuf [0] & 0xFC) >> 2];
     920    if(out-buf < size-1)
     921      *(out++) = encodingTable[((inbuf [0] & 0x03) << 4)
     922               | ((inbuf [1] & 0xF0) >> 4)];
     923    if(out-buf < size-1)
     924    {
     925      if(fill == 2)
     926        *(out++) = '=';
     927      else
     928        *(out++) = encodingTable[((inbuf [1] & 0x0F) << 2)
     929                 | ((inbuf [2] & 0xC0) >> 6)];
     930    }
     931    if(out-buf < size-1)
     932    {
     933      if(fill >= 1)
     934        *(out++) = '=';
     935      else
     936        *(out++) = encodingTable[inbuf [2] & 0x3F];
     937    }
     938    bytes += 4;
     939  }
     940  if(out-buf < size)
     941    *out = 0;
     942  return bytes;
     943}
Note: See TracChangeset for help on using the changeset viewer.