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; }
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; }