Skip to content

Commit

Permalink
Simplify OTA
Browse files Browse the repository at this point in the history
  • Loading branch information
vshymanskyy committed Aug 3, 2021
1 parent 41ea0ba commit d51fd22
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 168 deletions.
9 changes: 9 additions & 0 deletions examples/Blynk.Edgent/Edgent_MKR1000/Edgent_MKR1000.ino
@@ -1,3 +1,12 @@
/*
* Required libraries:
* - WiFi101
* - ArduinoOTA
* - ArduinoHttpClient
* - Timer5
*
* Please also update the WiFi module firmware, if needed
*/

// Fill-in information from your Blynk Template here
//#define BLYNK_TEMPLATE_ID "TMPLxxxxxx"
Expand Down
94 changes: 22 additions & 72 deletions examples/Blynk.Edgent/Edgent_MKR1000/OTA.h
@@ -1,4 +1,7 @@

#include <ArduinoOTA.h> // only for InternalStorage
#include <ArduinoHttpClient.h>

#define OTA_FATAL(...) { BLYNK_LOG1(__VA_ARGS__); delay(1000); restartMCU(); }

#define USE_SSL
Expand All @@ -10,6 +13,7 @@ extern BlynkTimer edgentTimer;
BLYNK_WRITE(InternalPinOTA) {
overTheAirURL = param.asString();

// Force HTTPS update
overTheAirURL.replace("http://", "https://");

edgentTimer.setTimeout(2000L, [](){
Expand All @@ -23,33 +27,6 @@ BLYNK_WRITE(InternalPinOTA) {
});
}

#include <ArduinoOTA.h> // only for InternalStorage

#if defined(USE_SSL)

WiFiClient* connectSSL(const String& host, const int port)
{
// Reuse Client
WiFiSSLClient* clientSSL = &_blynkWifiClient;
//WiFiSSLClient* clientSSL = new WiFiSSLClient();

if (!clientSSL->connect(host.c_str(), port)) {
OTA_FATAL(F("Connection failed"));
}
return clientSSL;
}

#endif

WiFiClient* connectTCP(const String& host, const int port)
{
WiFiClient* clientTCP = new WiFiClient();
if (!clientTCP->connect(host.c_str(), port)) {
OTA_FATAL(F("Client not connected"));
}
return clientTCP;
}

bool parseURL(String url, String& protocol, String& host, int& port, String& uri)
{
int index = url.indexOf(':');
Expand Down Expand Up @@ -104,72 +81,45 @@ void enterOTA() {

Client* client = NULL;
if (protocol == "http") {
client = connectTCP(host, port);
client = new WiFiClient();
#ifdef USE_SSL
} else if (protocol == "https") {
client = connectSSL(host, port);
client = &_blynkWifiClient;
//client = new WiFiClientSecure();
#endif
} else {
OTA_FATAL(String("Unsupported protocol: ") + protocol);
}
HttpClient http(*client, host, port);
http.get(url);

client->print(String("GET ") + url + " HTTP/1.0\r\n"
+ "Host: " + host + "\r\n"
+ "Connection: keep-alive\r\n"
+ "\r\n");

uint32_t timeout = millis();
while (client->connected() && !client->available()) {
if (millis() - timeout > 10000L) {
OTA_FATAL("Response timeout");
}
delay(10);
int statusCode = http.responseStatusCode();
if (statusCode != 200) {
http.stop();
OTA_FATAL(String("HTTP status code: ") + statusCode);
}

// Collect headers
String md5;
int contentLength = 0;

while (client->available()) {
String line = client->readStringUntil('\n');
line.trim();
//DEBUG_PRINT(line); // Uncomment this to show response headers
line.toLowerCase();
if (line.startsWith("content-length:")) {
contentLength = line.substring(line.lastIndexOf(':') + 1).toInt();
} else if (line.startsWith("x-md5:")) {
md5 = line.substring(line.lastIndexOf(':') + 1);
} else if (line.length() == 0) {
break;
}
delay(10);
}

if (contentLength <= 0) {
int contentLength = http.contentLength();
if (contentLength == HttpClient::kNoContentLengthHeader) {
http.stop();
OTA_FATAL("Content-Length not defined");
}

if (!InternalStorage.open(contentLength)) {
client->stop();
OTA_FATAL("OTA begin failed");
http.stop();
OTA_FATAL("Not enough space to store the update");
}
//InternalStorage.debugPrint();

DEBUG_PRINT("Flashing...");

int written = 0;
int prevProgress = 0;
uint8_t buff[256];
while (client->connected() && written < contentLength) {
delay(10);
timeout = millis();
while (client->connected() && !client->available()) {
delay(1);
if (millis() - timeout > 10000L) {
OTA_FATAL("Timeout");
}
}

int len = client->read(buff, sizeof(buff));
int len = http.readBytes(buff, sizeof(buff));
if (len <= 0) continue;

for (int i = 0; i<len; i++) {
Expand All @@ -184,11 +134,11 @@ void enterOTA() {
}
}
BLYNK_PRINT.println();
client->stop();
InternalStorage.close();
http.stop();

if (written != contentLength) {
OTA_FATAL(String("Write failed. Written ") + written + " / " + contentLength + " bytes");
OTA_FATAL(String("Interrupted at ") + written + " / " + contentLength + " bytes");
}

DEBUG_PRINT("=== Update successfully completed. Rebooting.");
Expand Down
9 changes: 9 additions & 0 deletions examples/Blynk.Edgent/Edgent_MKR1010/Edgent_MKR1010.ino
@@ -1,3 +1,12 @@
/*
* Required libraries:
* - WiFiNINA
* - ArduinoOTA
* - ArduinoHttpClient
* - Timer5
*
* Please also update the WiFi module firmware, if needed
*/

// Fill-in information from your Blynk Template here
//#define BLYNK_TEMPLATE_ID "TMPLxxxxxx"
Expand Down
94 changes: 22 additions & 72 deletions examples/Blynk.Edgent/Edgent_MKR1010/OTA.h
@@ -1,4 +1,7 @@

#include <ArduinoOTA.h> // only for InternalStorage
#include <ArduinoHttpClient.h>

#define OTA_FATAL(...) { BLYNK_LOG1(__VA_ARGS__); delay(1000); restartMCU(); }

#define USE_SSL
Expand All @@ -10,6 +13,7 @@ extern BlynkTimer edgentTimer;
BLYNK_WRITE(InternalPinOTA) {
overTheAirURL = param.asString();

// Force HTTPS update
overTheAirURL.replace("http://", "https://");

edgentTimer.setTimeout(2000L, [](){
Expand All @@ -23,33 +27,6 @@ BLYNK_WRITE(InternalPinOTA) {
});
}

#include <ArduinoOTA.h> // only for InternalStorage

#if defined(USE_SSL)

WiFiClient* connectSSL(const String& host, const int port)
{
// Reuse Client
WiFiSSLClient* clientSSL = &_blynkWifiClient;
//WiFiSSLClient* clientSSL = new WiFiSSLClient();

if (!clientSSL->connect(host.c_str(), port)) {
OTA_FATAL(F("Connection failed"));
}
return clientSSL;
}

#endif

WiFiClient* connectTCP(const String& host, const int port)
{
WiFiClient* clientTCP = new WiFiClient();
if (!clientTCP->connect(host.c_str(), port)) {
OTA_FATAL(F("Client not connected"));
}
return clientTCP;
}

bool parseURL(String url, String& protocol, String& host, int& port, String& uri)
{
int index = url.indexOf(':');
Expand Down Expand Up @@ -104,72 +81,45 @@ void enterOTA() {

Client* client = NULL;
if (protocol == "http") {
client = connectTCP(host, port);
client = new WiFiClient();
#ifdef USE_SSL
} else if (protocol == "https") {
client = connectSSL(host, port);
client = &_blynkWifiClient;
//client = new WiFiClientSecure();
#endif
} else {
OTA_FATAL(String("Unsupported protocol: ") + protocol);
}
HttpClient http(*client, host, port);
http.get(url);

client->print(String("GET ") + url + " HTTP/1.0\r\n"
+ "Host: " + host + "\r\n"
+ "Connection: keep-alive\r\n"
+ "\r\n");

uint32_t timeout = millis();
while (client->connected() && !client->available()) {
if (millis() - timeout > 10000L) {
OTA_FATAL("Response timeout");
}
delay(10);
int statusCode = http.responseStatusCode();
if (statusCode != 200) {
http.stop();
OTA_FATAL(String("HTTP status code: ") + statusCode);
}

// Collect headers
String md5;
int contentLength = 0;

while (client->available()) {
String line = client->readStringUntil('\n');
line.trim();
//DEBUG_PRINT(line); // Uncomment this to show response headers
line.toLowerCase();
if (line.startsWith("content-length:")) {
contentLength = line.substring(line.lastIndexOf(':') + 1).toInt();
} else if (line.startsWith("x-md5:")) {
md5 = line.substring(line.lastIndexOf(':') + 1);
} else if (line.length() == 0) {
break;
}
delay(10);
}

if (contentLength <= 0) {
int contentLength = http.contentLength();
if (contentLength == HttpClient::kNoContentLengthHeader) {
http.stop();
OTA_FATAL("Content-Length not defined");
}

if (!InternalStorage.open(contentLength)) {
client->stop();
OTA_FATAL("OTA begin failed");
http.stop();
OTA_FATAL("Not enough space to store the update");
}
//InternalStorage.debugPrint();

DEBUG_PRINT("Flashing...");

int written = 0;
int prevProgress = 0;
uint8_t buff[256];
while (client->connected() && written < contentLength) {
delay(10);
timeout = millis();
while (client->connected() && !client->available()) {
delay(1);
if (millis() - timeout > 10000L) {
OTA_FATAL("Timeout");
}
}

int len = client->read(buff, sizeof(buff));
int len = http.readBytes(buff, sizeof(buff));
if (len <= 0) continue;

for (int i = 0; i<len; i++) {
Expand All @@ -184,11 +134,11 @@ void enterOTA() {
}
}
BLYNK_PRINT.println();
client->stop();
InternalStorage.close();
http.stop();

if (written != contentLength) {
OTA_FATAL(String("Write failed. Written ") + written + " / " + contentLength + " bytes");
OTA_FATAL(String("Interrupted at ") + written + " / " + contentLength + " bytes");
}

DEBUG_PRINT("=== Update successfully completed. Rebooting.");
Expand Down

0 comments on commit d51fd22

Please sign in to comment.