diff --git a/firmware/.gitignore b/firmware/.gitignore new file mode 100644 index 0000000..6582c00 --- /dev/null +++ b/firmware/.gitignore @@ -0,0 +1,6 @@ +# Editor +*.swp +*.swo + +# Binary +*.bin diff --git a/firmware/firmware.ino b/firmware/firmware.ino index 934244b..6af3cdd 100644 --- a/firmware/firmware.ino +++ b/firmware/firmware.ino @@ -3,16 +3,20 @@ #include #include #include +#include #include #include #include +const char *FIRMWARE_VERSION = "MRWIZARD 0008 MRWIZARD"; + const char *WIFI_SSID PROGMEM = "Protospace"; const char *WIFI_PASS PROGMEM = "yycmakers"; char wifiMACAddr[20] = ""; const String SOCKET_URL = String("http://tools-socket.protospace.ca/api/lockout/"); const String CARD_URL = String("http://tools-auth.protospace.ca/cards/"); const String INFOLOG_URL = String("http://tools-auth.protospace.ca/infolog/"); +const String UPDATE_URL = String("http://tools-auth.protospace.ca/update/"); Ticker ticker; @@ -113,6 +117,7 @@ enum eventCodes LOG_CARD_GOOD_READ, LOG_CARD_ACCEPTED, LOG_CARD_DENIED, + LOG_UPDATE_FAILED, }; struct __attribute__((packed)) logData { @@ -170,9 +175,11 @@ void setup() struct timeval tv = { .tv_sec = 0, .tv_usec = 0 }; struct timezone tz = { .tz_minuteswest = 0, .tz_dsttime = 0 }; settimeofday(&tv, &tz); - if (SERIAL_LOGGING) Serial.println("[INFO] Set system time to 0."); - logEvent(LOG_BOOT_UP); + + logEvent(LOG_BOOT_UP, &FIRMWARE_VERSION[9], 4); + if (SERIAL_LOGGING) Serial.print("[INFO] Booting firmware version: "); + if (SERIAL_LOGGING) Serial.println(FIRMWARE_VERSION); pinMode(RELAY_PIN, OUTPUT); pinMode(GREEN_BUTTON_PIN, INPUT_PULLUP); @@ -510,15 +517,16 @@ String serializeLog() { return "{\"log\": \"" + base64::encode((uint8_t *) eventLog, logLengthBytes, false) + "\"}"; } -void deserializeInfoJson(String input, uint8_t *processed, uint32_t *unixTime) +void deserializeInfoJson(String input, uint8_t *processed, uint32_t *unixTime, String *version) { // Generated with: https://arduinojson.org/assistant/ - const size_t bufferSize = JSON_OBJECT_SIZE(2) + 50; + const size_t bufferSize = JSON_OBJECT_SIZE(3) + 70; StaticJsonBuffer jsonBuffer; JsonObject& root = jsonBuffer.parseObject(input); *processed = root["processed"]; *unixTime = root["unixTime"]; + *version = root["version"].as(); } @@ -660,7 +668,8 @@ void postInfolog() if (SERIAL_LOGGING) Serial.println(infoPayload); uint8_t processed; uint32_t unixTime; - deserializeInfoJson(infoPayload, &processed, &unixTime); + String version = String(); + deserializeInfoJson(infoPayload, &processed, &unixTime, &version); struct timeval tv = { .tv_sec = unixTime, .tv_usec = 0 }; struct timezone tz = { .tz_minuteswest = 0, .tz_dsttime = 0 }; @@ -668,6 +677,18 @@ void postInfolog() removeLogRecords(processed); + if (version != FIRMWARE_VERSION && lockState == LOCK_OFF) { + noInterrupts(); + if (SERIAL_LOGGING) Serial.println("[INFO] Firmware out of date. Updating..."); + WiFiClient client; + int16_t update_response = ESPhttpUpdate.update(client, UPDATE_URL + wifiMACAddr + "/"); + interrupts(); + + if (SERIAL_LOGGING) printf("[ERROR] %s\n", ESPhttpUpdate.getLastErrorString().c_str()); + String lastErrorNum = String(ESPhttpUpdate.getLastError()); + logEvent(LOG_UPDATE_FAILED, lastErrorNum.c_str(), lastErrorNum.length()); + } + if (SERIAL_LOGGING) Serial.print("[INFO] Set system time to: "); if (SERIAL_LOGGING) Serial.println(unixTime); } else {