Example #1
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;
}
Example #2
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;
}