Exemple #1
0
void handleClientRequest(int i)
{
    ssize_t r;
    char * p;
    size_t remain;

    if (stream[i].len >= sizeof(stream[i].buffer) - 2)
    {
        logAbort("Input line on stream %d too long: %s\n", i, stream[i].buffer);
    }
    remain = sizeof(stream[i].buffer) - stream[i].len - 2;

    logDebug("handleClientRequest: read i=%d\n", i);
    logDebug("read %s i=%d fd=%d len=%u remain=%u\n", streamTypeName[stream[i].type], i, stream[i].fd, stream[i].len, remain);
    r = read(stream[i].fd, stream[i].buffer + stream[i].len, remain);

    if (r <= 0)
    {
        logDebug("read %s i=%d fd=%d r=%d\n", streamTypeName[stream[i].type], i, stream[i].fd, r);
        if (stream[i].type == DATA_INPUT_STREAM)
        {
            logAbort("EOF on reading stdin\n");
        }
        closeStream(i);
        return;
    }

    stream[i].len += r;
    stream[i].buffer[stream[i].len] = 0;
    while (stream[i].len > 0)
    {
        size_t len;

        p = strchr(stream[i].buffer, '\n');
        if (!p)
        {
            break;
        }
        len = p - stream[i].buffer;
        sbAppendData(&tcpMessage, stream[i].buffer, len + 1);
        if (stream[i].type != DATA_INPUT_STREAM || stream[outputIdx].type == DATA_OUTPUT_COPY)
        {
            /* Send all TCP client input and the main stdin stream if the mode is -o */
            /* directly to stdout */
            sbAppendData(&outMessage, stream[i].buffer, len + 1);
        }
        *p = 0;
        if (storeMessage(stream[i].buffer, len))
        {
            convertJSONToNMEA0183(&nmeaMessage, stream[i].buffer);
        }
        p++, len++;
        stream[i].len -= len;

        /* Now remove [buffer..p> == the entire line */
        memmove(stream[i].buffer, p, stream[i].len + 1);
    }
}
Exemple #2
0
static enum ReadyDescriptor isready(int fd1, int fd2)
{
  fd_set fds;
  struct timeval waitfor;
  int setsize;
  int r;
  enum ReadyDescriptor ret = 0;

