Don't log duplicate COMM errors, remove sent log records

This commit is contained in:
Tanner Collin 2019-01-20 20:04:43 -07:00
parent 9717073507
commit 63adb9b9a3

View File

@ -23,12 +23,12 @@ char cardBuffer[CARD_BUFFER_LENGTH];
#define CARD_CHECK_LENGTH 2
#define CARD_HEAD_BYTE 0x2
#define CARD_TAIL_BYTE 0x3
typedef struct __attribute__((packed)) cardData {
struct __attribute__((packed)) cardData {
char head;
char data[CARD_DATA_LENGTH];
char checksum[CARD_CHECK_LENGTH];
char tail;
} cardData_t;
};
#define RELAY_PIN D1
#define GREEN_BUTTON_PIN D3
@ -90,7 +90,8 @@ enum commStates
#define SERIAL_LOGGING true
#define LOG_SIZE 100
#define LOG_SIZE 90 // 100 blew up the stack
#define LOG_DATA_LENGTH CARD_DATA_LENGTH
enum eventCodes
{
@ -98,6 +99,8 @@ enum eventCodes
LOG_INIT_COMPLETE,
LOG_WIFI_CONNECTED,
LOG_WIFI_DISCONNECTED,
LOG_COMM_LOCK_ARM,
LOG_COMM_LOCK_DISARM,
LOG_COMM_LOCK_FAIL,
LOG_COMM_CARD_FAIL,
LOG_COMM_INFO_FAIL,
@ -105,31 +108,33 @@ enum eventCodes
LOG_LOCK_ARMED,
LOG_LOCK_TIMEOUT,
LOG_LOCK_ON,
LOG_LOCK_CANCEL,
LOG_LOCK_DISARM,
LOG_LOCK_ERROR,
LOG_CARD_GOOD_READ,
LOG_CARD_ACCEPTED,
LOG_CARD_DENIED,
};
typedef struct __attribute__((packed)) logData {
struct __attribute__((packed)) logData {
uint32_t unixTime;
uint8_t eventCode;
char data[CARD_DATA_LENGTH];
} logData_t;
char data[LOG_DATA_LENGTH];
};
logData_t eventLog[LOG_SIZE];
struct logData eventLog[LOG_SIZE];
uint16_t logPosition = 0;
void logEvent(uint8_t eventCode, const char *data = nullptr, size_t num = 0)
{
logData_t event;
struct logData event;
noInterrupts();
event.unixTime = time(nullptr);
event.eventCode = eventCode;
for (uint8_t i = 0; i < CARD_DATA_LENGTH; i++) {
memset(event.data, 0, LOG_DATA_LENGTH);
for (uint8_t i = 0; i < LOG_DATA_LENGTH; i++) {
if (i >= num) break;
event.data[i] = data[i];
}
@ -141,6 +146,22 @@ void logEvent(uint8_t eventCode, const char *data = nullptr, size_t num = 0)
interrupts();
}
void removeLogRecords(uint8_t num) {
// shift records down by num because they've been sent
if (num > logPosition) return;
noInterrupts();
for (int i = 0; i < num; i++) {
eventLog[i] = eventLog[i + num];
}
logPosition -= num;
interrupts();
}
void setup()
{
Serial.begin(9600);
@ -217,7 +238,7 @@ int8_t charToNum(char input)
return String("0123456789ABCDEF").indexOf(input);
}
bool checksum(cardData_t *cardData)
bool checksum(struct cardData *cardData)
{
// checksum is each hex data byte xord'd together.
// each char is a hex nibble, so we have to work in pairs.
@ -244,7 +265,7 @@ bool checksum(cardData_t *cardData)
void checkCard()
{
cardData_t *cardData = (cardData_t *) cardBuffer;
struct cardData *cardData = (struct cardData *) cardBuffer;
if (cardData->head == CARD_HEAD_BYTE &&
cardData->tail == CARD_TAIL_BYTE &&
@ -357,7 +378,7 @@ void processLockState()
if (redButton()) {
if (SERIAL_LOGGING) Serial.println("[INFO] Unarming interlock.");
logEvent(LOG_LOCK_CANCEL);
logEvent(LOG_LOCK_DISARM);
lockState = LOCK_OFF;
} else if (greenButton()) {
if (SERIAL_LOGGING) Serial.println("[INFO] On button pressed.");
@ -485,24 +506,29 @@ String deserializeLockJson(String input)
}
String serializeLog() {
size_t logLengthBytes = logPosition * sizeof(logData_t);
return base64::encode((uint8_t *) eventLog, logLengthBytes, false);
size_t logLengthBytes = logPosition * sizeof(struct logData);
return "{\"log\": \"" + base64::encode((uint8_t *) eventLog, logLengthBytes, false) + "\"}";
}
uint32_t deserializeInfoJson(String input)
void deserializeInfoJson(String input, uint8_t *processed, uint32_t *unixTime)
{
// Generated with: https://arduinojson.org/assistant/
const size_t bufferSize = JSON_OBJECT_SIZE(1) + 50;
const size_t bufferSize = JSON_OBJECT_SIZE(2) + 50;
StaticJsonBuffer<bufferSize> jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(input);
uint32_t unixTime = root["unixTime"];
return unixTime;
*processed = root["processed"];
*unixTime = root["unixTime"];
}
//TODO: abstract http functions
void postState()
{
// Don't log more than one error at a time
static bool logErrors = true;
HTTPClient lockHTTP;
//lockHTTP.begin("https://url", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS
@ -521,27 +547,33 @@ void postState()
if (SERIAL_LOGGING) Serial.printf("[INFO] POST success, code: %d\n", lockHTTPCode);
if (lockHTTPCode == HTTP_CODE_OK) {
logErrors = true;
if (SERIAL_LOGGING) Serial.print("[INFO] Resource found, parsing response: ");
String lockPayload = lockHTTP.getString();
if (SERIAL_LOGGING) Serial.println(lockPayload);
String action = deserializeLockJson(lockPayload);
if (action == "arm" && lockState == LOCK_OFF && LEDState == LED_OFF) {
logEvent(LOG_COMM_LOCK_ARM);
lockState = LOCK_PREARM;
} else if (action == "disarm" && lockState != LOCK_ON) {
logEvent(LOG_COMM_LOCK_DISARM);
if (SERIAL_LOGGING) Serial.println("[INFO] Unarming interlock.");
logEvent(LOG_LOCK_CANCEL);
logEvent(LOG_LOCK_DISARM);
lockState = LOCK_OFF;
}
if (SERIAL_LOGGING) Serial.println("[INFO] action: " + action);
} else {
if (SERIAL_LOGGING) Serial.println("[ERROR] Resource not found.");
logEvent(LOG_COMM_LOCK_FAIL, lockHTTPCodeStr.c_str(), lockHTTPCodeStr.length());
if (logErrors) logEvent(LOG_COMM_LOCK_FAIL, lockHTTPCodeStr.c_str(), lockHTTPCodeStr.length());
logErrors = false;
}
} else {
if (SERIAL_LOGGING) Serial.printf("[ERROR] POST failed, error: %s\n", lockHTTP.errorToString(lockHTTPCode).c_str());
logEvent(LOG_COMM_LOCK_FAIL, lockHTTPCodeStr.c_str(), lockHTTPCodeStr.length());
if (logErrors) logEvent(LOG_COMM_LOCK_FAIL, lockHTTPCodeStr.c_str(), lockHTTPCodeStr.length());
logErrors = false;
}
lockHTTP.end();
@ -549,6 +581,9 @@ void postState()
void getCards()
{
// Don't log more than one error at a time
static bool logErrors = true;
HTTPClient cardHTTP;
//cardHTTP.begin("https://url", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS
@ -565,6 +600,8 @@ void getCards()
if (SERIAL_LOGGING) Serial.printf("[INFO] GET success, code: %d\n", cardHTTPCode);
if (cardHTTPCode == HTTP_CODE_OK) {
logErrors = true;
if (SERIAL_LOGGING) Serial.print("[INFO] Resource found, parsing response: ");
String cardPayload = cardHTTP.getString();
cardPayload += String(EEPROM_END_MARKER);
@ -581,11 +618,13 @@ void getCards()
if (SERIAL_LOGGING) Serial.println("[INFO] Finished getting card data.");
} else {
if (SERIAL_LOGGING) Serial.println("[ERROR] Resource not found.");
logEvent(LOG_COMM_CARD_FAIL, cardHTTPCodeStr.c_str(), cardHTTPCodeStr.length());
if (logErrors) logEvent(LOG_COMM_CARD_FAIL, cardHTTPCodeStr.c_str(), cardHTTPCodeStr.length());
logErrors = false;
}
} else {
if (SERIAL_LOGGING) Serial.printf("[ERROR] POST failed, error: %s\n", cardHTTP.errorToString(cardHTTPCode).c_str());
logEvent(LOG_COMM_CARD_FAIL, cardHTTPCodeStr.c_str(), cardHTTPCodeStr.length());
if (logErrors) logEvent(LOG_COMM_CARD_FAIL, cardHTTPCodeStr.c_str(), cardHTTPCodeStr.length());
logErrors = false;
}
cardHTTP.end();
@ -593,6 +632,9 @@ void getCards()
void postInfolog()
{
// Don't log more than one error at a time
static bool logErrors = true;
HTTPClient infoHTTP;
//infoHTTP.begin("https://url", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS
@ -611,24 +653,32 @@ void postInfolog()
if (SERIAL_LOGGING) Serial.printf("[INFO] POST success, code: %d\n", infoHTTPCode);
if (infoHTTPCode == HTTP_CODE_OK) {
logErrors = true;
if (SERIAL_LOGGING) Serial.print("[INFO] Resource found, parsing response: ");
String infoPayload = infoHTTP.getString();
if (SERIAL_LOGGING) Serial.println(infoPayload);
uint32_t unixTime = deserializeInfoJson(infoPayload);
uint8_t processed;
uint32_t unixTime;
deserializeInfoJson(infoPayload, &processed, &unixTime);
struct timeval tv = { .tv_sec = unixTime, .tv_usec = 0 };
struct timezone tz = { .tz_minuteswest = 0, .tz_dsttime = 0 };
settimeofday(&tv, &tz);
removeLogRecords(processed);
if (SERIAL_LOGGING) Serial.print("[INFO] Set system time to: ");
if (SERIAL_LOGGING) Serial.println(unixTime);
} else {
if (SERIAL_LOGGING) Serial.println("[ERROR] Resource not found.");
logEvent(LOG_COMM_INFO_FAIL, infoHTTPCodeStr.c_str(), infoHTTPCodeStr.length());
if (logErrors) logEvent(LOG_COMM_INFO_FAIL, infoHTTPCodeStr.c_str(), infoHTTPCodeStr.length());
logErrors = false;
}
} else {
if (SERIAL_LOGGING) Serial.printf("[ERROR] POST failed, error: %s\n", infoHTTP.errorToString(infoHTTPCode).c_str());
logEvent(LOG_COMM_INFO_FAIL, infoHTTPCodeStr.c_str(), infoHTTPCodeStr.length());
if (logErrors) logEvent(LOG_COMM_INFO_FAIL, infoHTTPCodeStr.c_str(), infoHTTPCodeStr.length());
logErrors = false;
}
infoHTTP.end();