Greetings and thank-you for your time. I'm a hobbyist desktop c++ programmer and teacher by profession the embed world has been a bit of a learning curve.
I am trying to send camera images from my ESP32 (M5 Stack PoECAM) to my personal google drive.
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 the code for the relevant function 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();
}