  FD_ZERO(&fds);
  if (fd1 >= 0)
  {
    FD_SET(fd1, &fds);
  }
  if (fd2 >= 0)
  {
    FD_SET(fd2, &fds);
  }
  waitfor.tv_sec = timeout ? timeout : 10;
  waitfor.tv_usec = 0;
  if (fd1 > fd2)
  {
    setsize = fd1 + 1;
  }
  else
  {
    setsize = fd2 + 1;
  }
  r = select(setsize, &fds, 0, 0, &waitfor);
  if (r < 0)
  {
    logAbort("I/O error; restart by quit\n");
  }
  if (r > 0)
  {
    if (fd1 >= 0 && FD_ISSET(fd1, &fds))
    {
      ret |= FD1_Ready;
    }
    if (fd2 >= 0 && FD_ISSET(fd2, &fds))
    {
      ret |= FD2_Ready;
    }
  }
  if (!ret && timeout)
  {
    logAbort("Timeout %ld seconds; restart by quit\n", timeout);
  }
  return ret;
}
Exemple #3
0
int64_t epoch(void)
{
    struct timeval t;

    if (gettimeofday(&t, 0))
    {
        logAbort("Error on obtaining wall clock\n");
    }
    return (int64_t) t.tv_sec * 1000 + t.tv_usec / 1000;
}
Exemple #4
0
void die (char * t)
{
  int e = errno;
  char * s = 0;

  if (e)
  {
    s = strerror(e);
  }

  if (s)
  {
    logAbort("%s: %s\n", t, s);
  }
  else
  {
    logAbort("%s\n", t);
  }
}
Exemple #5
0
static bool storeMessage(char * line, size_t len)
{
    char *s, *e = 0, *e2;
    Message * m;
    int i, idx, k;
    int src, dst, prn = 0;
    Pgn * pgn;
    time_t now;
    char * key2 = 0;
    int valid;
    char value[16];

    now = time(0);

    logDebug("storeMessage(\"%s\",%u)\n", line, len);

    if (!strstr(line, "\"fields\":"))
    {
        logDebug("Ignore: pgn %u without fields\n", prn);
        return false;
    }
    if (memcmp(line, "{\"timestamp", 11) != 0)
    {
        logDebug("Ignore: no timestamp: '%s'\n", line);
        return false;
    }
    if (memcmp(line + len - 2, "}}", 2) != 0)
    {
        logDebug("Ignore: no line end: '%s'\n", line);
        return false;
    }

    if (getJSONValue(line, "src", value, sizeof(value)))
    {
        sscanf(value, "%d", &src);
    }

    if (getJSONValue(line, "dst", value, sizeof(value)))
    {
        sscanf(value, "%d", &dst);
    }

    if (getJSONValue(line, "pgn", value, sizeof(value)))
    {
        sscanf(value, "%d", &prn);
    }

    idx = PrnToIdx(prn);
    logDebug("src=%d dst=%d prn=%d idx=%d\n", src, dst, prn, idx);
    if (idx < 0)
    {
        logError("Ignore: prn %d: '%s'\n", prn, line);
        return false;
    }

    /* Look for a secondary key */
    for (k = 0; k < ARRAYSIZE(secondaryKeyList); k++)
    {
        s = strstr(line, secondaryKeyList[k]);
        if (s)
        {
            logDebug("Found 2nd key %d = %s\n", k, secondaryKeyList[k]);
            s += strlen(secondaryKeyList[k]);
            while (strchr(SKIP_CHARACTERS, *s))
            {
                s++;
            }

            e = strchr(s, ' ');
            e2 = strchr(s, '"');
            if (!e || e2 < e)
            {
                e = e2;
            }
            if (!e)
            {
                e = s + strlen(s);
            }
            if (e > s && e[-1] == ',')
            {
                e--;
            }
            key2 = malloc(e - s + 1);
            if (!key2)
            {
                logAbort("Out of memory allocating %u bytes", e - s);
            }
            memcpy(key2, s, e - s);
            key2[e - s] = 0;
            break;
        }
    }

    pgn = pgnIdx[idx];
    if (!pgn)
    {
        if (maxPgnList == ARRAYSIZE(pgnList))
        {
            logAbort("Too many PGNs\n");
        }

        pgn = calloc(1, sizeof(Pgn) + sizeof(Message));
        if (!pgn)
        {
            logAbort("Out of memory allocating %u bytes", sizeof(Pgn) + sizeof(Message));
        }
        pgnIdx[idx] = pgn;
        pgnList[maxPgnList++] = &pgnIdx[idx];
        logDebug("Storing new PGN %d in index %u\n", prn, idx);
    }

    if (!pgn->p_description)
    {
        pgn->p_prn = prn;
        s = strstr(line, "\"description\":");
        if (s)
        {
            s = s + sizeof("\"description\":");
            e = strchr(s, ':');
            e2 = strchr(s, '"');
            if (!e || e2 < e)
            {
                e = e2;
            }
            if (!e)
            {
                logDebug("Cannot find end of description in %s\n", s);
                return false;
            }
            logDebug("New PGN '%.*s'\n", e - s, s);
            pgn->p_description = malloc(e - s + 1);
            if (!pgn->p_description)
            {
                logAbort("Out of memory allocating %u bytes", e - s);
            }
            memcpy(pgn->p_description, s, e - s);
            pgn->p_description[e - s] = 0;
        }
    }

    /* Find existing key */
    for (i = 0; i < pgn->p_maxSrc; i++)
    {
        if (pgn->p_message[i].m_src == src)
        {
            if (pgn->p_message[i].m_key2)
            {
                if (key2 && strcmp(pgn->p_message[i].m_key2, key2) == 0)
                {
                    break;
                }
            }
            else
            {
                break;
            }
        }
    }

    /* Reuse expired key ? */
    if (i == pgn->p_maxSrc)
    {
        for (i = 0; i < pgn->p_maxSrc; i++)
        {
            if (pgn->p_message[i].m_time < now)
            {
                pgn->p_message[i].m_src = (uint8_t) src;
                if (pgn->p_message[i].m_key2)
                {
                    free(pgn->p_message[i].m_key2);
                }
                pgn->p_message[i].m_key2 = key2;
                key2 = 0;
                break;
            }
        }
    }

    /* Create new key */
    if (i == pgn->p_maxSrc)
    {
        size_t newSize;

        pgn->p_maxSrc++;
        newSize = sizeof(Pgn) + pgn->p_maxSrc * sizeof(Message);
        pgn = realloc(pgnIdx[idx], newSize);
        if (!pgn)
        {
            logAbort("Out of memory allocating %u bytes", newSize);
        }
        pgnIdx[idx] = pgn;
        pgn->p_message[i].m_src = (uint8_t) src;
        pgn->p_message[i].m_key2 = key2;
        key2 = 0;
        pgn->p_message[i].m_text = 0;
    }

    m = &pgn->p_message[i];
    if (m->m_text)
    {
        m->m_text = realloc(m->m_text, len + 2);
    }
    else
    {
        m->m_text = malloc(len + 2);
    }
    if (!m->m_text)
    {
        logAbort("Out of memory allocating %u bytes", len + 1);
    }
    memcpy(m->m_text, line, len);
    m->m_text[len] = '\n';
    m->m_text[len + 1] = 0;

    if (prn == 60928 || prn == 126996)
    {
        valid = CLAIM_TIMEOUT;
    }
    else if (prn == 130816)
    {
        valid = SONICHUB_TIMEOUT;
    }
    else
    {
        valid = secondaryKeyTimeout[k];
    }
    logDebug("stored prn %d timeout=%d 2ndKey=%d\n", prn, valid, k);
    if (key2)
    {
        free(key2);
    }
    m->m_time = now + valid;
    return true;
}
Exemple #6
0
void writeAllClients(void)
{
    fd_set ws;
    struct timeval timeout = {0, 0};
    int r;
    int i;
    SOCKET fd;
    int64_t now = 0;
    char * state = 0;

    logDebug("writeAllClients tcp.len=%d\n", tcpMessage.len);
    FD_ZERO(&ws);

    if (socketIdxMax >= 0)
    {
        ws = writeSet;
        r = select(socketFdMax + 1, 0, &ws, 0, &timeout);
        logDebug("write to %d streams (%u..%u fdMax=%d)\n", r, socketIdxMin, socketIdxMax, socketFdMax);

        for (i = socketIdxMin; r > 0 && i <= socketIdxMax; i++)
        {
            fd = stream[i].fd;
            if (fd < 0)
            {
                continue;
            }
            if (fd > 8192)
            {
                logAbort("Stream %d contains invalid fd %d\n", i, fd);
            }
            if (fd > socketFdMax)
            {
                logAbort("Inconsistent: fd[%u]=%d, fdMax=%d\n", i, fd, socketFdMax);
            }
            if (FD_ISSET(fd, &ws))
            {
                logDebug("%s i=%u fd=%d writable=%d\n", streamTypeName[stream[i].type], i, fd, FD_ISSET(fd, &ws));
                r--;
                if (!now) now = epoch();

                switch (stream[i].type)
                {
                case CLIENT_JSON:
                    if (stream[i].timeout && stream[i].timeout < now)
                    {
                        if (!state)
                        {
                            state = getFullStateJSON();
                            logDebug("json=%s", state);
                        }
                        write(fd, state, strlen(state));
                        logDebug("JSON: wrote %u to %d, closing\n", strlen(state), fd);
                        closeStream(i);
                    }
                    break;
                case CLIENT_NMEA0183_STREAM:
                    logDebug("NMEA-> %d\n", nmeaMessage.len);
                    if (nmeaMessage.len)
                    {
                        write(fd, nmeaMessage.data, nmeaMessage.len);
                    }
                    break;
                case CLIENT_JSON_STREAM:
                    if (tcpMessage.len)
                    {
                        write(fd, tcpMessage.data, tcpMessage.len);
                    }
                    break;
                case DATA_OUTPUT_STREAM:
                case DATA_OUTPUT_COPY:
                    if (outMessage.len)
                    {
                        write(fd, outMessage.data, outMessage.len);
                    }
                    break;
                default:
                    break;
                }
            }
        }
    }

    if (state)
    {
        free(state);
    }

    outMessage.len = 0;
    tcpMessage.len = 0;
    nmeaMessage.len = 0;

# ifdef NEVER
    {
        static int count = 0;
        if (count++ > 100)
        {
            exit(1);
        }
    }
# endif
}
Exemple #7
0
void handleClientRequest(int i)
{
  ssize_t r;
  char * p;

  r = read(stream[i].fd, stream[i].buffer + stream[i].len, sizeof(stream[i].buffer) - 1 - stream[i].len);
  logDebug("read i=%d fd=%d r=%d\n", i, stream[i].fd, r);

  if (r < 0)
  {
    if (stream[i].fd == stdinfd)
    {
      logAbort("Read %d on reading stdin\n", r);
    }
    closeStream(i);
    return;
  }

  if (r == 0)
  {
    if (stream[i].type == DATA_INPUT_STREAM)
    {
      logAbort("EOF on reading stdin\n", r);
    }
    else
    {
      closeStream(i);
    }
    return;
  }

  stream[i].len += r;
  stream[i].buffer[stream[i].len] = 0;
  while (r > 0)
  {
    p = strchr(stream[i].buffer, '\n');
    if (p)
    {
      size_t len = ++p - stream[i].buffer;

      /* Feed it into the NMEA2000 message handler */
      char stash = *p;

      logDebug("Got msg='%1.*s'\n", len, stream[i].buffer);
      *p = 0;

      sbAppendData(&tcpMessage, stream[i].buffer, len);
      if (stream[i].type != DATA_INPUT_STREAM || stream[outputIdx].type == DATA_OUTPUT_COPY)
      {
        /* Send all TCP client input and the main stdin stream if the mode is -o */
        /* directly to stdout */
        sbAppendData(&outMessage, stream[i].buffer, len);
      }
      convertJSONToNMEA0183(&nmeaMessage, stream[i].buffer);
      storeMessage(stream[i].buffer, len);
      *p = stash;

      /* Now remove [buffer..p> */
      memcpy(stream[i].buffer, p, strlen(p));
      stream[i].len -= len;
      r -= len;
    }
    else
    {
      r = 0;
    }
  }
}
Exemple #8
0
void storeMessage(char * line, size_t len)
{
  char *s, *e = 0, *e2;
  Message * m;
  int i, idx, k;
  int src, dst, prn = 0;
  Pgn * pgn;
  time_t now;
  char * key2 = 0;
  int valid;

  now = time(0);

  if (!strstr(line, "\"fields\":"))
  {
#ifdef DEBUG
    logDebug("Ignore pgn %u without fields\n", prn);
#endif
    return;
  }
  if (memcmp(line, "{\"timestamp", 11) != 0)
  {
    logDebug("Ignore '%s'\n", line);
    return;
  }
  if (memcmp(line + len - 3, "}}\n", 3) != 0)
  {
    logDebug("Ignore '%s' (end)\n", line);
    return;
  }
  s = strstr(line, "\"src\":");
  if (s)
  {
    if (sscanf(s + sizeof("\"src\":"), "%u\",\"dst\":\"%u\",\"pgn\":\"%u\"", &src, &dst, &prn))
    {
#ifdef DEBUG
      logDebug("prn=%u src=%u\n", prn, src);
#endif
    }
  }
  if (prn == 0 || prn > MAX_PGN)
  {
    return;
  }

  /* Look for a secondary key */
  for (k = 0; k < ARRAYSIZE(secondaryKeyList); k++)
  {
    s = strstr(line, secondaryKeyList[k]);
    if (s)
    {
      s += strlen(secondaryKeyList[k]);
      while (strchr(SKIP_CHARACTERS, *s))
      {
        s++;
      }

      e = strchr(s, ' ');
      e2 = strchr(s, '"');
      if (!e || e2 < e)
      {
        e = e2;
      }
      if (!e)
      {
        e = s + strlen(s);
      }
      key2 = malloc(e - s + 1);
      if (!key2)
      {
        logAbort("Out of memory allocating %u bytes", e - s);
      }
      memcpy(key2, s, e - s);
      key2[e - s] = 0;
    }
  }

  idx = PrnToIdx(prn);
  if (idx < 0)
  {
    logAbort("PRN %d is out of range\n", prn);
  }

  pgn = pgnIdx[idx];
  if (!pgn)
  {
    if (maxPgnList == ARRAYSIZE(pgnList))
    {
      logAbort("Too many PGNs\n");
    }

    pgn = calloc(1, sizeof(Pgn) + sizeof(Message));
    if (!pgn)
    {
      logAbort("Out of memory allocating %u bytes", sizeof(Pgn) + sizeof(Message));
    }
    pgnIdx[idx] = pgn;
    pgnList[maxPgnList++] = &pgnIdx[idx];
    logDebug("Storing new PGN %d in index %u\n", prn, idx);
  }

  if (!pgn->p_description)
  {
    pgn->p_prn = prn;
    s = strstr(line, "\"description\":");
    if (s)
    {
      s = s + sizeof("\"description\":");
      e = strchr(s, ':');
      e2 = strchr(s, '"');
      if (!e || e2 < e)
      {
        e = e2;
      }
      if (!e)
      {
        logDebug("Cannot find end of description in %s\n", s);
        return;
      }
      logDebug("New PGN '%.*s'\n", e - s, s);
      pgn->p_description = malloc(e - s + 1);
      if (!pgn->p_description)
      {
        logAbort("Out of memory allocating %u bytes", e - s);
      }
      memcpy(pgn->p_description, s, e - s);
      pgn->p_description[e - s] = 0;
    }
  }

  /* Find existing key */
  for (i = 0; i < pgn->p_maxSrc; i++)
  {
    if (pgn->p_message[i].m_src == src)
    {
      if (pgn->p_message[i].m_key2)
      {
        if (key2 && strcmp(pgn->p_message[i].m_key2, key2) == 0)
        {
          break;
        }
      }
      else
      {
        break;
      }
    }
  }

  /* Reuse expired key ? */
  if (i == pgn->p_maxSrc)
  {
    for (i = 0; i < pgn->p_maxSrc; i++)
    {
      if (pgn->p_message[i].m_time < now)
      {
        pgn->p_message[i].m_src = (uint8_t) src;
        if (pgn->p_message[i].m_key2)
        {
          free(pgn->p_message[i].m_key2);
        }
        pgn->p_message[i].m_key2 = key2;
        key2 = 0;
        break;
      }
    }
  }

  /* Create new key */
  if (i == pgn->p_maxSrc)
  {
    size_t newSize;

    pgn->p_maxSrc++;
    newSize = sizeof(Pgn) + pgn->p_maxSrc * sizeof(Message);
    pgn = realloc(pgnIdx[idx], newSize);
    if (!pgn)
    {
      logAbort("Out of memory allocating %u bytes", newSize);
    }
    pgnIdx[idx] = pgn;
    pgn->p_message[i].m_src = (uint8_t) src;
    pgn->p_message[i].m_key2 = key2;
    key2 = 0;
    pgn->p_message[i].m_text = 0;
  }

  m = &pgn->p_message[i];
  if (m->m_text)
  {
    if (strlen(m->m_text) < len)
    {
      m->m_text = realloc(m->m_text, len + 1);
    }
  }
  else
  {
    m->m_text = malloc(len + 1);
  }
  if (!m->m_text)
  {
    logAbort("Out of memory allocating %u bytes", len + 1);
  }
  strcpy(m->m_text, line);

  if (prn == 126996)
  {
    valid = AIS_TIMEOUT;
  }
  else if (prn == 130816)
  {
    valid = SONICHUB_TIMEOUT;
  }
  else
  {
    valid = secondaryKeyTimeout[k];
  }
  m->m_time = now + valid;
}
Exemple #9
0
int main(int argc, char **argv)
{
  int            r;
  int            handle;
  struct termios attr;
  char *         name   = argv[0];
  char *         device = 0;
  struct stat    statbuf;
  int            pid = 0;
  int            speed;

  setProgName(argv[0]);
  while (argc > 1)
  {
    if (strcasecmp(argv[1], "-version") == 0)
    {
      printf("%s\n", VERSION);
      exit(0);
    }
    else if (strcasecmp(argv[1], "-w") == 0)
    {
      writeonly = 1;
    }
    else if (strcasecmp(argv[1], "-p") == 0)
    {
      passthru = 1;
    }
    else if (strcasecmp(argv[1], "-r") == 0)
    {
      readonly = 1;
    }
    else if (strcasecmp(argv[1], "-v") == 0)
    {
      verbose = 1;
    }
    else if (strcasecmp(argv[1], "-t") == 0 && argc > 2)
    {
      argc--;
      argv++;
      timeout = strtol(argv[1], 0, 10);
      logDebug("timeout set to %ld seconds\n", timeout);
    }
    else if (strcasecmp(argv[1], "-s") == 0 && argc > 2)
    {
      argc--;
      argv++;
      speed = strtol(argv[1], 0, 10);
      switch (speed)
      {
        case 38400:
          baudRate = B38400;
          break;
        case 57600:
          baudRate = B57600;
          break;
        case 115200:
          baudRate = B115200;
          break;
        case 230400:
          baudRate = B230400;
          break;
#ifdef B460800
        case 460800:
          baudRate = B460800;
          break;
#endif
#ifdef B921600
        case 921600:
          baudRate = B921600;
          break;
#endif
        default:
          baudRate = speed;
          break;
      }
      logDebug("speed set to %d (%d) baud\n", speed, baudRate);
    }
    else if (strcasecmp(argv[1], "-d") == 0)
    {
      setLogLevel(LOGLEVEL_DEBUG);
    }
    else if (strcasecmp(argv[1], "-o") == 0)
    {
      outputCommands = 1;
    }
    else if (!device)
    {
      device = argv[1];
    }
    else
    {
      device = 0;
      break;
    }
    argc--;
    argv++;
  }

  if (!device)
  {
    fprintf(stderr,
            "Usage: %s [-w] -[-p] [-r] [-v] [-d] [-s <n>] [-t <n>] device\n"
            "\n"
            "Options:\n"
            "  -w      writeonly mode, no data is read from device\n"
            "  -r      readonly mode, no data is sent to device\n"
            "  -p      passthru mode, data on stdin is sent to stdout but not to device\n"
            "  -v      verbose\n"
            "  -d      debug\n"
            "  -s <n>  set baudrate to 38400, 57600, 115200, 230400"
#ifdef B460800
            ", 460800"
#endif
#ifdef B921600
            ", 921600"
#endif
            "\n"
            "  -t <n>  timeout, if no message is received after <n> seconds the program quits\n"
            "  -o      output commands sent to stdin to the stdout \n"
            "  <device> can be a serial device, a normal file containing a raw log,\n"
            "  or the address of a TCP server in the format tcp://<host>[:<port>]\n"
            "\n"
            "  Examples: %s /dev/ttyUSB0\n"
            "            %s tcp://192.168.1.1:10001\n"
            "\n" COPYRIGHT,
            name,
            name,
            name);
    exit(1);
  }

retry:
  logDebug("Opening %s\n", device);
  if (strncmp(device, "tcp:", STRSIZE("tcp:")) == 0)
  {
    handle = open_socket_stream(device);
    logDebug("socket = %d\n", handle);
    isFile = true;
    if (handle < 0)
    {
      fprintf(stderr, "Cannot open NGT-1-A TCP stream %s\n", device);
      exit(1);
    }
  }
  else
  {
    handle = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK);
    logDebug("fd = %d\n", handle);
    if (handle < 0)
    {
      logAbort("Cannot open NGT-1-A device %s\n", device);
    }
    if (fstat(handle, &statbuf) < 0)
    {
      logAbort("Cannot determine device %s\n", device);
    }
    isFile = S_ISREG(statbuf.st_mode);
  }

  if (isFile)
  {
    logInfo("Device is a normal file, do not set the attributes.\n");
  }
  else
  {
    logDebug("Device is a serial port, set the attributes.\n");

    memset(&attr, 0, sizeof(attr));
    if (cfsetspeed(&attr, baudRate) < 0)
    {
      logAbort("Could not set baudrate %d\n", speed);
    }
    attr.c_cflag |= CS8 | CLOCAL | CREAD;

    attr.c_iflag |= IGNPAR;
    attr.c_cc[VMIN]  = 1;
    attr.c_cc[VTIME] = 0;
    tcflush(handle, TCIFLUSH);
    tcsetattr(handle, TCSANOW, &attr);

    logDebug("Device is a serial port, send the startup sequence.\n");

    writeMessage(handle, NGT_MSG_SEND, NGT_STARTUP_SEQ, sizeof(NGT_STARTUP_SEQ));
    sleep(2);
  }

  for (;;)
  {
    unsigned char msg[BUFFER_SIZE];
    size_t        msgLen;
    int           r = isReady(writeonly ? INVALID_SOCKET : handle, readonly ? INVALID_SOCKET : 0, INVALID_SOCKET, timeout);

    if ((r & FD1_ReadReady) > 0)
    {
      if (!readNGT1(handle))
      {
        break;
      }
    }
    if ((r & FD2_ReadReady) > 0)
    {
      if (!readIn(msg, sizeof(msg)))
      {
        break;
      }
      if (!passthru)
      {
        parseAndWriteIn(handle, msg);
      }
      if (outputCommands)
      {
        fprintf(stdout, "%s", msg);
        fflush(stdout);
      }
    }
    else if (writeonly)
    {
      break;
    }
  }

  close(handle);
  return 0;
}
Exemple #10
0
int main(int argc, char ** argv)
{
  int r;
  int handle;
  struct termios attr;
  char * device = 0;
  struct stat statbuf;
  int pid = 0;

  setProgName(argv[0]);

  while (argc > 1)
  {
    if (strcasecmp(argv[1], "-r") == 0)
    {
      readonly = 1;
    }
    else if (strcasecmp(argv[1], "-d") == 0)
    {
      setLogLevel(LOGLEVEL_DEBUG);
    }
    else if (strcasecmp(argv[1], "-?") == 0)
    {
      break;
    }
    else if (!device)
    {
      device = argv[1];
    }
    else
    {
      device = 0;
      break;
    }
    argc--;
    argv++;
  }

  if (!device)
  {
    fprintf(stderr, "Usage: nmea0183-serial [-r] [-d] device\n\n"
    "-r : read-only, do not pass stdin to stdout\n"
    "-d : debug mode\n\n"
    "Example: nmea0183-serial /dev/ttyUSB0\n\n"COPYRIGHT);
    exit(1);
  }

retry:
  logDebug("Opening %s\n", device);
  handle = open(device, O_RDWR | O_NOCTTY);
  logDebug("fd = %d\n", handle);
  if (handle < 0)
  {
    logAbort("NMEA-00001: Cannot open NMEA-0183 device %s\n", device);
    exit(1);
  }
  if (fstat(handle, &statbuf) < 0)
  {
    logAbort("NMEA-00002: Cannot determine device %s\n", device);
    exit(1);
  }
  isFile = S_ISREG(statbuf.st_mode);

  if (!isFile)
  {
    logDebug("Device is a serial port, set the attributes.\n");

    memset(&attr, 0, sizeof(attr));
    attr.c_cflag = B38400 | CS8 | CLOCAL | CREAD;
    attr.c_iflag = IGNPAR;
    attr.c_oflag = 0;
    attr.c_lflag = 0;
    attr.c_cc[VMIN] = 0;
    attr.c_cc[VTIME] = 1;
    tcflush(handle, TCIFLUSH);
    tcsetattr(handle, TCSANOW, &attr);
  }

  for (;;)
  {
    char msg[BUFFER_SIZE];
    size_t msgLen;
    enum ReadyDescriptor r;
    int b;

    r = isready(handle, readonly ? -1 : 0);

    if ((r & FD1_Ready) > 0)
    {
      b = read(handle, msg, sizeof(msg));
      if (b < 0)
      {
        break;
      }
      else if (b > 0)
      {
        if (write(1, msg, b) < b)
        {
          break;
        }
      }
    }
    if ((r & FD2_Ready) > 0)
    {
      b = read(0, msg, sizeof(msg));
      if (b < 0)
      {
        break;
      }
      else if (b > 0)
      {
        if (write(1, msg, b) < b)
        {
          break;
        }
        if (write(handle, msg, b) < b)
        {
          break;
        }
      }
    }
  }

  close(handle);
  return 0;
}