ota.cpp restructured; .h file sanitization

This commit is contained in:
Klaus K Wilting 2018-11-04 19:25:11 +01:00
parent 5793b3c811
commit 3aa8a88d3a
11 changed files with 126 additions and 155 deletions

View File

@ -38,6 +38,14 @@ typedef struct {
uint8_t Message[PAYLOAD_BUFFER_SIZE]; uint8_t Message[PAYLOAD_BUFFER_SIZE];
} MessageBuffer_t; } MessageBuffer_t;
typedef struct {
uint32_t latitude;
uint32_t longitude;
uint8_t satellites;
uint16_t hdop;
uint16_t altitude;
} gpsStatus_t;
// global variables // global variables
extern configData_t cfg; // current device configuration extern configData_t cfg; // current device configuration
extern char display_line6[], display_line7[]; // screen buffers extern char display_line6[], display_line7[]; // screen buffers
@ -52,16 +60,13 @@ extern std::array<uint64_t, 0xff> beacons;
extern TaskHandle_t irqHandlerTask, wifiSwitchTask; extern TaskHandle_t irqHandlerTask, wifiSwitchTask;
#include "led.h"
#include "payload.h"
#ifdef HAS_GPS #ifdef HAS_GPS
#include "gpsread.h" #include "gpsread.h"
#endif #endif
#if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED)
#include "led.h"
#endif
#include "payload.h"
#ifdef HAS_LORA #ifdef HAS_LORA
#include "lorawan.h" #include "lorawan.h"
#endif #endif
@ -86,8 +91,4 @@ extern TaskHandle_t irqHandlerTask, wifiSwitchTask;
#include "antenna.h" #include "antenna.h"
#endif #endif
void reset_counters(void);
void blink_LED(uint16_t set_color, uint16_t set_blinkduration);
uint64_t uptime();
#endif #endif

View File

@ -8,14 +8,6 @@
#include <Wire.h> #include <Wire.h>
#endif #endif
typedef struct {
uint32_t latitude;
uint32_t longitude;
uint8_t satellites;
uint16_t hdop;
uint16_t altitude;
} gpsStatus_t;
extern TinyGPSPlus gps; // Make TinyGPS++ instance globally availabe extern TinyGPSPlus gps; // Make TinyGPS++ instance globally availabe
extern gpsStatus_t extern gpsStatus_t
gps_status; // Make struct for storing gps data globally available gps_status; // Make struct for storing gps data globally available

View File

@ -37,8 +37,6 @@ extern TaskHandle_t ledLoopTask;
void rgb_set_color(uint16_t hue); void rgb_set_color(uint16_t hue);
void blink_LED(uint16_t set_color, uint16_t set_blinkduration); void blink_LED(uint16_t set_color, uint16_t set_blinkduration);
void ledLoop(void *parameter); void ledLoop(void *parameter);
#if (HAS_LED != NOT_A_PIN)
void switch_LED(uint8_t state); void switch_LED(uint8_t state);
#endif
#endif #endif

View File

@ -11,7 +11,7 @@
#include <BintrayClient.h> #include <BintrayClient.h>
#include <string> #include <string>
void do_ota_update(); bool do_ota_update();
void start_ota_update(); void start_ota_update();
int version_compare(const String v1, const String v2); int version_compare(const String v1, const String v2);
void display(const uint8_t row, const std::string status, void display(const uint8_t row, const std::string status,

View File

@ -38,12 +38,8 @@ public:
void addStatus(uint16_t voltage, uint64_t uptime, float cputemp, uint32_t mem, void addStatus(uint16_t voltage, uint64_t uptime, float cputemp, uint32_t mem,
uint8_t reset1, uint8_t reset2); uint8_t reset1, uint8_t reset2);
void addAlarm(int8_t rssi, uint8_t message); void addAlarm(int8_t rssi, uint8_t message);
#ifdef HAS_GPS
void addGPS(gpsStatus_t value); void addGPS(gpsStatus_t value);
#endif
#ifdef HAS_BUTTON
void addButton(uint8_t value); void addButton(uint8_t value);
#endif
#if PAYLOAD_ENCODER == 1 // format plain #if PAYLOAD_ENCODER == 1 // format plain

View File

@ -2,6 +2,7 @@
#define _RCOMMAND_H #define _RCOMMAND_H
#include "senddata.h" #include "senddata.h"
#include "cyclic.h"
#include "configmanager.h" #include "configmanager.h"
#include "lorawan.h" #include "lorawan.h"
#include "macsniff.h" #include "macsniff.h"

View File

@ -3,6 +3,7 @@
#include "spislave.h" #include "spislave.h"
#include "lorawan.h" #include "lorawan.h"
#include "cyclic.h"
void SendData(uint8_t port); void SendData(uint8_t port);
void sendPayload(void); void sendPayload(void);

View File

@ -87,9 +87,8 @@ void rgb_set_color(uint16_t hue) {}
#endif #endif
#if (HAS_LED != NOT_A_PIN)
void switch_LED(uint8_t state) { void switch_LED(uint8_t state) {
#if (HAS_LED != NOT_A_PIN)
if (state == LED_ON) { if (state == LED_ON) {
// switch LED on // switch LED on
#ifdef LED_ACTIVE_LOW #ifdef LED_ACTIVE_LOW
@ -105,9 +104,8 @@ void switch_LED(uint8_t state) {
digitalWrite(HAS_LED, LOW); digitalWrite(HAS_LED, LOW);
#endif #endif
} }
}
#endif #endif
}
#if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED) #if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED)

View File

@ -26,9 +26,6 @@ const BintrayClient bintray(BINTRAY_USER, BINTRAY_REPO, BINTRAY_PACKAGE);
// Connection port (HTTPS) // Connection port (HTTPS)
const int port = 443; const int port = 443;
// Connection timeout
const uint32_t RESPONSE_TIMEOUT_MS = 5000;
// Variables to validate firmware content // Variables to validate firmware content
int volatile contentLength = 0; int volatile contentLength = 0;
bool volatile isValidContentType = false; bool volatile isValidContentType = false;
@ -43,24 +40,17 @@ inline String getHeaderValue(String header, String headerName) {
void start_ota_update() { void start_ota_update() {
/* /*
// check battery status if we can before doing ota // check battery status if we can before doing ota
#ifdef HAS_BATTERY_PROBE #ifdef HAS_BATTERY_PROBE
if (!batt_sufficient()) { if (!batt_sufficient()) {
ESP_LOGW(TAG, "Battery voltage %dmV too low for OTA", batt_voltage); ESP_LOGW(TAG, "Battery voltage %dmV too low for OTA", batt_voltage);
return; return;
} }
#endif #endif
*/ */
// turn on LED switch_LED(LED_ON);
#if (HAS_LED != NOT_A_PIN)
#ifdef LED_ACTIVE_LOW
digitalWrite(HAS_LED, LOW);
#else
digitalWrite(HAS_LED, HIGH);
#endif
#endif
#ifdef HAS_DISPLAY #ifdef HAS_DISPLAY
u8x8.begin(); u8x8.begin();
@ -84,42 +74,45 @@ void start_ota_update() {
WiFi.begin(WIFI_SSID, WIFI_PASS); WiFi.begin(WIFI_SSID, WIFI_PASS);
int i = WIFI_MAX_TRY; int i = WIFI_MAX_TRY, j = OTA_MAX_TRY;
while (i--) { while (i--) {
ESP_LOGI(TAG, "Trying to connect to %s", WIFI_SSID); ESP_LOGI(TAG, "Trying to connect to %s", WIFI_SSID);
if (WiFi.status() == WL_CONNECTED) if (WiFi.status() == WL_CONNECTED) {
break; // we now have wifi connection and try to do an OTA over wifi update
vTaskDelay(5000 / portTICK_PERIOD_MS); ESP_LOGI(TAG, "Connected to %s", WIFI_SSID);
display(1, "OK", "WiFi connected");
// do a number of tries limited by OTA_MAX_TRY
while (j--) {
ESP_LOGI(TAG,
"Starting OTA update, attempt %u of %u. This will take some "
"time to complete...",
OTA_MAX_TRY - j, OTA_MAX_TRY);
if (do_ota_update())
goto end;
}
} else {
vTaskDelay(5000 / portTICK_PERIOD_MS);
}
} }
if (i >= 0) { ESP_LOGI(TAG, "Could not connect to %s, rebooting.", WIFI_SSID);
ESP_LOGI(TAG, "Connected to %s", WIFI_SSID); display(1, " E", "no WiFi connect");
display(1, "OK", "WiFi connected");
do_ota_update(); // gets and flashes new firmware
} else {
ESP_LOGI(TAG, "Could not connect to %s, rebooting.", WIFI_SSID);
display(1, " E", "no WiFi connect");
}
end:
switch_LED(LED_OFF);
display(5, "**", ""); // mark line rebooting display(5, "**", ""); // mark line rebooting
// turn off LED
#if (HAS_LED != NOT_A_PIN)
#ifdef LED_ACTIVE_LOW
digitalWrite(HAS_LED, HIGH);
#else
digitalWrite(HAS_LED, LOW);
#endif
#endif
vTaskDelay(5000 / portTICK_PERIOD_MS); vTaskDelay(5000 / portTICK_PERIOD_MS);
ESP.restart(); ESP.restart();
} // start_ota_update } // start_ota_update
void do_ota_update() { bool do_ota_update() {
char buf[17]; char buf[17];
bool redirect = true;
size_t written = 0;
// Fetch the latest firmware version // Fetch the latest firmware version
ESP_LOGI(TAG, "Checking latest firmware version on server..."); ESP_LOGI(TAG, "Checking latest firmware version on server...");
@ -131,11 +124,11 @@ void do_ota_update() {
TAG, TAG,
"Could not load info about the latest firmware. Rebooting to runmode."); "Could not load info about the latest firmware. Rebooting to runmode.");
display(2, " E", "file not found"); display(2, " E", "file not found");
return; return false;
} else if (version_compare(latest, cfg.version) <= 0) { } else if (version_compare(latest, cfg.version) <= 0) {
ESP_LOGI(TAG, "Current firmware is up to date. Rebooting to runmode."); ESP_LOGI(TAG, "Current firmware is up to date. Rebooting to runmode.");
display(2, "NO", "no update found"); display(2, "NO", "no update found");
return; return false;
} }
ESP_LOGI(TAG, "New firmware version v%s available. Downloading...", ESP_LOGI(TAG, "New firmware version v%s available. Downloading...",
latest.c_str()); latest.c_str());
@ -146,7 +139,7 @@ void do_ota_update() {
if (!firmwarePath.endsWith(".bin")) { if (!firmwarePath.endsWith(".bin")) {
ESP_LOGI(TAG, "Unsupported binary format, OTA update cancelled."); ESP_LOGI(TAG, "Unsupported binary format, OTA update cancelled.");
display(3, " E", "file type error"); display(3, " E", "file type error");
return; return false;
} }
String currentHost = bintray.getStorageHost(); String currentHost = bintray.getStorageHost();
@ -158,10 +151,9 @@ void do_ota_update() {
if (!client.connect(currentHost.c_str(), port)) { if (!client.connect(currentHost.c_str(), port)) {
ESP_LOGI(TAG, "Cannot connect to %s", currentHost.c_str()); ESP_LOGI(TAG, "Cannot connect to %s", currentHost.c_str());
display(3, " E", "connection lost"); display(3, " E", "connection lost");
return; goto failure;
} }
bool redirect = true;
while (redirect) { while (redirect) {
if (currentHost != prevHost) { if (currentHost != prevHost) {
client.stop(); client.stop();
@ -170,7 +162,7 @@ void do_ota_update() {
ESP_LOGI(TAG, "Redirect detected, but cannot connect to %s", ESP_LOGI(TAG, "Redirect detected, but cannot connect to %s",
currentHost.c_str()); currentHost.c_str());
display(3, " E", "server error"); display(3, " E", "server error");
return; goto failure;
} }
} }
@ -186,8 +178,7 @@ void do_ota_update() {
if (millis() - timeout > RESPONSE_TIMEOUT_MS) { if (millis() - timeout > RESPONSE_TIMEOUT_MS) {
ESP_LOGI(TAG, "Client Timeout."); ESP_LOGI(TAG, "Client Timeout.");
display(3, " E", "client timeout"); display(3, " E", "client timeout");
client.stop(); goto failure;
return;
} }
} }
@ -243,79 +234,66 @@ void do_ota_update() {
} }
} }
} }
} } // while (redirect)
display(3, "OK", ""); // line download display(3, "OK", ""); // line download
// check whether we have everything for OTA update // check whether we have everything for OTA update
if (contentLength && isValidContentType) { if (!(contentLength && isValidContentType)) {
size_t written = 0;
if (Update.begin(contentLength)) {
#ifdef HAS_DISPLAY
// register callback function for showing progress while streaming data
Update.onProgress(&show_progress);
#endif
int i = FLASH_MAX_TRY;
while ((i--) && (written != contentLength)) {
ESP_LOGI(TAG,
"Starting OTA update, attempt %u of %u. This will take some "
"time to complete...",
FLASH_MAX_TRY - i, FLASH_MAX_TRY);
display(4, "**", "writing...");
written = Update.writeStream(client);
if (written == contentLength) {
ESP_LOGI(TAG, "Written %u bytes successfully", written);
snprintf(buf, 17, "%ukB Done!", (uint16_t)(written / 1024));
display(4, "OK", buf);
break;
} else {
ESP_LOGI(TAG,
"Written only %u of %u bytes, OTA update attempt cancelled.",
written, contentLength);
}
}
if (Update.end()) {
if (Update.isFinished()) {
ESP_LOGI(
TAG,
"OTA update completed. Rebooting to runmode with new version.");
client.stop();
return;
} else {
ESP_LOGI(TAG, "Something went wrong! OTA update hasn't been finished "
"properly.");
}
} else {
ESP_LOGI(TAG, "An error occurred. Error #: %d", Update.getError());
snprintf(buf, 17, "Error #: %d", Update.getError());
display(4, " E", buf);
}
} else {
ESP_LOGI(TAG, "There isn't enough space to start OTA update");
display(4, " E", "disk full");
client.flush();
}
} else {
ESP_LOGI(TAG, ESP_LOGI(TAG,
"There was no valid content in the response from the OTA server!"); "There was no valid content in the response from the OTA server!");
display(4, " E", "response error"); display(4, " E", "response error");
client.flush(); goto failure;
} }
if (!Update.begin(contentLength)) {
ESP_LOGI(TAG, "There isn't enough space to start OTA update");
display(4, " E", "disk full");
goto failure;
}
#ifdef HAS_DISPLAY
// register callback function for showing progress while streaming data
Update.onProgress(&show_progress);
#endif
display(4, "**", "writing...");
written = Update.writeStream(client);
if (written == contentLength) {
ESP_LOGI(TAG, "Written %u bytes successfully", written);
snprintf(buf, 17, "%ukB Done!", (uint16_t)(written / 1024));
display(4, "OK", buf);
} else {
ESP_LOGI(TAG, "Written only %u of %u bytes, OTA update attempt cancelled.",
written, contentLength);
}
if (Update.end()) {
goto finished;
} else {
ESP_LOGI(TAG, "An error occurred. Error #: %d", Update.getError());
snprintf(buf, 17, "Error #: %d", Update.getError());
display(4, " E", buf);
goto failure;
}
finished:
client.stop();
ESP_LOGI(TAG, "OTA update completed. Rebooting to runmode with new version.");
return true;
failure:
client.stop();
ESP_LOGI(TAG, ESP_LOGI(TAG,
"OTA update failed. Rebooting to runmode with current version."); "OTA update failed. Rebooting to runmode with current version.");
client.stop(); return false;
} // do_ota_update } // do_ota_update
void display(const uint8_t row, const std::string status, void display(const uint8_t row, const std::string status,
const std::string msg) { const std::string msg) {
#ifdef HAS_DISPLAY #ifdef HAS_DISPLAY
u8x8.setCursor(14, row); u8x8.setCursor(14, row);
u8x8.print((status.substr(0, 2)).c_str()); u8x8.print((status.substr(0, 2)).c_str());
@ -329,7 +307,7 @@ void display(const uint8_t row, const std::string status,
#ifdef HAS_DISPLAY #ifdef HAS_DISPLAY
// callback function to show download progress while streaming data // callback function to show download progress while streaming data
void show_progress (unsigned long current, unsigned long size) { void show_progress(unsigned long current, unsigned long size) {
char buf[17]; char buf[17];
snprintf(buf, 17, "%-9lu (%3lu%%)", current, current * 100 / size); snprintf(buf, 17, "%-9lu (%3lu%%)", current, current * 100 / size);
display(4, "**", buf); display(4, "**", buf);

View File

@ -68,8 +68,9 @@
// OTA settings // OTA settings
#define USE_OTA 1 // Comment out to disable OTA update #define USE_OTA 1 // Comment out to disable OTA update
#define WIFI_MAX_TRY 5 // maximum number of wifi connect attempts for OTA update [default = 20] #define WIFI_MAX_TRY 5 // maximum number of wifi connect attempts for OTA update [default = 20]
#define FLASH_MAX_TRY 3 // maximum number of attempts for writing update binary to flash [default = 3] #define OTA_MAX_TRY 3 // maximum number of attempts for OTA download and write to flash [default = 3]
#define OTA_MIN_BATT 3700 // minimum battery level vor OTA [millivolt] #define OTA_MIN_BATT 3700 // minimum battery level for OTA [millivolt]
#define RESPONSE_TIMEOUT_MS 30000 // firmware binary server connection timeout [milliseconds]
// LMIC settings // LMIC settings
// moved to src/lmic_config.h // moved to src/lmic_config.h

View File

@ -75,8 +75,8 @@ void PayloadConvert::addStatus(uint16_t voltage, uint64_t uptime, float cputemp,
buffer[cursor++] = (byte)(reset2); buffer[cursor++] = (byte)(reset2);
} }
#ifdef HAS_GPS
void PayloadConvert::addGPS(gpsStatus_t value) { void PayloadConvert::addGPS(gpsStatus_t value) {
#ifdef HAS_GPS
buffer[cursor++] = (byte)((value.latitude & 0xFF000000) >> 24); buffer[cursor++] = (byte)((value.latitude & 0xFF000000) >> 24);
buffer[cursor++] = (byte)((value.latitude & 0x00FF0000) >> 16); buffer[cursor++] = (byte)((value.latitude & 0x00FF0000) >> 16);
buffer[cursor++] = (byte)((value.latitude & 0x0000FF00) >> 8); buffer[cursor++] = (byte)((value.latitude & 0x0000FF00) >> 8);
@ -90,14 +90,17 @@ void PayloadConvert::addGPS(gpsStatus_t value) {
buffer[cursor++] = lowByte(value.hdop); buffer[cursor++] = lowByte(value.hdop);
buffer[cursor++] = highByte(value.altitude); buffer[cursor++] = highByte(value.altitude);
buffer[cursor++] = lowByte(value.altitude); buffer[cursor++] = lowByte(value.altitude);
#endif
} }
#endif
void PayloadConvert::addButton(uint8_t value) {
#ifdef HAS_BUTTON #ifdef HAS_BUTTON
void PayloadConvert::addButton(uint8_t value) { buffer[cursor++] = value; } buffer[cursor++] = value;
#endif #endif
}
/* ---------------- packed format with LoRa serialization Encoder ---------- */ /* ---------------- packed format with LoRa serialization Encoder ----------
*/
// derived from // derived from
// https://github.com/thesolarnomad/lora-serialization/blob/master/src/LoraEncoder.cpp // https://github.com/thesolarnomad/lora-serialization/blob/master/src/LoraEncoder.cpp
@ -138,18 +141,20 @@ void PayloadConvert::addStatus(uint16_t voltage, uint64_t uptime, float cputemp,
writeUint8(reset2); writeUint8(reset2);
} }
#ifdef HAS_GPS
void PayloadConvert::addGPS(gpsStatus_t value) { void PayloadConvert::addGPS(gpsStatus_t value) {
#ifdef HAS_GPS
writeLatLng(value.latitude, value.longitude); writeLatLng(value.latitude, value.longitude);
writeUint8(value.satellites); writeUint8(value.satellites);
writeUint16(value.hdop); writeUint16(value.hdop);
writeUint16(value.altitude); writeUint16(value.altitude);
#endif
} }
#endif
void PayloadConvert::addButton(uint8_t value) {
#ifdef HAS_BUTTON #ifdef HAS_BUTTON
void PayloadConvert::addButton(uint8_t value) { writeUint8(value); } writeUint8(value);
#endif #endif
}
void PayloadConvert::intToBytes(uint8_t pos, int32_t i, uint8_t byteSize) { void PayloadConvert::intToBytes(uint8_t pos, int32_t i, uint8_t byteSize) {
for (uint8_t x = 0; x < byteSize; x++) { for (uint8_t x = 0; x < byteSize; x++) {
@ -162,7 +167,7 @@ void PayloadConvert::writeUptime(uint64_t uptime) {
intToBytes(cursor, uptime, 8); intToBytes(cursor, uptime, 8);
} }
void PayloadConvert::writeVersion(char * version) { void PayloadConvert::writeVersion(char *version) {
memcpy(buffer + cursor, version, 10); memcpy(buffer + cursor, version, 10);
cursor += 10; cursor += 10;
} }
@ -273,8 +278,8 @@ void PayloadConvert::addStatus(uint16_t voltage, uint64_t uptime, float celsius,
buffer[cursor++] = lowByte(temp); buffer[cursor++] = lowByte(temp);
} }
#ifdef HAS_GPS
void PayloadConvert::addGPS(gpsStatus_t value) { void PayloadConvert::addGPS(gpsStatus_t value) {
#ifdef HAS_GPS
int32_t lat = value.latitude / 100; int32_t lat = value.latitude / 100;
int32_t lon = value.longitude / 100; int32_t lon = value.longitude / 100;
int32_t alt = value.altitude * 100; int32_t alt = value.altitude * 100;
@ -291,18 +296,18 @@ void PayloadConvert::addGPS(gpsStatus_t value) {
buffer[cursor++] = (byte)((alt & 0xFF0000) >> 16); buffer[cursor++] = (byte)((alt & 0xFF0000) >> 16);
buffer[cursor++] = (byte)((alt & 0x00FF00) >> 8); buffer[cursor++] = (byte)((alt & 0x00FF00) >> 8);
buffer[cursor++] = (byte)((alt & 0x0000FF)); buffer[cursor++] = (byte)((alt & 0x0000FF));
}
#endif #endif
}
#ifdef HAS_BUTTON
void PayloadConvert::addButton(uint8_t value) { void PayloadConvert::addButton(uint8_t value) {
#ifdef HAS_BUTTON
#if (PAYLOAD_ENCODER == 3) #if (PAYLOAD_ENCODER == 3)
buffer[cursor++] = LPP_BUTTON_CHANNEL; buffer[cursor++] = LPP_BUTTON_CHANNEL;
#endif #endif
buffer[cursor++] = LPP_DIGITAL_INPUT; buffer[cursor++] = LPP_DIGITAL_INPUT;
buffer[cursor++] = value; buffer[cursor++] = value;
}
#endif #endif
}
#else #else
#error "No valid payload converter defined" #error "No valid payload converter defined"