SSL Socket errors
-
Greetings and thank-you for your time.
I am trying to send camera images from my ESP32 (M5 Stack PoECAM) to my personal google drive.
following this tutorial :
https://hobby-it.com/m5timer_gdrive-2/I have setup SSLClient with the EthernetLarge library the jpgs arrive and but they are corrupted/incomplete. Any ideas why this might be happening, I have tried different chunk sizes no effect ?
I don't believe its hardware as the example sketches all work as intended
errors/warnings
SSLClient)(SSL_WARN)(connected): Socket was dropped unexpectedly (this can be an alternative to closing the connection) (SSLClient)(SSL_ERROR)(m_print_ssl_error): SSL_CLIENT_WRITE_FAIL (SSLClient)(SSL_ERROR)(available): Cannot operate if the write error is not reset:
The project is on github (https://gitlab.com/ArchNemsys/esp32-poe-cam) the code for the relevant function (sensitive data removed) is posted below apologies I was halfway through refactoring it to use char bufs rather than strings:
#include <SSLClient.h> #include "gdrive_trust.h" #define WRITE_SIZE_MAX 1024 // //#define API_PORT 443 //#define API_PATH_TOKEN "/oauth2/v4/token" const char* refreshServer = "oauth2.googleapis.com"; const char* refreshUri = "/token"; const char* apiServer = "www.googleapis.com"; const char* apiUri = "/upload/drive/v3/files?uploadType=multipart"; char accessToken[2048]; // ethClient is declared elsewhere but works perfectly outside this funciton SSLClient httpsClient(ethClient, gdriveTAs, 1, 25); // SSLClient::write, is buffered does not actually write to the network. you must call SSLClient::available or SSLClient::flush, int waitingTime = 10000; // Wait 10 seconds to google response. // Send JPEG by Http POST void postGoogleDriveByAPI() { Serial.println("Connect to " + String(apiServer)); if (httpsClient.connect(apiServer, 443)) { Serial.println("Connection successful"); // Get Time for save file name struct tm timeinfo; if(!getLocalTime(&timeinfo)){ Serial.println("Failed to obtain time 1"); return; } char saveFilename[64]; /* char metadata[256]; const char* startBoundry = "--foo_bar_baz\r\n" "Content-Type:image/jpeg\r\n\r\n"; const char* endBoundry = "\r\n--foo_bar_baz--"; */ strftime (saveFilename,64,"ALERT_%A_%B_%d_%Y_%Hh%Mm%Ss.jpg",&timeinfo); Serial.println(saveFilename); /* snprintf( metadata, 256, "--foo_bar_baz\r\n" "Content-Type: application/json; charset=UTF-8\r\n\r\n" "{\"name\":\"%s\",\"parents\":[\"%s\"]}\r\n\r\n" , saveFilename, PARENT_ID ); unsigned long contentsLength = strlen(metadata) + strlen(startBoundry) + fb->len + strlen(endBoundry); snprintf(header,256, "POST %s HTTP/1.1\r\n" "HOST: %s \r\n" "Connection: close\r\n" "content-type: multipart/related; boundary=foo_bar_baz\r\n" "content-length: %u \r\n" "authorization: Bearer %s \r\n\r\n", apiUri, apiServer, contentsLength, accessToken); */ String metadata = "--foo_bar_baz\r\n" "Content-Type: application/json; charset=UTF-8\r\n\r\n" "{\"name\":\"" + String(saveFilename) + "\",\"parents\":[\"" + String(PARENT_ID) + "\"]}\r\n\r\n"; // parents:save folder //"{\"name\":\"" + saveFilename + "\"}\r\n\r\n"; // parerents is Optional String startBoundry = "--foo_bar_baz\r\n" "Content-Type:image/jpeg\r\n\r\n"; String endBoundry = "\r\n--foo_bar_baz--"; unsigned long contentsLength = metadata.length() + startBoundry.length() + fb->len + endBoundry.length(); String header = "POST " + String(apiUri) + " HTTP/1.1\r\n" + "HOST: " + String(apiServer) + "\r\n" + "Connection: close\r\n" + "content-type: multipart/related; boundary=foo_bar_baz\r\n" + "content-length: " + String(contentsLength) + "\r\n" + "authorization: Bearer " + accessToken + "\r\n\r\n"; Serial.println("Send JPEG DATA by API"); httpsClient.print(header); httpsClient.print(metadata); httpsClient.print(startBoundry); // JPEG data is separated into 1000 bytes and POST int chunk = 1000; unsigned long dataLength = fb->len; uint8_t* bufAddr = fb->buf; for(unsigned long i = 0; i < dataLength ;i=i+chunk) { if ( (i + chunk) < dataLength ) { httpsClient.write(( bufAddr + i ), chunk); } else if (dataLength%chunk != 0) { httpsClient.write(( bufAddr + i ), dataLength%chunk); } } httpsClient.print(endBoundry); Serial.println("Waiting for response."); long int StartTime=millis(); while (!httpsClient.available()) { Serial.print("."); delay(100); if ((StartTime+waitingTime) < millis()) { Serial.println(); Serial.println("No response."); break; } } } else { Serial.println("Connected to " + String(refreshServer) + " failed."); } httpsClient.stop(); }
-
error found the Framebuffer fb was being freed before the SSLClient could finish writing hence the corrupted drive image.