Commit a4859a38 authored by Simon Gölzhäuser's avatar Simon Gölzhäuser
Browse files

Improved file upload handling

parent 25d46c5f
......@@ -121,7 +121,6 @@ File g_fAvi;
File g_fIndex;
char g_aviFileName[50];
char g_logfileName[50];
// --------------------------------------------------
// Internet stuff
......@@ -132,6 +131,8 @@ char g_wifiPass[50];
bool g_bWifiCredentialsSet = false;
#ifdef FILEUPLOAD
File g_fLogUpload;
#ifdef HTTPS
WiFiClientSecure g_WifiClient;
#else
......@@ -178,7 +179,6 @@ float g_fMostRecentAvgFramesize = 0;
uint8_t* g_pFrameBuffer = NULL;
bool g_bShouldRecord = false;
bool g_bIsRecording = false;
long g_lBytesBeforeLast100Frames = 0;
long g_lTimeBeforeLast100Frames = 0;
......@@ -310,7 +310,9 @@ void inline print2Quartetts(unsigned long i, unsigned long j, File file) {
*/
void getAviFileName(char aviFileName[50]) {
#ifdef TESTING
sprintf(aviFileName, "/rec-TEST.avi");
static int nFileNum = 0;
sprintf(aviFileName, "/rec-TEST-%d.avi", nFileNum);
++nFileNum;
#else
DateTime now = g_rtc.now();
sprintf(aviFileName, "/rec-%d-%02d-%02dT%02d-%02d-%02d.avi", now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());
......@@ -331,6 +333,21 @@ void getLogfileName(char logfileName[50]) {
}
#ifdef FILEUPLOAD
/**
* Returns a current time based name for the logfile.
*/
void getFileUploadLogfileName(char logfileName[50]) {
#ifdef TESTING
sprintf(logfileName, "/log-upload-TEST.txt");
#else
DateTime now = g_rtc.now();
sprintf(logfileName, "/log-upload-%d-%02d-%02dT%02d-%02d-%02d.txt", now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());
#endif
}
#endif
/**
* If there is no camera or SD card, flash little red led (SOS) and reboot after some time.
*/
......@@ -716,6 +733,39 @@ void readConfigFile() {
// File upload functions
// --------------------------------------------------
#ifdef FILEUPLOAD
/**
* Finds the next not-uploaded AVI file available.
*/
bool getNextFileForUpload(char fileName[50]) {
File fRoot = SD_MMC.open("/");
if (!fRoot) {
return false;
}
File fFile = fRoot.openNextFile();
while (fFile) {
if (!fFile.isDirectory()) {
if (strstr(fFile.name(), ".avi") != NULL) {
if (strstr(fFile.name(), "U-rec") == NULL) {
strcpy(fileName, fFile.name());
#ifdef SERIALPRINTS
Serial.printf("Got next file for upload: %s\n", fileName);
#endif
g_fLogUpload.printf("Got next file for upload: %s\n", fileName);
g_fLogUpload.flush();
return true;
}
}
}
fFile = fRoot.openNextFile();
}
return false;
}
#endif
#ifdef FILEUPLOAD
/**
* Uploads a file to the specified remote host endpoint.
......@@ -723,8 +773,14 @@ void readConfigFile() {
bool uploadFile(char fileName[50]) {
File fFile = SD_MMC.open(fileName, "r");
long lStartMillis = 0;
bool bSuccess = true;
if (!fFile) {
#ifdef SERIALPRINTS
Serial.printf("Connection to %s:%d failed (took %ld ms)\n", fileName);
#endif
g_fLogUpload.printf("Connection to %s:%d failed (took %ld ms)\n", fileName);
g_fLogUpload.flush();
return false;
}
......@@ -738,16 +794,26 @@ bool uploadFile(char fileName[50]) {
#ifdef SERIALPRINTS
Serial.printf("Connection to %s:%d failed (took %ld ms)\n", g_postHost, g_nPostPort, (millis() - lStartMillis));
#endif
g_fLog.printf("Connection to %s:%d failed (took %ld ms)\n", g_postHost, g_nPostPort, (millis() - lStartMillis));
g_fLog.flush();
g_fLogUpload.printf("Connection to %s:%d failed (took %ld ms)\n", g_postHost, g_nPostPort, (millis() - lStartMillis));
g_fLogUpload.flush();
return false;
}
#ifdef SERIALPRINTS
Serial.printf("Connection to %s:%d established (took %ld ms)\n", g_postHost, g_nPostPort, (millis() - lStartMillis));
#endif
g_fLog.printf("Connection to %s:%d established (took %ld ms)\n", g_postHost, g_nPostPort, (millis() - lStartMillis));
g_fLogUpload.printf("Connection to %s:%d established (took %ld ms)\n", g_postHost, g_nPostPort, (millis() - lStartMillis));
// --- 1. Preparation ---
if (g_bShouldRecord) {
g_WifiClient.stop();
#ifdef SERIALPRINTS
Serial.println("Upload interrupted by recording start");
#endif
g_fLogUpload.println("Upload interrupted by recording start");
g_fLogUpload.flush();
return false;
}
char postHeader[500];
sprintf(postHeader, "POST %s HTTP/1.1\r\nHost: %s:%d\r\nContent-Type: multipart/form-data;boundary=%s\r\nAuthorization: Bearer %s\r\n", g_postEndpoint, g_postHost, g_nPostPort, g_postBoundary, g_bearer);
......@@ -770,7 +836,7 @@ bool uploadFile(char fileName[50]) {
#ifdef SERIALPRINTS
Serial.printf("Uploading file %s (%d)\n", fileName, fFile.size());
#endif
g_fLog.printf("Uploading file %s (%d)\n", fileName, fFile.size());
g_fLogUpload.printf("Uploading file %s (%d)\n", fileName, fFile.size());
lStartMillis = millis();
g_WifiClient.print(postHeader);
......@@ -779,7 +845,7 @@ bool uploadFile(char fileName[50]) {
#ifdef SERIALPRINTS
Serial.printf("Finished writing headers (took %d ms)\n", (millis() - lStartMillis));
#endif
g_fLog.printf("Finished writing headers (took %d ms)\n", (millis() - lStartMillis));
g_fLogUpload.printf("Finished writing headers (took %d ms)\n", (millis() - lStartMillis));
lStartMillis = millis();
g_WifiClient.print(requestHeader);
......@@ -796,6 +862,16 @@ bool uploadFile(char fileName[50]) {
nToWrite = fFile.readBytes(g_pFileSendBuffer, nToRead);
nWritten += g_WifiClient.write((uint8_t*)g_pFileSendBuffer, nToWrite);
nAvailable = fFile.available();
if (g_bShouldRecord) {
fFile.close();
g_WifiClient.stop();
#ifdef SERIALPRINTS
Serial.println("Upload interrupted by recording start");
#endif
g_fLogUpload.println("Upload interrupted by recording start");
g_fLogUpload.flush();
return false;
}
}
g_WifiClient.print(tail);
......@@ -803,7 +879,7 @@ bool uploadFile(char fileName[50]) {
#ifdef SERIALPRINTS
Serial.printf("Finished writing content (took %d ms)\n", (millis() - lStartMillis));
#endif
g_fLog.printf("Finished writing content (took %d ms)\n", (millis() - lStartMillis));
g_fLogUpload.printf("Finished writing content (took %d ms)\n", (millis() - lStartMillis));
fFile.close();
......@@ -832,18 +908,45 @@ bool uploadFile(char fileName[50]) {
}
++nIndex;
}
if (g_bShouldRecord) {
g_WifiClient.stop();
#ifdef SERIALPRINTS
Serial.println("Upload interrupted by recording start");
#endif
g_fLogUpload.println("Upload interrupted by recording start");
g_fLogUpload.flush();
return false;
}
delay(10);
}
if (response[0] != '\0') {
if (response[0] == '\0') {
bSuccess = false;
#ifdef SERIALPRINTS
Serial.println("Upload failed, no response after 5s");
#endif
g_fLogUpload.println("Upload failed, no response after 5s");
} else {
#ifdef SERIALPRINTS
Serial.printf("Response:\n%s", response);
#endif
g_fLog.printf("Response:\n%s", response);
g_fLogUpload.printf("Response:\n%s", response);
if (strstr(response, "200 OK") != NULL) {
#ifdef SERIALPRINTS
Serial.println("Upload successful");
#endif
g_fLogUpload.println("Upload successful");
} else {
bSuccess = false;
#ifdef SERIALPRINTS
Serial.println("Upload failed");
#endif
g_fLogUpload.println("Upload failed");
}
}
g_fLog.flush();
g_fLogUpload.flush();
return true;
return bSuccess;
}
#endif
......@@ -861,8 +964,8 @@ void markFileAsUploaded(char fileName[50]) {
#ifdef SERIALPRINTS
Serial.printf("File %s marked as uploaded (-> %s)\n", fileName, newFileName);
#endif
g_fLog.printf("File %s marked as uploaded (-> %s)\n", fileName, newFileName);
g_fLog.flush();
g_fLogUpload.printf("File %s marked as uploaded (-> %s)\n", fileName, newFileName);
g_fLogUpload.flush();
}
#endif
......@@ -879,8 +982,8 @@ void handleFileUpload(char fileName[50]) {
#ifdef SERIALPRINTS
Serial.println("No WiFi credentials set");
#endif
g_fLog.println("No WiFi credentials set");
g_fLog.flush();
g_fLogUpload.println("No WiFi credentials set");
g_fLogUpload.flush();
return;
}
......@@ -888,8 +991,8 @@ void handleFileUpload(char fileName[50]) {
#ifdef SERIALPRINTS
Serial.println("No bearer token set");
#endif
g_fLog.println("No bearer token set");
g_fLog.flush();
g_fLogUpload.println("No bearer token set");
g_fLogUpload.flush();
return;
}
......@@ -903,8 +1006,18 @@ void handleFileUpload(char fileName[50]) {
#ifdef SERIALPRINTS
Serial.printf("Connection to WiFi %s failed\n\n", g_wifiSsid);
#endif
g_fLog.printf("Connection to WiFi %s failed\n\n", g_wifiPass);
g_fLog.flush();
g_fLogUpload.printf("Connection to WiFi %s failed\n\n", g_wifiPass);
g_fLogUpload.flush();
return;
}
if (g_bShouldRecord) {
WiFi.disconnect();
WiFi.mode(WIFI_OFF);
#ifdef SERIALPRINTS
Serial.println("Upload interrupted by recording start\n");
#endif
g_fLogUpload.println("Upload interrupted by recording start\n");
g_fLogUpload.flush();
return;
}
}
......@@ -914,21 +1027,21 @@ void handleFileUpload(char fileName[50]) {
Serial.printf("Connection to WiFi %s successful\n", g_wifiSsid);
Serial.printf("RSSI: %d, IP: %d.%d.%d.%d\n", WiFi.RSSI(), ip[0], ip[1], ip[2], ip[3]);
#endif
g_fLog.printf("Connection to WiFi %s successful\n", g_wifiPass);
g_fLog.printf("RSSI: %d, IP: %d.%d.%d.%d\n", WiFi.RSSI(), ip[0], ip[1], ip[2], ip[3]);
g_fLogUpload.printf("Connection to WiFi %s successful\n", g_wifiPass);
g_fLogUpload.printf("RSSI: %d, IP: %d.%d.%d.%d\n", WiFi.RSSI(), ip[0], ip[1], ip[2], ip[3]);
// --- 3. Upload file ---
#ifdef FLASHLIGHTINDICATOR
digitalWrite(PIN_FLASHLIGHT, HIGH);
#else
digitalWrite(PIN_REDLED, LOW);
#endif
if (uploadFile(g_aviFileName)) {
markFileAsUploaded(g_aviFileName);
if (uploadFile(fileName)) {
markFileAsUploaded(fileName);
}
#ifdef FLASHLIGHTINDICATOR
digitalWrite(PIN_FLASHLIGHT, LOW);
#else
......@@ -943,8 +1056,8 @@ void handleFileUpload(char fileName[50]) {
#ifdef SERIALPRINTS
Serial.println();
#endif
g_fLog.println();
g_fLog.flush();
g_fLogUpload.println();
g_fLogUpload.flush();
}
#endif
......@@ -1408,9 +1521,9 @@ void cameraLoop (void* pvParameter) {
g_u16AviFrameCnt = 0;
g_bShouldRecord = false;
g_bIsRecording = false;
#ifdef FILEUPLOAD
char fileName[50];
g_pFileSendBuffer = (char*)malloc(g_nFileSendBufferSize);
#endif
......@@ -1419,12 +1532,16 @@ void cameraLoop (void* pvParameter) {
while (true) {
// --- Case 1: Nothing to do ---
if ((g_u16AviFrameCnt == 0) && !g_bShouldRecord) {
#ifdef FILEUPLOAD
if (getNextFileForUpload(fileName)) {
handleFileUpload(fileName);
}
#endif
delay(100);
// --- Case 2: Start recording ---
} else if ((g_u16AviFrameCnt == 0) && g_bShouldRecord) {
g_bIsRecording = true;
g_u16AviFrameCnt++;
lTemp = millis();
......@@ -1493,10 +1610,6 @@ void cameraLoop (void* pvParameter) {
aviEnd();
#ifdef FILEUPLOAD
handleFileUpload(g_aviFileName);
#endif
// LED off
#ifdef FLASHLIGHTINDICATOR
digitalWrite(PIN_FLASHLIGHT, LOW);
......@@ -1506,8 +1619,6 @@ void cameraLoop (void* pvParameter) {
g_u16AviFrameCnt = 0;
g_bIsRecording = false;
// --- Case 4: Another frame ---
} else if ((g_u16AviFrameCnt > 0) && g_bShouldRecord) {
g_u16AviFrameCnt++;
......@@ -1582,15 +1693,16 @@ void handleRecording() {
}
#ifdef TESTING
void handleRecordingTesting() {
static bool bRecordingStarted = false;
static long lLastRecordingTrigger = 0;
static long lRecordingStart = 0;
if (!bRecordingStarted) {
if ((lLastRecordingTrigger == 0) || (millis() >= (lLastRecordingTrigger + (3 * g_lRecordTurnOffDelay)))) {
lLastRecordingTrigger = millis();
lRecordingStart = millis();
getAviFileName(g_aviFileName);
g_bShouldRecord = true;
bRecordingStarted = true;
}
if ((lRecordingStart > 0) && (millis() >= (lRecordingStart + g_lRecordTurnOffDelay))) {
......@@ -1598,6 +1710,7 @@ void handleRecordingTesting() {
lRecordingStart = 0;
}
}
#endif
// --------------------------------------------------
// Arduino functions
......@@ -1607,6 +1720,7 @@ void setup() {
esp_reset_reason_t espReset;
esp_err_t espErr;
char resetReason[20];
char logFileName[50];
#ifdef SERIALPRINTS
Serial.begin(115200);
......@@ -1639,15 +1753,14 @@ void setup() {
initSdCard();
// Open logfile
getLogfileName(g_logfileName);
g_fLog = SD_MMC.open(g_logfileName, "w");
getLogfileName(logFileName);
g_fLog = SD_MMC.open(logFileName, "w");
if (!g_fLog) {
#ifdef SERIALPRINTS
Serial.println("Failed to open logfile");
#endif
majorFail();
}
#ifdef SERIALPRINTS
Serial.println("\n----- Soap Dispenser Video Recorder -----");
Serial.print("Setup, core ");
......@@ -1657,6 +1770,20 @@ void setup() {
#endif
g_fLog.println("\n----- Soap Dispenser Video Recorder -----");
#ifdef FILEUPLOAD
// Open file upload logfile
getFileUploadLogfileName(logFileName);
g_fLogUpload = SD_MMC.open(logFileName, "w");
if (!g_fLogUpload) {
#ifdef SERIALPRINTS
Serial.println("Failed to open file upload logfile");
#endif
majorFail();
}
g_fLogUpload.println("\n----- Soap Dispenser Video Recorder -----");
g_fLogUpload.flush();
#endif
espReset = esp_reset_reason();
switch (espReset) {
case ESP_RST_UNKNOWN:
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment