This commit is contained in:
Klaus K Wilting 2018-08-12 15:42:58 +02:00
parent 5099d25965
commit cc603d4ab8
15 changed files with 123 additions and 75 deletions

View File

@ -142,6 +142,7 @@ Hereafter described is the default *plain* format, which uses MSB bit numbering.
byte 3-10: Uptime [seconds]
bytes 11-14: CPU temperature [°C]
bytes 15-18: Free RAM [bytes]
bytes 19-20: Last reset reasons core 0 / core 1
**Port #3:** Device configuration query result

View File

@ -109,7 +109,7 @@ String BintrayClient::getLatestVersion() const
const size_t bufferSize = 1024;
if (jsonResult.length() > bufferSize)
{
Serial.println("Error: Could parse JSON. Input data is too big!");
ESP_LOGI(TAG, "Error: Could not parse JSON. Input data is too big!");
return version;
}
StaticJsonBuffer<bufferSize> jsonBuffer;
@ -118,7 +118,7 @@ String BintrayClient::getLatestVersion() const
// Check for errors in parsing
if (!root.success())
{
Serial.println("Error: Could not parse JSON!");
ESP_LOGI(TAG, "Error: Could not parse JSON!");
return version;
}
return root.get<String>("name");
@ -133,7 +133,7 @@ String BintrayClient::getBinaryPath(const String &version) const
const size_t bufferSize = 1024;
if (jsonResult.length() > bufferSize)
{
Serial.println("Error: Could parse JSON. Input data is too big!");
ESP_LOGI(TAG, "Error: Could parse JSON. Input data is too big!");
return path;
}
StaticJsonBuffer<bufferSize> jsonBuffer;
@ -142,7 +142,7 @@ String BintrayClient::getBinaryPath(const String &version) const
JsonObject &firstItem = root[0];
if (!root.success())
{ //Check for errors in parsing
Serial.println("Error: Could not parse JSON!");
ESP_LOGI(TAG, "Error: Could not parse JSON!");
return path;
}
return "/" + getUser() + "/" + getRepository() + "/" + firstItem.get<String>("path");

View File

@ -56,25 +56,7 @@ build_flags =
'-DBINTRAY_REPO="${bintray.repository}"'
'-DBINTRAY_PACKAGE="${bintray.package}"'
'-DVERSION=0'
; extra dependencies
lib_deps = ArduinoJson
[common_env_data]
platform_espressif32 = espressif32@1.2.0
;platform_espressif32 = https://github.com/platformio/platform-espressif32.git#feature/stage
;board_build.partitions = no_ota.csv
board_build.partitions = min_spiffs.csv
lib_deps_all =
lib_deps_display =
U8g2@>=2.23.12
lib_deps_rgbled =
SmartLeds@>=1.1.3
lib_deps_gps =
TinyGPSPlus@>=1.0.2
Time@>=1.5
build_flags =
;
; ---> NOTE: For production run set DEBUG_LEVEL level to NONE! <---
; otherwise device may leak RAM
;
@ -90,7 +72,22 @@ build_flags =
; -DCORE_DEBUG_LEVEL=4
; Verbose
; -DCORE_DEBUG_LEVEL=5
;
[common_env_data]
platform_espressif32 = espressif32@1.2.0
;platform_espressif32 = https://github.com/platformio/platform-espressif32.git#feature/stage
;board_build.partitions = no_ota.csv
board_build.partitions = min_spiffs.csv
lib_deps_all =
ArduinoJson
lib_deps_display =
U8g2@>=2.23.12
lib_deps_rgbled =
SmartLeds@>=1.1.3
lib_deps_gps =
TinyGPSPlus@>=1.0.2
Time@>=1.5
build_flags =
; override lora settings from LMiC library in lmic/config.h and use main.h instead
-D_lmic_config_h_
-include "src/paxcounter.conf"

30
src/OTA.cpp Normal file
View File

@ -0,0 +1,30 @@
#include "OTA.h"
const BintrayClient bintray(BINTRAY_USER, BINTRAY_REPO, BINTRAY_PACKAGE);
void ota_wifi_init(void) {
const int RESPONSE_TIMEOUT_MS = 5000;
unsigned long timeout = millis();
ESP_ERROR_CHECK(esp_wifi_set_promiscuous(false)); // switch off monitor mode
tcpip_adapter_init();
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_start());
WiFi.begin(WIFI_SSID, WIFI_PASS);
WiFi.setHostname(PROGNAME);
/*
while (WiFi.status() != WL_CONNECTED) {
ESP_LOGI(TAG, "WiFi Status %d", WiFi.status());
if (millis() - timeout > RESPONSE_TIMEOUT_MS) {
ESP_LOGE(TAG, "WiFi connection timeout. Please check your settings!");
}
delay(500);
}
configASSERT(WiFi.isConnected() == true);
*/
}

11
src/OTA.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef OTA_H
#define OTA_H
#include <Arduino.h>
#include "globals.h"
#include <BintrayClient.h>
#include <WiFi.h>
void ota_wifi_init(void);
#endif // OTA_H

View File

@ -37,16 +37,16 @@ void checkFirmwareUpdates()
const String latest = bintray.getLatestVersion();
if (latest.length() == 0)
{
Serial.println("Could not load info about the latest firmware, so nothing to update. Continue ...");
ESP_LOGI(TAG, "Could not load info about the latest firmware, so nothing to update. Continue ...");
return;
}
else if (atoi(latest.c_str()) <= VERSION)
{
//Serial.println("The current firmware is up to date. Continue ...");
//ESP_LOGI(TAG, "The current firmware is up to date. Continue ...");
return;
}
Serial.println("There is a new version of firmware available: v." + latest);
ESP_LOGI(TAG, "There is a new version of firmware available: v.%s", latest);
processOTAUpdate(latest);
}
@ -64,7 +64,7 @@ void processOTAUpdate(const String &version)
String firmwarePath = bintray.getBinaryPath(version);
if (!firmwarePath.endsWith(".bin"))
{
Serial.println("Unsupported binary format. OTA update cannot be performed!");
ESP_LOGI(TAG, "Unsupported binary format. OTA update cannot be performed!");
return;
}
@ -76,7 +76,7 @@ void processOTAUpdate(const String &version)
if (!client.connect(currentHost.c_str(), port))
{
Serial.println("Cannot connect to " + currentHost);
ESP_LOGI(TAG, "Cannot connect to %s", currentHost);
return;
}
@ -89,12 +89,12 @@ void processOTAUpdate(const String &version)
client.setCACert(bintray.getCertificate(currentHost));
if (!client.connect(currentHost.c_str(), port))
{
Serial.println("Redirect detected! Cannot connect to " + currentHost + " for some reason!");
ESP_LOGI(TAG, "Redirect detected! Cannot connect to %s for some reason!", currentHost);
return;
}
}
//Serial.println("Requesting: " + firmwarePath);
//ESP_LOGI(TAG, "Requesting: " + firmwarePath);
client.print(String("GET ") + firmwarePath + " HTTP/1.1\r\n");
client.print(String("Host: ") + currentHost + "\r\n");
@ -106,7 +106,7 @@ void processOTAUpdate(const String &version)
{
if (millis() - timeout > RESPONSE_TIMEOUT_MS)
{
Serial.println("Client Timeout !");
ESP_LOGI(TAG, "Client Timeout !");
client.stop();
return;
}
@ -128,17 +128,17 @@ void processOTAUpdate(const String &version)
{
if (line.indexOf("200") > 0)
{
//Serial.println("Got 200 status code from server. Proceeding to firmware flashing");
ESP_LOGI(TAG, "Got 200 status code from server. Proceeding to firmware flashing");
redirect = false;
}
else if (line.indexOf("302") > 0)
{
//Serial.println("Got 302 status code from server. Redirecting to the new address");
ESP_LOGI(TAG, "Got 302 status code from server. Redirecting to the new address");
redirect = true;
}
else
{
//Serial.println("Could not get a valid firmware url");
ESP_LOGI(TAG, "Could not get a valid firmware url");
//Unexptected HTTP response. Retry or skip update?
redirect = false;
}
@ -148,12 +148,12 @@ void processOTAUpdate(const String &version)
if (line.startsWith("Location: "))
{
String newUrl = getHeaderValue(line, "Location: ");
//Serial.println("Got new url: " + newUrl);
ESP_LOGI(TAG, "Got new url: %s", newUrl);
newUrl.remove(0, newUrl.indexOf("//") + 2);
currentHost = newUrl.substring(0, newUrl.indexOf('/'));
newUrl.remove(newUrl.indexOf(currentHost), currentHost.length());
firmwarePath = newUrl;
//Serial.println("firmwarePath: " + firmwarePath);
ESP_LOGI(TAG, "firmwarePath: %s", firmwarePath);
continue;
}
@ -161,13 +161,13 @@ void processOTAUpdate(const String &version)
if (line.startsWith("Content-Length: "))
{
contentLength = atoi((getHeaderValue(line, "Content-Length: ")).c_str());
Serial.println("Got " + String(contentLength) + " bytes from server");
ESP_LOGI(TAG, "Got %s bytes from server", String(contentLength));
}
if (line.startsWith("Content-Type: "))
{
String contentType = getHeaderValue(line, "Content-Type: ");
//Serial.println("Got " + contentType + " payload.");
ESP_LOGI(TAG, "Got %s payload", contentType);
if (contentType == "application/octet-stream")
{
isValidContentType = true;
@ -181,16 +181,16 @@ void processOTAUpdate(const String &version)
{
if (Update.begin(contentLength))
{
Serial.println("Starting Over-The-Air update. This may take some time to complete ...");
ESP_LOGI(TAG, "Starting Over-The-Air update. This may take some time to complete ...");
size_t written = Update.writeStream(client);
if (written == contentLength)
{
Serial.println("Written : " + String(written) + " successfully");
ESP_LOGI(TAG, "Written %s successfully", String(written));
}
else
{
Serial.println("Written only : " + String(written) + "/" + String(contentLength) + ". Retry?");
ESP_LOGI(TAG, "Written only %s / %s Retry?", String(written), String(contentLength));
// Retry??
}
@ -198,28 +198,28 @@ void processOTAUpdate(const String &version)
{
if (Update.isFinished())
{
Serial.println("OTA update has successfully completed. Rebooting ...");
ESP_LOGI(TAG, "OTA update has successfully completed. Rebooting ...");
ESP.restart();
}
else
{
Serial.println("Something went wrong! OTA update hasn't been finished properly.");
ESP_LOGI(TAG, "Something went wrong! OTA update hasn't been finished properly.");
}
}
else
{
Serial.println("An error Occurred. Error #: " + String(Update.getError()));
ESP_LOGI(TAG, "An error occurred. Error #: %s", String(Update.getError()));
}
}
else
{
Serial.println("There isn't enough space to start OTA update");
ESP_LOGI(TAG, "There isn't enough space to start OTA update");
client.flush();
}
}
else
{
Serial.println("There was no valid content in the response from the OTA server!");
ESP_LOGI(TAG, "There was no valid content in the response from the OTA server!");
client.flush();
}
}

View File

@ -18,7 +18,7 @@ function Decoder(bytes, port) {
if (port === 2) {
// device status data
return decode(bytes, [uint16, uptime, temperature, uint32], ['voltage', 'uptime', 'cputemp', 'memory']);
return decode(bytes, [uint16, uptime, temperature, uint32, uint8, uint8], ['voltage', 'uptime', 'cputemp', 'memory', 'reset', 'reset']);
}
@ -181,6 +181,7 @@ if (typeof module === 'object' && typeof module.exports !== 'undefined') {
uint16: uint16,
uint32: uint32,
uptime: uptime,
reset: reset,
temperature: temperature,
humidity: humidity,
latLng: latLng,

View File

@ -51,7 +51,7 @@ extern hw_timer_t *channelSwitch, *sendCycle;
extern portMUX_TYPE timerMux;
extern volatile int SendCycleTimerIRQ, HomeCycleIRQ, DisplayTimerIRQ,
ChannelTimerIRQ, ButtonPressedIRQ;
extern QueueHandle_t LoraSendQueue, SPISendQueue;
//extern QueueHandle_t LoraSendQueue, SPISendQueue;
extern TaskHandle_t WifiLoopTask;
extern std::array<uint64_t, 0xff>::iterator it;
@ -68,9 +68,15 @@ extern std::array<uint64_t, 0xff> beacons;
#include "payload.h"
#ifdef HAS_LORA
extern QueueHandle_t LoraSendQueue;
extern TaskHandle_t LoraTask;
#include "lorawan.h"
#endif
#ifdef HAS_SPI
extern QueueHandle_t SPISendQueue;
#endif
#ifdef HAS_DISPLAY
#include "display.h"
#endif

View File

@ -46,6 +46,7 @@ TaskHandle_t WifiLoopTask = NULL;
// RTos send queues for payload transmit
#ifdef HAS_LORA
QueueHandle_t LoraSendQueue;
TaskHandle_t LoraTask = NULL;
#endif
#ifdef HAS_SPI
@ -271,7 +272,7 @@ void setup() {
ESP_LOGI(TAG, "Starting Lora task on core 1");
xTaskCreatePinnedToCore(lorawan_loop, "loraloop", 2048, (void *)1,
(5 | portPRIVILEGE_BIT), NULL, 1);
(5 | portPRIVILEGE_BIT), &LoraTask, 1);
#endif
// if device has GPS and it is enabled, start GPS reader task on core 0 with
@ -332,6 +333,8 @@ void loop() {
processSendBuffer();
// check send cycle and enqueue payload if cycle is expired
sendPayload();
// reset watchdog
vTaskDelay(1 / portTICK_PERIOD_MS);
} // loop()
}

View File

@ -9,7 +9,7 @@
// Payload send cycle and encoding
#define SEND_SECS 30 // payload send cycle [seconds/2] -> 60 sec.
#define PAYLOAD_ENCODER 1 // payload encoder: 1=Plain, 2=Packed, 3=CayenneLPP dynamic, 4=CayenneLPP packed
#define PAYLOAD_ENCODER 2 // payload encoder: 1=Plain, 2=Packed, 3=CayenneLPP dynamic, 4=CayenneLPP packed
// Set this to include BLE counting and vendor filter functions
#define VENDORFILTER 1 // comment out if you want to count things, not people

View File

@ -52,8 +52,8 @@ void PayloadConvert::addConfig(configData_t value) {
cursor += 10;
}
void PayloadConvert::addStatus(uint16_t voltage, uint64_t uptime,
float cputemp, uint32_t mem) {
void PayloadConvert::addStatus(uint16_t voltage, uint64_t uptime, float cputemp,
uint32_t mem, uint8_t reset1, uint8_t reset2) {
uint32_t temp = (uint32_t)cputemp;
buffer[cursor++] = highByte(voltage);
buffer[cursor++] = lowByte(voltage);
@ -73,6 +73,8 @@ void PayloadConvert::addStatus(uint16_t voltage, uint64_t uptime,
buffer[cursor++] = (byte)((mem & 0x00FF0000) >> 16);
buffer[cursor++] = (byte)((mem & 0x0000FF00) >> 8);
buffer[cursor++] = (byte)((mem & 0x000000FF));
buffer[cursor++] = (byte)(reset1);
buffer[cursor++] = (byte)(reset2);
}
#ifdef HAS_GPS
@ -127,12 +129,14 @@ void PayloadConvert::addConfig(configData_t value) {
value.vendorfilter ? true : false, value.gpsmode ? true : false);
}
void PayloadConvert::addStatus(uint16_t voltage, uint64_t uptime,
float cputemp, uint32_t mem) {
void PayloadConvert::addStatus(uint16_t voltage, uint64_t uptime, float cputemp,
uint32_t mem, uint8_t reset1, uint8_t reset2) {
writeUint16(voltage);
writeUptime(uptime);
writeTemperature(cputemp);
writeUint32(mem);
writeUint8(reset1);
writeUint8(reset2);
}
#ifdef HAS_GPS
@ -245,8 +249,8 @@ void PayloadConvert::addConfig(configData_t value) {
buffer[cursor++] = value.adrmode;
}
void PayloadConvert::addStatus(uint16_t voltage, uint64_t uptime,
float celsius, uint32_t mem) {
void PayloadConvert::addStatus(uint16_t voltage, uint64_t uptime, float celsius,
uint32_t mem, uint8_t reset1, uint8_t reset2) {
uint16_t temp = celsius * 10;
uint16_t volt = voltage / 10;
#ifdef HAS_BATTERY_PROBE

View File

@ -35,7 +35,8 @@ public:
uint8_t *getBuffer(void);
void addCount(uint16_t value1, uint16_t value2);
void addConfig(configData_t value);
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);
void addAlarm(int8_t rssi, uint8_t message);
#ifdef HAS_GPS
void addGPS(gpsStatus_t value);
@ -44,7 +45,6 @@ public:
void addButton(uint8_t value);
#endif
#if PAYLOAD_ENCODER == 1 // format plain
private:
@ -77,7 +77,6 @@ private:
#else
#error "No valid payload converter defined"
#endif
};
extern PayloadConvert payload;

View File

@ -203,7 +203,8 @@ void get_status(uint8_t val[]) {
#endif
payload.reset();
payload.addStatus(voltage, uptime() / 1000, temperatureRead(),
ESP.getFreeHeap());
ESP.getFreeHeap(), rtc_get_reset_reason(0),
rtc_get_reset_reason(1));
SendData(STATUSPORT);
};
@ -225,21 +226,13 @@ void set_update(uint8_t val[]) {
ESP_LOGI(TAG, "Stopping Wifi task on core 0");
vTaskDelete(WifiLoopTask);
ESP_LOGI(TAG, "Stopping LORA task on core 1");
vTaskDelete(LoraTask);
ESP_LOGI(TAG, "Connecting to %s", WIFI_SSID);
ESP_ERROR_CHECK(esp_wifi_set_promiscuous(false)); // switch off monitor mode
//tcpipInit();
tcpip_adapter_init();
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
ESP_LOGI(TAG, ".");
delay(500);
}
ESP_LOGI(TAG, "connected!");
ota_wifi_init();
checkFirmwareUpdates();
};
// assign previously defined functions to set of numeric remote commands

View File

@ -5,6 +5,8 @@
#include "configmanager.h"
#include "lorawan.h"
#include "macsniff.h"
#include <rom/rtc.h>
#include "ota.h"
#include <WiFi.h>
#include "SecureOTA.h"

View File

@ -36,6 +36,7 @@ void wifi_sniffer_init(void) {
ESP_ERROR_CHECK(
esp_wifi_set_storage(WIFI_STORAGE_RAM)); // we don't need NVRAM
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_NULL));
ESP_ERROR_CHECK(esp_wifi_stop());
ESP_ERROR_CHECK(
esp_wifi_set_promiscuous_filter(&filter)); // set MAC frame filter
ESP_ERROR_CHECK(esp_wifi_set_promiscuous_rx_cb(&wifi_sniffer_packet_handler));