mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-30 13:41:53 +00:00
Compare commits
39 Commits
v1.3.6.f51
...
v1.3.8.90d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
90df7c2488 | ||
|
|
8c1a81c03a | ||
|
|
6fe9f0b42f | ||
|
|
43f6f61472 | ||
|
|
ed62b6916c | ||
|
|
cf45e4fce5 | ||
|
|
136e2e96f7 | ||
|
|
7c071e2361 | ||
|
|
0b85e97087 | ||
|
|
81d1cc1003 | ||
|
|
748416d9e3 | ||
|
|
da6d49385c | ||
|
|
f279f9614e | ||
|
|
9097475149 | ||
|
|
5327d6162a | ||
|
|
5d7990667d | ||
|
|
79a41bd81c | ||
|
|
6a3d81eff8 | ||
|
|
7cd66b2b68 | ||
|
|
8124ecbfd8 | ||
|
|
7df1a64b52 | ||
|
|
e51b7c3c32 | ||
|
|
0c285aac6e | ||
|
|
fbeb554186 | ||
|
|
87da779478 | ||
|
|
1082c5d771 | ||
|
|
3933d24d62 | ||
|
|
fc0508f254 | ||
|
|
bb22b6ec58 | ||
|
|
ddb9678377 | ||
|
|
dc20cbb672 | ||
|
|
a10ea604af | ||
|
|
fb1caa51d0 | ||
|
|
7e977aea00 | ||
|
|
ecc114f1cd | ||
|
|
b76424db50 | ||
|
|
b056081d3c | ||
|
|
a4bdef4151 | ||
|
|
478274aff1 |
@@ -17,3 +17,7 @@ Manual Method
|
||||
[For nRF52 devices click here](https://meshtastic.org/docs/getting-started/flashing-nrf52)
|
||||
|
||||
For developer information and specific building instructions, please see the [developer documentation](https://meshtastic.org/docs/developers)
|
||||
|
||||
## Stats
|
||||
|
||||

|
||||
|
||||
@@ -102,7 +102,6 @@ lib_deps =
|
||||
${environmental.lib_deps}
|
||||
https://github.com/meshtastic/esp32_https_server.git
|
||||
h2zero/NimBLE-Arduino@1.3.7
|
||||
tobozo/ESP32-targz@^1.1.4
|
||||
arduino-libraries/NTPClient@^3.1.0
|
||||
lorol/LittleFS_esp32@^1.0.6
|
||||
lib_ignore =
|
||||
@@ -110,11 +109,15 @@ lib_ignore =
|
||||
ESP32 BLE Arduino
|
||||
platform_packages =
|
||||
framework-arduinoespressif32@https://github.com/meshtastic/arduino-esp32.git#4cde0f5d412d2695184f32e8a47e9bea57b45276
|
||||
; leave this commented out to avoid breaking Windows
|
||||
|
||||
; leave this commented out to avoid breaking Windows
|
||||
;upload_port = /dev/ttyUSB0
|
||||
;monitor_port = /dev/ttyUSB0
|
||||
|
||||
; Please don't delete these lines. JM uses them.
|
||||
;upload_port = /dev/cu.SLAB_USBtoUART
|
||||
;monitor_port = /dev/cu.SLAB_USBtoUART
|
||||
|
||||
; customize the partition table
|
||||
; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables
|
||||
board_build.partitions = partition-table.csv
|
||||
|
||||
2
proto
2
proto
Submodule proto updated: 870a62b27e...8bac81b631
@@ -11,13 +11,13 @@ template <class T> class Observable;
|
||||
*/
|
||||
template <class T> class Observer
|
||||
{
|
||||
Observable<T> *observed = NULL;
|
||||
std::list<Observable<T> *> observed;
|
||||
|
||||
public:
|
||||
virtual ~Observer();
|
||||
|
||||
/// Stop watching our current obserable
|
||||
void unobserve();
|
||||
/// Stop watching the obserable
|
||||
void unobserve(Observable<T> *o);
|
||||
|
||||
/// Start watching a specified observable
|
||||
void observe(Observable<T> *o);
|
||||
@@ -87,21 +87,21 @@ template <class T> class Observable
|
||||
|
||||
template <class T> Observer<T>::~Observer()
|
||||
{
|
||||
unobserve();
|
||||
for (typename std::list<Observable<T> *>::const_iterator iterator = observed.begin(); iterator != observed.end();
|
||||
++iterator) {
|
||||
(*iterator)->removeObserver(this);
|
||||
}
|
||||
observed.clear();
|
||||
}
|
||||
|
||||
template <class T> void Observer<T>::unobserve()
|
||||
template <class T> void Observer<T>::unobserve(Observable<T> *o)
|
||||
{
|
||||
if (observed)
|
||||
observed->removeObserver(this);
|
||||
observed = NULL;
|
||||
o->removeObserver(this);
|
||||
observed.remove(o);
|
||||
}
|
||||
|
||||
template <class T> void Observer<T>::observe(Observable<T> *o)
|
||||
{
|
||||
// We can only watch one thing at a time
|
||||
assert(!observed);
|
||||
|
||||
observed = o;
|
||||
observed.push_back(o);
|
||||
o->addObserver(this);
|
||||
}
|
||||
|
||||
@@ -125,6 +125,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define RTC_DATA_ATTR
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Feature toggles
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Disable use of the NTP library and related features
|
||||
//#define DISABLE_NTP
|
||||
|
||||
// Disable the welcome screen and allow
|
||||
// #define DISABLE_WELCOME_UNSET
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// OLED & Input
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@@ -6,21 +6,28 @@
|
||||
uint8_t oled_probe(byte addr)
|
||||
{
|
||||
uint8_t r = 0;
|
||||
uint8_t r_prev = 0;
|
||||
uint8_t c = 0;
|
||||
uint8_t o_probe = 0;
|
||||
Wire.beginTransmission(addr);
|
||||
Wire.write(0x00);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom((int)addr, 1);
|
||||
if (Wire.available()) {
|
||||
r = Wire.read();
|
||||
}
|
||||
r &= 0x0f;
|
||||
if (r == 0x08 || r == 0x00) {
|
||||
o_probe = 2; // SH1106
|
||||
} else if ( r == 0x03 || r == 0x06 || r == 0x07) {
|
||||
o_probe = 1; // SSD1306
|
||||
}
|
||||
DEBUG_MSG("0x%x subtype probed\n", r);
|
||||
do {
|
||||
r_prev = r;
|
||||
Wire.beginTransmission(addr);
|
||||
Wire.write(0x00);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom((int)addr, 1);
|
||||
if (Wire.available()) {
|
||||
r = Wire.read();
|
||||
}
|
||||
r &= 0x0f;
|
||||
|
||||
if (r == 0x08 || r == 0x00) {
|
||||
o_probe = 2; // SH1106
|
||||
} else if ( r == 0x03 || r == 0x06 || r == 0x07) {
|
||||
o_probe = 1; // SSD1306
|
||||
}
|
||||
c++;
|
||||
} while ((r != r_prev) && (c < 4));
|
||||
DEBUG_MSG("0x%x subtype probed in %i tries \n", r, c);
|
||||
return o_probe;
|
||||
}
|
||||
|
||||
|
||||
@@ -95,8 +95,8 @@ bool GPS::setup()
|
||||
GPS::~GPS()
|
||||
{
|
||||
// we really should unregister our sleep observer
|
||||
notifySleepObserver.unobserve();
|
||||
notifyDeepSleepObserver.unobserve();
|
||||
notifySleepObserver.unobserve(¬ifySleep);
|
||||
notifyDeepSleepObserver.unobserve(¬ifyDeepSleep);
|
||||
}
|
||||
|
||||
bool GPS::hasLock() { return hasValidLocation; }
|
||||
|
||||
@@ -31,6 +31,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "graphics/images.h"
|
||||
#include "main.h"
|
||||
#include "mesh-pb-constants.h"
|
||||
#include "mesh/generated/deviceonly.pb.h"
|
||||
#include "mesh/Channels.h"
|
||||
#include "modules/TextMessageModule.h"
|
||||
#include "sleep.h"
|
||||
@@ -44,6 +45,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using namespace meshtastic; /** @todo remove */
|
||||
|
||||
extern bool loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, void *dest_struct);
|
||||
|
||||
namespace graphics
|
||||
{
|
||||
|
||||
@@ -77,6 +80,10 @@ static char ourId[5];
|
||||
// GeoCoord object for the screen
|
||||
GeoCoord geoCoord;
|
||||
|
||||
// OEM Config File
|
||||
static const char *oemConfigFile = "/prefs/oem.proto";
|
||||
OEMStore oemStore;
|
||||
|
||||
#ifdef SHOW_REDRAWS
|
||||
static bool heartbeat = false;
|
||||
#endif
|
||||
@@ -148,6 +155,54 @@ static void drawBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int1
|
||||
drawIconScreen(region, display, state, x, y);
|
||||
}
|
||||
|
||||
static void drawOEMIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||
{
|
||||
// draw an xbm image.
|
||||
// Please note that everything that should be transitioned
|
||||
// needs to be drawn relative to x and y
|
||||
|
||||
// draw centered icon left to right and centered above the one line of app text
|
||||
display->drawXbm(x + (SCREEN_WIDTH - oemStore.oem_icon_width) / 2, y + (SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM - oemStore.oem_icon_height) / 2 + 2,
|
||||
oemStore.oem_icon_width, oemStore.oem_icon_height, (const uint8_t *)oemStore.oem_icon_bits.bytes);
|
||||
|
||||
switch(oemStore.oem_font){
|
||||
case 0:
|
||||
display->setFont(FONT_SMALL);
|
||||
break;
|
||||
case 2:
|
||||
display->setFont(FONT_LARGE);
|
||||
break;
|
||||
default:
|
||||
display->setFont(FONT_MEDIUM);
|
||||
break;
|
||||
}
|
||||
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
const char *title = oemStore.oem_text;
|
||||
display->drawString(x + getStringCenteredX(title), y + SCREEN_HEIGHT - FONT_HEIGHT_MEDIUM, title);
|
||||
display->setFont(FONT_SMALL);
|
||||
|
||||
// Draw region in upper left
|
||||
if (upperMsg)
|
||||
display->drawString(x + 0, y + 0, upperMsg);
|
||||
|
||||
// Draw version in upper right
|
||||
char buf[16];
|
||||
snprintf(buf, sizeof(buf), "%s",
|
||||
xstr(APP_VERSION_SHORT)); // Note: we don't bother printing region or now, it makes the string too long
|
||||
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(buf), y + 0, buf);
|
||||
screen->forceDisplay();
|
||||
|
||||
// FIXME - draw serial # somewhere?
|
||||
}
|
||||
|
||||
static void drawOEMBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||
{
|
||||
// Draw region in upper left
|
||||
const char *region = myRegion ? myRegion->name : NULL;
|
||||
drawOEMIconScreen(region, display, state, x, y);
|
||||
}
|
||||
|
||||
// Used on boot when a certificate is being created
|
||||
static void drawSSLScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||
{
|
||||
@@ -172,22 +227,34 @@ static void drawSSLScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
||||
static void drawWelcomeScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||
{
|
||||
|
||||
display->setFont(FONT_SMALL);
|
||||
if ((millis() / 10000) % 2) {
|
||||
display->setFont(FONT_SMALL);
|
||||
|
||||
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
||||
display->drawString(64 + x, y, "Meshtastic :)");
|
||||
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
||||
display->drawString(64 + x, y, "//\\ E S H T /\\ S T / C");
|
||||
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 2 - 3, "Set the region using the");
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 3 - 3, "Meshtastic Android, iOS,");
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 4 - 3, "Flasher or CLI client.");
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 2 - 3, "Set the region using the");
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 3 - 3, "Meshtastic Android, iOS,");
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 4 - 3, "Flasher or CLI client.");
|
||||
} else {
|
||||
display->setFont(FONT_SMALL);
|
||||
|
||||
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
||||
display->drawString(64 + x, y, "//\\ E S H T /\\ S T / C");
|
||||
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 2 - 3, "Visit meshtastic.org");
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 3 - 3, "for more information.");
|
||||
display->drawString(x, y + FONT_HEIGHT_SMALL * 4 - 3, "");
|
||||
}
|
||||
|
||||
#ifndef NO_ESP32
|
||||
yield();
|
||||
esp_task_wdt_reset();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#ifdef HAS_EINK
|
||||
@@ -801,8 +868,8 @@ void Screen::setup()
|
||||
dispdev.setDetected(screen_model);
|
||||
#endif
|
||||
|
||||
// I think this is not needed - redundant with ui.init
|
||||
// dispdev.resetOrientation();
|
||||
// Load OEM config from Proto file if existent
|
||||
loadProto(oemConfigFile, OEMStore_size, sizeof(oemConfigFile), OEMStore_fields, &oemStore);
|
||||
|
||||
// Initialising the UI will init the display too.
|
||||
ui.init();
|
||||
@@ -855,6 +922,7 @@ void Screen::setup()
|
||||
// twice initially.
|
||||
ui.update();
|
||||
ui.update();
|
||||
serialSinceMsec = millis();
|
||||
|
||||
// Subscribe to status updates
|
||||
powerStatusObserver.observe(&powerStatus->onNewStatus);
|
||||
@@ -885,7 +953,7 @@ int32_t Screen::runOnce()
|
||||
return RUN_SAME;
|
||||
}
|
||||
|
||||
// Show boot screen for first 3 seconds, then switch to normal operation.
|
||||
// Show boot screen for first 5 seconds, then switch to normal operation.
|
||||
// serialSinceMsec adjusts for additional serial wait time during nRF52 bootup
|
||||
static bool showingBootScreen = true;
|
||||
if (showingBootScreen && (millis() > (5000 + serialSinceMsec))) {
|
||||
@@ -894,9 +962,26 @@ int32_t Screen::runOnce()
|
||||
showingBootScreen = false;
|
||||
}
|
||||
|
||||
if (radioConfig.preferences.region == RegionCode_Unset) {
|
||||
// If we have an OEM Boot screen, toggle after 2,5 seconds
|
||||
if(strlen(oemStore.oem_text) > 0){
|
||||
static bool showingOEMBootScreen = true;
|
||||
if (showingOEMBootScreen && (millis() > (2500 + serialSinceMsec))) {
|
||||
DEBUG_MSG("Switch to OEM screen...\n");
|
||||
// Change frames.
|
||||
static FrameCallback bootOEMFrames[] = {drawOEMBootScreen};
|
||||
static const int bootOEMFrameCount = sizeof(bootOEMFrames) / sizeof(bootOEMFrames[0]);
|
||||
ui.setFrames(bootOEMFrames, bootOEMFrameCount);
|
||||
ui.update();
|
||||
ui.update();
|
||||
showingOEMBootScreen = false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef DISABLE_WELCOME_UNSET
|
||||
if (showingNormalScreen && radioConfig.preferences.region == RegionCode_Unset) {
|
||||
setWelcomeFrames();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Process incoming commands.
|
||||
for (;;) {
|
||||
|
||||
@@ -276,11 +276,9 @@ void NodeDB::pickNewNodeNum()
|
||||
myNodeInfo.my_node_num = r;
|
||||
}
|
||||
|
||||
static const char *preffileOld = "/db.proto";
|
||||
static const char *preffile = "/prefs/db.proto";
|
||||
static const char *radiofile = "/prefs/radio.proto";
|
||||
static const char *channelfile = "/prefs/channels.proto";
|
||||
// const char *preftmp = "/db.proto.tmp";
|
||||
|
||||
/** Load a protobuf from a file, return true for success */
|
||||
bool loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, void *dest_struct)
|
||||
@@ -290,13 +288,6 @@ bool loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_
|
||||
|
||||
auto f = FSCom.open(filename);
|
||||
|
||||
// FIXME, temporary hack until every node in the universe is 1.2 or later - look for prefs in the old location (so we can
|
||||
// preserve region)
|
||||
if (!f && filename == preffile) {
|
||||
filename = preffileOld;
|
||||
f = FSCom.open(filename);
|
||||
}
|
||||
|
||||
bool okay = false;
|
||||
if (f) {
|
||||
DEBUG_MSG("Loading %s\n", filename);
|
||||
@@ -399,8 +390,6 @@ void NodeDB::saveToDisk()
|
||||
saveProto(radiofile, RadioConfig_size, sizeof(RadioConfig), RadioConfig_fields, &radioConfig);
|
||||
saveChannelsToDisk();
|
||||
|
||||
// remove any pre 1.2 pref files, turn on after 1.2 is in beta
|
||||
// if(okay) FSCom.remove(preffileOld);
|
||||
} else {
|
||||
DEBUG_MSG("***** DEVELOPMENT MODE - DO NOT RELEASE - not saving to flash *****\n");
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ void PhoneAPI::close()
|
||||
if (state != STATE_SEND_NOTHING) {
|
||||
state = STATE_SEND_NOTHING;
|
||||
|
||||
unobserve();
|
||||
unobserve(&service.fromNumChanged);
|
||||
releasePhonePacket(); // Don't leak phone packets on shutdown
|
||||
|
||||
onConnectionChanged(false);
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
#include "configuration.h"
|
||||
#include "Router.h"
|
||||
#include "Channels.h"
|
||||
#include "CryptoEngine.h"
|
||||
#include "NodeDB.h"
|
||||
#include "RTC.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
#include "mesh-pb-constants.h"
|
||||
#include "modules/RoutingModule.h"
|
||||
extern "C" {
|
||||
#include "mesh/compression/unishox2.h"
|
||||
}
|
||||
|
||||
#if defined(HAS_WIFI) || defined(PORTDUINO)
|
||||
#include "mqtt/MQTT.h"
|
||||
@@ -210,29 +213,27 @@ ErrorCode Router::send(MeshPacket *p)
|
||||
if (p->which_payloadVariant == MeshPacket_decoded_tag) {
|
||||
ChannelIndex chIndex = p->channel; // keep as a local because we are about to change it
|
||||
|
||||
|
||||
|
||||
#if defined(HAS_WIFI) || defined(PORTDUINO)
|
||||
//check if we should send decrypted packets to mqtt
|
||||
// check if we should send decrypted packets to mqtt
|
||||
|
||||
//truth table:
|
||||
// truth table:
|
||||
/* mqtt_server mqtt_encryption_enabled should_encrypt
|
||||
* not set 0 1
|
||||
* not set 1 1
|
||||
* set 0 0
|
||||
* set 1 1
|
||||
*
|
||||
*
|
||||
* => so we only decrypt mqtt if they have a custom mqtt server AND mqtt_encryption_enabled is FALSE
|
||||
*/
|
||||
*/
|
||||
|
||||
bool shouldActuallyEncrypt = true;
|
||||
if (*radioConfig.preferences.mqtt_server && !radioConfig.preferences.mqtt_encryption_enabled) {
|
||||
shouldActuallyEncrypt = false;
|
||||
}
|
||||
|
||||
|
||||
DEBUG_MSG("Should encrypt MQTT?: %d\n", shouldActuallyEncrypt);
|
||||
|
||||
//the packet is currently in a decrypted state. send it now if they want decrypted packets
|
||||
// the packet is currently in a decrypted state. send it now if they want decrypted packets
|
||||
if (mqtt && !shouldActuallyEncrypt)
|
||||
mqtt->onSend(*p, chIndex);
|
||||
#endif
|
||||
@@ -244,8 +245,8 @@ ErrorCode Router::send(MeshPacket *p)
|
||||
}
|
||||
|
||||
#if defined(HAS_WIFI) || defined(PORTDUINO)
|
||||
//the packet is now encrypted.
|
||||
//check if we should send encrypted packets to mqtt
|
||||
// the packet is now encrypted.
|
||||
// check if we should send encrypted packets to mqtt
|
||||
if (mqtt && shouldActuallyEncrypt)
|
||||
mqtt->onSend(*p, chIndex);
|
||||
#endif
|
||||
@@ -276,7 +277,7 @@ bool perhapsDecode(MeshPacket *p)
|
||||
if (p->which_payloadVariant == MeshPacket_decoded_tag)
|
||||
return true; // If packet was already decoded just return
|
||||
|
||||
//assert(p->which_payloadVariant == MeshPacket_encrypted_tag);
|
||||
// assert(p->which_payloadVariant == MeshPacket_encrypted_tag);
|
||||
|
||||
// Try to find a channel that works with this hash
|
||||
for (ChannelIndex chIndex = 0; chIndex < channels.getNumChannels(); chIndex++) {
|
||||
@@ -302,6 +303,14 @@ bool perhapsDecode(MeshPacket *p)
|
||||
// parsing was successful
|
||||
p->which_payloadVariant = MeshPacket_decoded_tag; // change type to decoded
|
||||
p->channel = chIndex; // change to store the index instead of the hash
|
||||
|
||||
|
||||
// Decompress if needed. jm
|
||||
if (p->decoded.which_payloadVariant == Data_payload_compressed_tag) {
|
||||
// Decompress the file
|
||||
}
|
||||
|
||||
|
||||
printPacket("decoded message", p);
|
||||
return true;
|
||||
}
|
||||
@@ -320,10 +329,56 @@ Routing_Error perhapsEncode(MeshPacket *p)
|
||||
if (p->which_payloadVariant == MeshPacket_decoded_tag) {
|
||||
static uint8_t bytes[MAX_RHPACKETLEN]; // we have to use a scratch buffer because a union
|
||||
|
||||
// printPacket("pre encrypt", p); // portnum valid here
|
||||
|
||||
size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), Data_fields, &p->decoded);
|
||||
|
||||
// Only allow encryption on the text message app.
|
||||
// TODO: Allow modules to opt into compression.
|
||||
if (p->decoded.portnum == PortNum_TEXT_MESSAGE_APP) {
|
||||
|
||||
char original_payload[Constants_DATA_PAYLOAD_LEN];
|
||||
memcpy(original_payload, p->decoded.payload.bytes, p->decoded.payload.size);
|
||||
|
||||
char compressed_out[Constants_DATA_PAYLOAD_LEN] = {0};
|
||||
|
||||
int compressed_len;
|
||||
// compressed_len = unishox2_compress_simple(original_payload, p->decoded.payload.size, compressed_out);
|
||||
|
||||
Serial.print("Original length - ");
|
||||
Serial.println(p->decoded.payload.size);
|
||||
|
||||
Serial.print("Compressed length - ");
|
||||
Serial.println(compressed_len);
|
||||
// Serial.println(compressed_out);
|
||||
|
||||
// If the compressed length is greater than or equal to the original size, don't use the compressed form
|
||||
if (compressed_len >= p->decoded.payload.size) {
|
||||
|
||||
DEBUG_MSG("Not compressing message. Not enough benefit from doing so.\n");
|
||||
// Set the uncompressed payload varient anyway. Shouldn't hurt?
|
||||
p->decoded.which_payloadVariant = Data_payload_tag;
|
||||
|
||||
// Otherwise we use the compressor
|
||||
} else {
|
||||
DEBUG_MSG("Compressing message.\n");
|
||||
// Copy the compressed data into the meshpacket
|
||||
//p->decoded.payload_compressed.size = compressed_len;
|
||||
//memcpy(p->decoded.payload_compressed.bytes, compressed_out, compressed_len);
|
||||
|
||||
//p->decoded.which_payloadVariant = Data_payload_compressed_tag;
|
||||
}
|
||||
|
||||
if (0) {
|
||||
char decompressed_out[Constants_DATA_PAYLOAD_LEN] = {};
|
||||
int decompressed_len;
|
||||
|
||||
// decompressed_len = unishox2_decompress_simple(compressed_out, compressed_len, decompressed_out);
|
||||
|
||||
Serial.print("Decompressed length - ");
|
||||
Serial.println(decompressed_len);
|
||||
Serial.println(decompressed_out);
|
||||
}
|
||||
}
|
||||
|
||||
if (numbytes > MAX_RHPACKETLEN)
|
||||
return Routing_Error_TOO_LARGE;
|
||||
|
||||
|
||||
1344
src/mesh/compression/unishox2.c
Normal file
1344
src/mesh/compression/unishox2.c
Normal file
File diff suppressed because it is too large
Load Diff
278
src/mesh/compression/unishox2.h
Normal file
278
src/mesh/compression/unishox2.h
Normal file
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Siara Logics (cc)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @author Arundale Ramanathan
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file unishox2.h
|
||||
* @author Arundale Ramanathan, James Z. M. Gao
|
||||
* @brief API for Unishox2 Compression and Decompression
|
||||
*
|
||||
* This file describes each function of the Unishox2 API \n
|
||||
* For finding out how this API can be used in your program, \n
|
||||
* please see test_unishox2.c.
|
||||
*/
|
||||
|
||||
#ifndef unishox2
|
||||
#define unishox2
|
||||
|
||||
#define UNISHOX_VERSION "2.0" ///< Unicode spec version
|
||||
|
||||
/**
|
||||
* Macro switch to enable/disable output buffer length parameter in low level api \n
|
||||
* Disabled by default \n
|
||||
* When this macro is defined, the all the API functions \n
|
||||
* except the simple API functions accept an additional parameter olen \n
|
||||
* that enables the developer to pass the size of the output buffer provided \n
|
||||
* so that the api function may not write beyond that length. \n
|
||||
* This can be disabled if the developer knows that the buffer provided is sufficient enough \n
|
||||
* so no additional parameter is passed and the program is faster since additional check \n
|
||||
* for output length is not performed at each step \n
|
||||
* The simple api, i.e. unishox2_(de)compress_simple will always omit the buffer length
|
||||
*/
|
||||
#ifndef UNISHOX_API_WITH_OUTPUT_LEN
|
||||
# define UNISHOX_API_WITH_OUTPUT_LEN 0
|
||||
#endif
|
||||
|
||||
/// Upto 8 bits of initial magic bit sequence can be included. Bit count can be specified with UNISHOX_MAGIC_BIT_LEN
|
||||
#ifndef UNISHOX_MAGIC_BITS
|
||||
# define UNISHOX_MAGIC_BITS 0xFF
|
||||
#endif
|
||||
|
||||
/// Desired length of Magic bits defined by UNISHOX_MAGIC_BITS
|
||||
#ifdef UNISHOX_MAGIC_BIT_LEN
|
||||
# if UNISHOX_MAGIC_BIT_LEN < 0 || 9 <= UNISHOX_MAGIC_BIT_LEN
|
||||
# error "UNISHOX_MAGIC_BIT_LEN need between [0, 8)"
|
||||
# endif
|
||||
#else
|
||||
# define UNISHOX_MAGIC_BIT_LEN 1
|
||||
#endif
|
||||
|
||||
//enum {USX_ALPHA = 0, USX_SYM, USX_NUM, USX_DICT, USX_DELTA};
|
||||
|
||||
/// Default Horizontal codes. When composition of text is know beforehand, the other hcodes in this section can be used to achieve more compression.
|
||||
#define USX_HCODES_DFLT (const unsigned char[]) {0x00, 0x40, 0x80, 0xC0, 0xE0}
|
||||
/// Length of each default hcode
|
||||
#define USX_HCODE_LENS_DFLT (const unsigned char[]) {2, 2, 2, 3, 3}
|
||||
|
||||
/// Horizontal codes preset for English Alphabet content only
|
||||
#define USX_HCODES_ALPHA_ONLY (const unsigned char[]) {0x00, 0x00, 0x00, 0x00, 0x00}
|
||||
/// Length of each Alpha only hcode
|
||||
#define USX_HCODE_LENS_ALPHA_ONLY (const unsigned char[]) {0, 0, 0, 0, 0}
|
||||
|
||||
/// Horizontal codes preset for Alpha Numeric content only
|
||||
#define USX_HCODES_ALPHA_NUM_ONLY (const unsigned char[]) {0x00, 0x00, 0x80, 0x00, 0x00}
|
||||
/// Length of each Alpha numeric hcode
|
||||
#define USX_HCODE_LENS_ALPHA_NUM_ONLY (const unsigned char[]) {1, 0, 1, 0, 0}
|
||||
|
||||
/// Horizontal codes preset for Alpha Numeric and Symbol content only
|
||||
#define USX_HCODES_ALPHA_NUM_SYM_ONLY (const unsigned char[]) {0x00, 0x80, 0xC0, 0x00, 0x00}
|
||||
/// Length of each Alpha numeric and symbol hcodes
|
||||
#define USX_HCODE_LENS_ALPHA_NUM_SYM_ONLY (const unsigned char[]) {1, 2, 2, 0, 0}
|
||||
|
||||
/// Horizontal codes preset favouring Alphabet content
|
||||
#define USX_HCODES_FAVOR_ALPHA (const unsigned char[]) {0x00, 0x80, 0xA0, 0xC0, 0xE0}
|
||||
/// Length of each hcode favouring Alpha content
|
||||
#define USX_HCODE_LENS_FAVOR_ALPHA (const unsigned char[]) {1, 3, 3, 3, 3}
|
||||
|
||||
/// Horizontal codes preset favouring repeating sequences
|
||||
#define USX_HCODES_FAVOR_DICT (const unsigned char[]) {0x00, 0x40, 0xC0, 0x80, 0xE0}
|
||||
/// Length of each hcode favouring repeating sequences
|
||||
#define USX_HCODE_LENS_FAVOR_DICT (const unsigned char[]) {2, 2, 3, 2, 3}
|
||||
|
||||
/// Horizontal codes preset favouring symbols
|
||||
#define USX_HCODES_FAVOR_SYM (const unsigned char[]) {0x80, 0x00, 0xA0, 0xC0, 0xE0}
|
||||
/// Length of each hcode favouring symbols
|
||||
#define USX_HCODE_LENS_FAVOR_SYM (const unsigned char[]) {3, 1, 3, 3, 3}
|
||||
|
||||
//#define USX_HCODES_FAVOR_UMLAUT {0x00, 0x40, 0xE0, 0xC0, 0x80}
|
||||
//#define USX_HCODE_LENS_FAVOR_UMLAUT {2, 2, 3, 3, 2}
|
||||
|
||||
/// Horizontal codes preset favouring umlaut letters
|
||||
#define USX_HCODES_FAVOR_UMLAUT (const unsigned char[]) {0x80, 0xA0, 0xC0, 0xE0, 0x00}
|
||||
/// Length of each hcode favouring umlaut letters
|
||||
#define USX_HCODE_LENS_FAVOR_UMLAUT (const unsigned char[]) {3, 3, 3, 3, 1}
|
||||
|
||||
/// Horizontal codes preset for no repeating sequences
|
||||
#define USX_HCODES_NO_DICT (const unsigned char[]) {0x00, 0x40, 0x80, 0x00, 0xC0}
|
||||
/// Length of each hcode for no repeating sequences
|
||||
#define USX_HCODE_LENS_NO_DICT (const unsigned char[]) {2, 2, 2, 0, 2}
|
||||
|
||||
/// Horizontal codes preset for no Unicode characters
|
||||
#define USX_HCODES_NO_UNI (const unsigned char[]) {0x00, 0x40, 0x80, 0xC0, 0x00}
|
||||
/// Length of each hcode for no Unicode characters
|
||||
#define USX_HCODE_LENS_NO_UNI (const unsigned char[]) {2, 2, 2, 2, 0}
|
||||
|
||||
/// Default frequently occuring sequences. When composition of text is know beforehand, the other sequences in this section can be used to achieve more compression.
|
||||
#define USX_FREQ_SEQ_DFLT (const char *[]) {"\": \"", "\": ", "</", "=\"", "\":\"", "://"}
|
||||
/// Frequently occuring sequences in text content
|
||||
#define USX_FREQ_SEQ_TXT (const char *[]) {" the ", " and ", "tion", " with", "ing", "ment"}
|
||||
/// Frequently occuring sequences in URL content
|
||||
#define USX_FREQ_SEQ_URL (const char *[]) {"https://", "www.", ".com", "http://", ".org", ".net"}
|
||||
/// Frequently occuring sequences in JSON content
|
||||
#define USX_FREQ_SEQ_JSON (const char *[]) {"\": \"", "\": ", "\",", "}}}", "\":\"", "}}"}
|
||||
/// Frequently occuring sequences in HTML content
|
||||
#define USX_FREQ_SEQ_HTML (const char *[]) {"</", "=\"", "div", "href", "class", "<p>"}
|
||||
/// Frequently occuring sequences in XML content
|
||||
#define USX_FREQ_SEQ_XML (const char *[]) {"</", "=\"", "\">", "<?xml version=\"1.0\"", "xmlns:", "://"}
|
||||
|
||||
/// Commonly occuring templates (ISO Date/Time, ISO Date, US Phone number, ISO Time, Unused)
|
||||
#define USX_TEMPLATES (const char *[]) {"tfff-of-tfTtf:rf:rf.fffZ", "tfff-of-tf", "(fff) fff-ffff", "tf:rf:rf", 0}
|
||||
|
||||
/// Default preset parameter set. When composition of text is know beforehand, the other parameter sets in this section can be used to achieve more compression.
|
||||
#define USX_PSET_DFLT USX_HCODES_DFLT, USX_HCODE_LENS_DFLT, USX_FREQ_SEQ_DFLT, USX_TEMPLATES
|
||||
/// Preset parameter set for English Alphabet only content
|
||||
#define USX_PSET_ALPHA_ONLY USX_HCODES_ALPHA_ONLY, USX_HCODE_LENS_ALPHA_ONLY, USX_FREQ_SEQ_TXT, USX_TEMPLATES
|
||||
/// Preset parameter set for Alpha numeric content
|
||||
#define USX_PSET_ALPHA_NUM_ONLY USX_HCODES_ALPHA_NUM_ONLY, USX_HCODE_LENS_ALPHA_NUM_ONLY, USX_FREQ_SEQ_TXT, USX_TEMPLATES
|
||||
/// Preset parameter set for Alpha numeric and symbol content
|
||||
#define USX_PSET_ALPHA_NUM_SYM_ONLY USX_HCODES_ALPHA_NUM_SYM_ONLY, USX_HCODE_LENS_ALPHA_NUM_SYM_ONLY, USX_FREQ_SEQ_DFLT, USX_TEMPLATES
|
||||
/// Preset parameter set for Alpha numeric symbol content having predominantly text
|
||||
#define USX_PSET_ALPHA_NUM_SYM_ONLY_TXT USX_HCODES_ALPHA_NUM_SYM_ONLY, USX_HCODE_LENS_ALPHA_NUM_SYM_ONLY, USX_FREQ_SEQ_DFLT, USX_TEMPLATES
|
||||
/// Preset parameter set favouring Alphabet content
|
||||
#define USX_PSET_FAVOR_ALPHA USX_HCODES_FAVOR_ALPHA, USX_HCODE_LENS_FAVOR_ALPHA, USX_FREQ_SEQ_TXT, USX_TEMPLATES
|
||||
/// Preset parameter set favouring repeating sequences
|
||||
#define USX_PSET_FAVOR_DICT USX_HCODES_FAVOR_DICT, USX_HCODE_LENS_FAVOR_DICT, USX_FREQ_SEQ_DFLT, USX_TEMPLATES
|
||||
/// Preset parameter set favouring symbols
|
||||
#define USX_PSET_FAVOR_SYM USX_HCODES_FAVOR_SYM, USX_HCODE_LENS_FAVOR_SYM, USX_FREQ_SEQ_DFLT, USX_TEMPLATES
|
||||
/// Preset parameter set favouring unlaut letters
|
||||
#define USX_PSET_FAVOR_UMLAUT USX_HCODES_FAVOR_UMLAUT, USX_HCODE_LENS_FAVOR_UMLAUT, USX_FREQ_SEQ_DFLT, USX_TEMPLATES
|
||||
/// Preset parameter set for when there are no repeating sequences
|
||||
#define USX_PSET_NO_DICT USX_HCODES_NO_DICT, USX_HCODE_LENS_NO_DICT, USX_FREQ_SEQ_DFLT, USX_TEMPLATES
|
||||
/// Preset parameter set for when there are no unicode symbols
|
||||
#define USX_PSET_NO_UNI USX_HCODES_NO_UNI, USX_HCODE_LENS_NO_UNI, USX_FREQ_SEQ_DFLT, USX_TEMPLATES
|
||||
/// Preset parameter set for when there are no unicode symbols favouring text
|
||||
#define USX_PSET_NO_UNI_FAVOR_TEXT USX_HCODES_NO_UNI, USX_HCODE_LENS_NO_UNI, USX_FREQ_SEQ_TXT, USX_TEMPLATES
|
||||
/// Preset parameter set favouring URL content
|
||||
#define USX_PSET_URL USX_HCODES_DFLT, USX_HCODE_LENS_DFLT, USX_FREQ_SEQ_URL, USX_TEMPLATES
|
||||
/// Preset parameter set favouring JSON content
|
||||
#define USX_PSET_JSON USX_HCODES_DFLT, USX_HCODE_LENS_DFLT, USX_FREQ_SEQ_JSON, USX_TEMPLATES
|
||||
/// Preset parameter set favouring JSON content having no Unicode symbols
|
||||
#define USX_PSET_JSON_NO_UNI USX_HCODES_NO_UNI, USX_HCODE_LENS_NO_UNI, USX_FREQ_SEQ_JSON, USX_TEMPLATES
|
||||
/// Preset parameter set favouring XML content
|
||||
#define USX_PSET_XML USX_HCODES_DFLT, USX_HCODE_LENS_DFLT, USX_FREQ_SEQ_XML, USX_TEMPLATES
|
||||
/// Preset parameter set favouring HTML content
|
||||
#define USX_PSET_HTML USX_HCODES_DFLT, USX_HCODE_LENS_DFLT, USX_FREQ_SEQ_HTML, USX_TEMPLATES
|
||||
|
||||
/**
|
||||
* This structure is used when a string array needs to be compressed.
|
||||
* This is passed as a parameter to the unishox2_decompress_lines() function
|
||||
*/
|
||||
struct us_lnk_lst {
|
||||
char *data;
|
||||
struct us_lnk_lst *previous;
|
||||
};
|
||||
|
||||
/**
|
||||
* This macro is for internal use, but builds upon the macro UNISHOX_API_WITH_OUTPUT_LEN
|
||||
* When the macro UNISHOX_API_WITH_OUTPUT_LEN is defined, the all the API functions
|
||||
* except the simple API functions accept an additional parameter olen
|
||||
* that enables the developer to pass the size of the output buffer provided
|
||||
* so that the api function may not write beyond that length.
|
||||
* This can be disabled if the developer knows that the buffer provided is sufficient enough
|
||||
* so no additional parameter is passed and the program is faster since additional check
|
||||
* for output length is not performed at each step
|
||||
*/
|
||||
#if defined(UNISHOX_API_WITH_OUTPUT_LEN) && UNISHOX_API_WITH_OUTPUT_LEN != 0
|
||||
# define UNISHOX_API_OUT_AND_LEN(out, olen) out, olen
|
||||
#else
|
||||
# define UNISHOX_API_OUT_AND_LEN(out, olen) out
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Simple API for compressing a string
|
||||
* @param[in] in Input ASCII / UTF-8 string
|
||||
* @param[in] len length in bytes
|
||||
* @param[out] out output buffer - should be large enough to hold compressed output
|
||||
*/
|
||||
extern int unishox2_compress_simple(const char *in, int len, char *out);
|
||||
/**
|
||||
* Simple API for decompressing a string
|
||||
* @param[in] in Input compressed bytes (output of unishox2_compress functions)
|
||||
* @param[in] len length of 'in' in bytes
|
||||
* @param[out] out output buffer for ASCII / UTF-8 string - should be large enough
|
||||
*/
|
||||
extern int unishox2_decompress_simple(const char *in, int len, char *out);
|
||||
/**
|
||||
* Comprehensive API for compressing a string
|
||||
*
|
||||
* Presets are available for the last four parameters so they can be passed as single parameter. \n
|
||||
* See USX_PSET_* macros. Example call: \n
|
||||
* unishox2_compress(in, len, out, olen, USX_PSET_ALPHA_ONLY);
|
||||
*
|
||||
* @param[in] in Input ASCII / UTF-8 string
|
||||
* @param[in] len length in bytes
|
||||
* @param[out] out output buffer - should be large enough to hold compressed output
|
||||
* @param[in] olen length of 'out' buffer in bytes. Can be omitted if sufficient buffer is provided
|
||||
* @param[in] usx_hcodes Horizontal codes (array of bytes). See macro section for samples.
|
||||
* @param[in] usx_hcode_lens Length of each element in usx_hcodes array
|
||||
* @param[in] usx_freq_seq Frequently occuring sequences. See USX_FREQ_SEQ_* macros for samples
|
||||
* @param[in] usx_templates Templates of frequently occuring patterns. See USX_TEMPLATES macro.
|
||||
*/
|
||||
extern int unishox2_compress(const char *in, int len, UNISHOX_API_OUT_AND_LEN(char *out, int olen),
|
||||
const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[],
|
||||
const char *usx_freq_seq[], const char *usx_templates[]);
|
||||
/**
|
||||
* Comprehensive API for de-compressing a string
|
||||
*
|
||||
* Presets are available for the last four parameters so they can be passed as single parameter. \n
|
||||
* See USX_PSET_* macros. Example call: \n
|
||||
* unishox2_decompress(in, len, out, olen, USX_PSET_ALPHA_ONLY);
|
||||
*
|
||||
* @param[in] in Input compressed bytes (output of unishox2_compress functions)
|
||||
* @param[in] len length of 'in' in bytes
|
||||
* @param[out] out output buffer - should be large enough to hold de-compressed output
|
||||
* @param[in] olen length of 'out' buffer in bytes. Can be omitted if sufficient buffer is provided
|
||||
* @param[in] usx_hcodes Horizontal codes (array of bytes). See macro section for samples.
|
||||
* @param[in] usx_hcode_lens Length of each element in usx_hcodes array
|
||||
* @param[in] usx_freq_seq Frequently occuring sequences. See USX_FREQ_SEQ_* macros for samples
|
||||
* @param[in] usx_templates Templates of frequently occuring patterns. See USX_TEMPLATES macro.
|
||||
*/
|
||||
extern int unishox2_decompress(const char *in, int len, UNISHOX_API_OUT_AND_LEN(char *out, int olen),
|
||||
const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[],
|
||||
const char *usx_freq_seq[], const char *usx_templates[]);
|
||||
/**
|
||||
* More Comprehensive API for compressing array of strings
|
||||
*
|
||||
* See unishox2_compress() function for parameter definitions. \n
|
||||
* This function takes an additional parameter, i.e. 'prev_lines' - the usx_lnk_lst structure \n
|
||||
* See -g parameter in test_unishox2.c to find out how this can be used. \n
|
||||
* This function is used when an array of strings need to be compressed \n
|
||||
* and stored in a compressed array of bytes for use as a constant in other programs \n
|
||||
* where each element of the array can be decompressed and used at runtime.
|
||||
*/
|
||||
extern int unishox2_compress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(char *out, int olen),
|
||||
const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[],
|
||||
const char *usx_freq_seq[], const char *usx_templates[],
|
||||
struct us_lnk_lst *prev_lines);
|
||||
/**
|
||||
* More Comprehensive API for de-compressing array of strings \n
|
||||
* This function is not be used in conjuction with unishox2_compress_lines()
|
||||
*
|
||||
* See unishox2_decompress() function for parameter definitions. \n
|
||||
* Typically an array is compressed using unishox2_compress_lines() and \n
|
||||
* a header (.h) file is generated using the resultant compressed array. \n
|
||||
* This header file can be used in another program with another decompress \n
|
||||
* routine which takes this compressed array as parameter and index to be \n
|
||||
* decompressed.
|
||||
*/
|
||||
extern int unishox2_decompress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(char *out, int olen),
|
||||
const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[],
|
||||
const char *usx_freq_seq[], const char *usx_templates[],
|
||||
struct us_lnk_lst *prev_lines);
|
||||
|
||||
#endif
|
||||
@@ -12,4 +12,8 @@ PB_BIND(DeviceState, DeviceState, 4)
|
||||
PB_BIND(ChannelFile, ChannelFile, 2)
|
||||
|
||||
|
||||
PB_BIND(OEMStore, OEMStore, 2)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -11,6 +11,17 @@
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
/* Enum definitions */
|
||||
/* TODO: REPLACE */
|
||||
typedef enum _ScreenFonts {
|
||||
/* TODO: REPLACE */
|
||||
ScreenFonts_FONT_SMALL = 0,
|
||||
/* TODO: REPLACE */
|
||||
ScreenFonts_FONT_MEDIUM = 1,
|
||||
/* TODO: REPLACE */
|
||||
ScreenFonts_FONT_LARGE = 2
|
||||
} ScreenFonts;
|
||||
|
||||
/* Struct definitions */
|
||||
/* The on-disk saved channels */
|
||||
typedef struct _ChannelFile {
|
||||
@@ -33,7 +44,7 @@ typedef struct _DeviceState {
|
||||
User owner;
|
||||
/* TODO: REPLACE */
|
||||
pb_size_t node_db_count;
|
||||
NodeInfo node_db[80];
|
||||
NodeInfo node_db[64];
|
||||
/* Received packets saved for delivery to the phone */
|
||||
pb_size_t receive_queue_count;
|
||||
MeshPacket receive_queue[1];
|
||||
@@ -53,16 +64,38 @@ typedef struct _DeviceState {
|
||||
bool did_gps_reset;
|
||||
} DeviceState;
|
||||
|
||||
typedef PB_BYTES_ARRAY_T(2048) OEMStore_oem_icon_bits_t;
|
||||
/* This can be used for customizing the firmware distribution. If populated,
|
||||
show a secondary bootup screen with cuatom logo and text for 2.5 seconds. */
|
||||
typedef struct _OEMStore {
|
||||
/* The Logo width in Px */
|
||||
uint32_t oem_icon_width;
|
||||
/* The Logo height in Px */
|
||||
uint32_t oem_icon_height;
|
||||
/* The Logo in xbm bytechar format */
|
||||
OEMStore_oem_icon_bits_t oem_icon_bits;
|
||||
/* Use this font for the OEM text. */
|
||||
ScreenFonts oem_font;
|
||||
/* Use this font for the OEM text. */
|
||||
char oem_text[40];
|
||||
} OEMStore;
|
||||
|
||||
|
||||
/* Helper constants for enums */
|
||||
#define _ScreenFonts_MIN ScreenFonts_FONT_SMALL
|
||||
#define _ScreenFonts_MAX ScreenFonts_FONT_LARGE
|
||||
#define _ScreenFonts_ARRAYSIZE ((ScreenFonts)(ScreenFonts_FONT_LARGE+1))
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define DeviceState_init_default {false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0, 0}
|
||||
#define ChannelFile_init_default {0, {Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default}}
|
||||
#define DeviceState_init_zero {false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0, 0}
|
||||
#define DeviceState_init_default {false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0, 0}
|
||||
#define DeviceState_init_zero {false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0, 0}
|
||||
#define ChannelFile_init_zero {0, {Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero}}
|
||||
#define OEMStore_init_zero {0, 0, {0, {0}}, _ScreenFonts_MIN, ""}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define ChannelFile_channels_tag 1
|
||||
@@ -74,6 +107,11 @@ extern "C" {
|
||||
#define DeviceState_version_tag 8
|
||||
#define DeviceState_no_save_tag 9
|
||||
#define DeviceState_did_gps_reset_tag 11
|
||||
#define OEMStore_oem_icon_width_tag 1
|
||||
#define OEMStore_oem_icon_height_tag 2
|
||||
#define OEMStore_oem_icon_bits_tag 3
|
||||
#define OEMStore_oem_font_tag 4
|
||||
#define OEMStore_oem_text_tag 5
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define DeviceState_FIELDLIST(X, a) \
|
||||
@@ -99,16 +137,28 @@ X(a, STATIC, REPEATED, MESSAGE, channels, 1)
|
||||
#define ChannelFile_DEFAULT NULL
|
||||
#define ChannelFile_channels_MSGTYPE Channel
|
||||
|
||||
#define OEMStore_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, oem_icon_width, 1) \
|
||||
X(a, STATIC, SINGULAR, UINT32, oem_icon_height, 2) \
|
||||
X(a, STATIC, SINGULAR, BYTES, oem_icon_bits, 3) \
|
||||
X(a, STATIC, SINGULAR, UENUM, oem_font, 4) \
|
||||
X(a, STATIC, SINGULAR, STRING, oem_text, 5)
|
||||
#define OEMStore_CALLBACK NULL
|
||||
#define OEMStore_DEFAULT NULL
|
||||
|
||||
extern const pb_msgdesc_t DeviceState_msg;
|
||||
extern const pb_msgdesc_t ChannelFile_msg;
|
||||
extern const pb_msgdesc_t OEMStore_msg;
|
||||
|
||||
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
||||
#define DeviceState_fields &DeviceState_msg
|
||||
#define ChannelFile_fields &ChannelFile_msg
|
||||
#define OEMStore_fields &OEMStore_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define ChannelFile_size 832
|
||||
#define DeviceState_size 23903
|
||||
#define DeviceState_size 19327
|
||||
#define OEMStore_size 2106
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
@@ -500,6 +500,7 @@ typedef struct _User {
|
||||
} User;
|
||||
|
||||
typedef PB_BYTES_ARRAY_T(237) Data_payload_t;
|
||||
typedef PB_BYTES_ARRAY_T(237) Data_payload_compressed_t;
|
||||
/* (Formerly called SubPacket)
|
||||
The payload portion fo a packet, this is the actual bytes that are sent
|
||||
inside a radio packet (because from/to are broken out by the comms library) */
|
||||
@@ -507,30 +508,34 @@ typedef struct _Data {
|
||||
/* Formerly named typ and of type Type */
|
||||
PortNum portnum;
|
||||
/* TODO: REPLACE */
|
||||
Data_payload_t payload;
|
||||
pb_size_t which_payloadVariant;
|
||||
union {
|
||||
Data_payload_t payload;
|
||||
Data_payload_compressed_t payload_compressed;
|
||||
};
|
||||
/* TODO: REPLACE */
|
||||
bool want_response;
|
||||
/* Not normally used, but for testing a sender can request that recipient
|
||||
responds in kind (i.e. if it received a position, it should unicast back it's position).
|
||||
Note: that if you set this on a broadcast you will receive many replies. */
|
||||
bool want_response;
|
||||
uint32_t dest;
|
||||
/* The address of the destination node.
|
||||
This field is is filled in by the mesh radio device software, application
|
||||
layer software should never need it.
|
||||
RouteDiscovery messages _must_ populate this.
|
||||
Other message types might need to if they are doing multihop routing. */
|
||||
uint32_t dest;
|
||||
uint32_t source;
|
||||
/* The address of the original sender for this message.
|
||||
This field should _only_ be populated for reliable multihop packets (to keep
|
||||
packets small). */
|
||||
uint32_t source;
|
||||
uint32_t request_id;
|
||||
/* Only used in routing or response messages.
|
||||
Indicates the original message ID that this message is reporting failure on. (formerly called original_id) */
|
||||
uint32_t request_id;
|
||||
/* If set, this message is intened to be a reply to a previously sent message with the defined id. */
|
||||
uint32_t reply_id;
|
||||
/* If set, this message is intened to be a reply to a previously sent message with the defined id. */
|
||||
uint32_t emoji;
|
||||
/* Defaults to false. If true, then what is in the payload should be treated as an emoji like giving
|
||||
a message a heart or poop emoji. */
|
||||
uint32_t emoji;
|
||||
/* Location structure */
|
||||
bool has_location;
|
||||
Location location;
|
||||
} Data;
|
||||
@@ -738,7 +743,7 @@ extern "C" {
|
||||
#define User_init_default {"", "", "", {0}, _HardwareModel_MIN, 0, _Team_MIN, 0, 0, 0}
|
||||
#define RouteDiscovery_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}}
|
||||
#define Routing_init_default {0, {RouteDiscovery_init_default}}
|
||||
#define Data_init_default {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, Location_init_default}
|
||||
#define Data_init_default {_PortNum_MIN, 0, {{0, {0}}}, 0, 0, 0, 0, 0, 0, false, Location_init_default}
|
||||
#define Location_init_default {0, 0, 0, 0, 0}
|
||||
#define MeshPacket_init_default {0, 0, 0, 0, {Data_init_default}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN}
|
||||
#define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0, false, DeviceMetrics_init_default}
|
||||
@@ -751,7 +756,7 @@ extern "C" {
|
||||
#define User_init_zero {"", "", "", {0}, _HardwareModel_MIN, 0, _Team_MIN, 0, 0, 0}
|
||||
#define RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}}
|
||||
#define Routing_init_zero {0, {RouteDiscovery_init_zero}}
|
||||
#define Data_init_zero {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, Location_init_zero}
|
||||
#define Data_init_zero {_PortNum_MIN, 0, {{0, {0}}}, 0, 0, 0, 0, 0, 0, false, Location_init_zero}
|
||||
#define Location_init_zero {0, 0, 0, 0, 0}
|
||||
#define MeshPacket_init_zero {0, 0, 0, 0, {Data_init_zero}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN}
|
||||
#define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0, false, DeviceMetrics_init_zero}
|
||||
@@ -825,6 +830,7 @@ extern "C" {
|
||||
#define User_ant_azimuth_tag 12
|
||||
#define Data_portnum_tag 1
|
||||
#define Data_payload_tag 2
|
||||
#define Data_payload_compressed_tag 10
|
||||
#define Data_want_response_tag 3
|
||||
#define Data_dest_tag 4
|
||||
#define Data_source_tag 5
|
||||
@@ -923,14 +929,15 @@ X(a, STATIC, ONEOF, UENUM, (variant,error_reason,error_reason), 3)
|
||||
|
||||
#define Data_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UENUM, portnum, 1) \
|
||||
X(a, STATIC, SINGULAR, BYTES, payload, 2) \
|
||||
X(a, STATIC, ONEOF, BYTES, (payloadVariant,payload,payload), 2) \
|
||||
X(a, STATIC, SINGULAR, BOOL, want_response, 3) \
|
||||
X(a, STATIC, SINGULAR, FIXED32, dest, 4) \
|
||||
X(a, STATIC, SINGULAR, FIXED32, source, 5) \
|
||||
X(a, STATIC, SINGULAR, FIXED32, request_id, 6) \
|
||||
X(a, STATIC, SINGULAR, FIXED32, reply_id, 7) \
|
||||
X(a, STATIC, SINGULAR, FIXED32, emoji, 8) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, location, 9)
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, location, 9) \
|
||||
X(a, STATIC, ONEOF, BYTES, (payloadVariant,payload_compressed,payload_compressed), 10)
|
||||
#define Data_CALLBACK NULL
|
||||
#define Data_DEFAULT NULL
|
||||
#define Data_location_MSGTYPE Location
|
||||
|
||||
@@ -40,10 +40,10 @@ typedef struct _EnvironmentMetrics {
|
||||
|
||||
/* Types of Measurements the telemetry module is equipped to handle */
|
||||
typedef struct _Telemetry {
|
||||
/* This is usually not sent over the mesh (to save space), but it is sent
|
||||
from the phone so that the local device can set its RTC If it is sent over
|
||||
the mesh (because there are devices on the mesh without GPS), it will only
|
||||
be sent by devices which has a hardware GPS clock (IE Mobile Phone).
|
||||
/* This is usually not sent over the mesh (to save space), but it is sent
|
||||
from the phone so that the local device can set its RTC If it is sent over
|
||||
the mesh (because there are devices on the mesh without GPS), it will only
|
||||
be sent by devices which has a hardware GPS clock (IE Mobile Phone).
|
||||
seconds since 1970 */
|
||||
uint32_t time;
|
||||
/* Key native device metrics such as battery level */
|
||||
|
||||
@@ -47,11 +47,9 @@ using namespace httpsserver;
|
||||
#include <WiFiClientSecure.h>
|
||||
HTTPClient httpClient;
|
||||
|
||||
// needed for ESP32-targz
|
||||
#define DEST_FS_USES_LITTLEFS
|
||||
#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch))
|
||||
#define ESP_ARDUINO_VERSION ESP_ARDUINO_VERSION_VAL(1, 0, 4)
|
||||
#include <ESP32-targz.h>
|
||||
|
||||
// We need to specify some content-type mapping, so the resources get delivered with the
|
||||
// right content type and are displayed correctly in the browser
|
||||
@@ -63,57 +61,13 @@ char contentTypes[][2][32] = {{".txt", "text/plain"}, {".html", "text/html"}
|
||||
{".svg", "image/svg+xml"}, {"", ""}};
|
||||
|
||||
// const char *tarURL = "https://www.casler.org/temp/meshtastic-web.tar";
|
||||
const char *tarURL = "https://api-production-871d.up.railway.app/mirror/webui";
|
||||
const char *certificate = NULL; // change this as needed, leave as is for no TLS check (yolo security)
|
||||
// const char *tarURL = "https://api-production-871d.up.railway.app/mirror/webui";
|
||||
// const char *certificate = NULL; // change this as needed, leave as is for no TLS check (yolo security)
|
||||
|
||||
// Our API to handle messages to and from the radio.
|
||||
HttpAPI webAPI;
|
||||
|
||||
WiFiClient *getTarHTTPClientPtr(WiFiClientSecure *client, const char *url, const char *cert = NULL)
|
||||
{
|
||||
if (cert == NULL) {
|
||||
// New versions don't have setInsecure
|
||||
// client->setInsecure();
|
||||
} else {
|
||||
client->setCACert(cert);
|
||||
}
|
||||
const char *UserAgent = "ESP32-HTTP-GzUpdater-Client";
|
||||
httpClient.setReuse(true); // handle 301 redirects gracefully
|
||||
httpClient.setUserAgent(UserAgent);
|
||||
httpClient.setConnectTimeout(10000); // 10s timeout = 10000
|
||||
if (!httpClient.begin(*client, url)) {
|
||||
log_e("Can't open url %s", url);
|
||||
return nullptr;
|
||||
}
|
||||
const char *headerKeys[] = {"location", "redirect", "Content-Type", "Content-Length", "Content-Disposition"};
|
||||
const size_t numberOfHeaders = 5;
|
||||
httpClient.collectHeaders(headerKeys, numberOfHeaders);
|
||||
int httpCode = httpClient.GET();
|
||||
// file found at server
|
||||
if (httpCode == HTTP_CODE_FOUND || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
|
||||
String newlocation = "";
|
||||
String headerLocation = httpClient.header("location");
|
||||
String headerRedirect = httpClient.header("redirect");
|
||||
if (headerLocation != "") {
|
||||
newlocation = headerLocation;
|
||||
Serial.printf("302 (location): %s => %s\n", url, headerLocation.c_str());
|
||||
} else if (headerRedirect != "") {
|
||||
Serial.printf("301 (redirect): %s => %s\n", url, headerLocation.c_str());
|
||||
newlocation = headerRedirect;
|
||||
}
|
||||
httpClient.end();
|
||||
if (newlocation != "") {
|
||||
log_w("Found 302/301 location header: %s", newlocation.c_str());
|
||||
return getTarHTTPClientPtr(client, newlocation.c_str(), cert);
|
||||
} else {
|
||||
log_e("Empty redirect !!");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
if (httpCode != 200)
|
||||
return nullptr;
|
||||
return httpClient.getStreamPtr();
|
||||
}
|
||||
|
||||
|
||||
void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
|
||||
{
|
||||
@@ -131,9 +85,9 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
|
||||
ResourceNode *nodeAdmin = new ResourceNode("/admin", "GET", &handleAdmin);
|
||||
ResourceNode *nodeAdminSettings = new ResourceNode("/admin/settings", "GET", &handleAdminSettings);
|
||||
ResourceNode *nodeAdminSettingsApply = new ResourceNode("/admin/settings/apply", "POST", &handleAdminSettingsApply);
|
||||
ResourceNode *nodeAdminFs = new ResourceNode("/admin/fs", "GET", &handleFs);
|
||||
ResourceNode *nodeUpdateFs = new ResourceNode("/admin/fs/update", "POST", &handleUpdateFs);
|
||||
ResourceNode *nodeDeleteFs = new ResourceNode("/admin/fs/delete", "GET", &handleDeleteFsContent);
|
||||
// ResourceNode *nodeAdminFs = new ResourceNode("/admin/fs", "GET", &handleFs);
|
||||
// ResourceNode *nodeUpdateFs = new ResourceNode("/admin/fs/update", "POST", &handleUpdateFs);
|
||||
// ResourceNode *nodeDeleteFs = new ResourceNode("/admin/fs/delete", "GET", &handleDeleteFsContent);
|
||||
|
||||
ResourceNode *nodeRestart = new ResourceNode("/restart", "POST", &handleRestart);
|
||||
ResourceNode *nodeFormUpload = new ResourceNode("/upload", "POST", &handleFormUpload);
|
||||
@@ -160,10 +114,10 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
|
||||
secureServer->registerNode(nodeJsonFsBrowseStatic);
|
||||
secureServer->registerNode(nodeJsonDelete);
|
||||
secureServer->registerNode(nodeJsonReport);
|
||||
secureServer->registerNode(nodeUpdateFs);
|
||||
secureServer->registerNode(nodeDeleteFs);
|
||||
// secureServer->registerNode(nodeUpdateFs);
|
||||
// secureServer->registerNode(nodeDeleteFs);
|
||||
secureServer->registerNode(nodeAdmin);
|
||||
secureServer->registerNode(nodeAdminFs);
|
||||
// secureServer->registerNode(nodeAdminFs);
|
||||
secureServer->registerNode(nodeAdminSettings);
|
||||
secureServer->registerNode(nodeAdminSettingsApply);
|
||||
secureServer->registerNode(nodeRoot); // This has to be last
|
||||
@@ -181,10 +135,10 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer)
|
||||
insecureServer->registerNode(nodeJsonFsBrowseStatic);
|
||||
insecureServer->registerNode(nodeJsonDelete);
|
||||
insecureServer->registerNode(nodeJsonReport);
|
||||
insecureServer->registerNode(nodeUpdateFs);
|
||||
insecureServer->registerNode(nodeDeleteFs);
|
||||
// insecureServer->registerNode(nodeUpdateFs);
|
||||
// insecureServer->registerNode(nodeDeleteFs);
|
||||
insecureServer->registerNode(nodeAdmin);
|
||||
insecureServer->registerNode(nodeAdminFs);
|
||||
// insecureServer->registerNode(nodeAdminFs);
|
||||
insecureServer->registerNode(nodeAdminSettings);
|
||||
insecureServer->registerNode(nodeAdminSettingsApply);
|
||||
insecureServer->registerNode(nodeRoot); // This has to be last
|
||||
@@ -727,86 +681,6 @@ void handleHotspot(HTTPRequest *req, HTTPResponse *res)
|
||||
res->println("<meta http-equiv=\"refresh\" content=\"0;url=/\" />\n");
|
||||
}
|
||||
|
||||
void handleUpdateFs(HTTPRequest *req, HTTPResponse *res)
|
||||
{
|
||||
res->setHeader("Content-Type", "text/html");
|
||||
res->setHeader("Access-Control-Allow-Origin", "*");
|
||||
// res->setHeader("Access-Control-Allow-Methods", "POST");
|
||||
|
||||
res->println("<h1>Meshtastic</h1>\n");
|
||||
res->println("Downloading Meshtastic Web Content...");
|
||||
|
||||
WiFiClientSecure *client = new WiFiClientSecure;
|
||||
Stream *streamptr = getTarHTTPClientPtr(client, tarURL, certificate);
|
||||
|
||||
delay(5); // Let other network operations run
|
||||
|
||||
if (streamptr != nullptr) {
|
||||
DEBUG_MSG("Connection to content server ... success!\n");
|
||||
|
||||
DEBUG_MSG("Deleting files from /static : \n");
|
||||
|
||||
htmlDeleteDir("/static");
|
||||
|
||||
delay(5); // Let other network operations run
|
||||
|
||||
TarUnpacker *TARUnpacker = new TarUnpacker();
|
||||
TARUnpacker->haltOnError(false); // stop on fail (manual restart/reset required)
|
||||
TARUnpacker->setTarVerify(false); // true = enables health checks but slows down the overall process
|
||||
TARUnpacker->setupFSCallbacks(targzTotalBytesFn, targzFreeBytesFn); // prevent the partition from exploding, recommended
|
||||
TARUnpacker->setLoggerCallback(BaseUnpacker::targzPrintLoggerCallback); // gz log verbosity
|
||||
TARUnpacker->setTarProgressCallback(
|
||||
BaseUnpacker::defaultProgressCallback); // prints the untarring progress for each individual file
|
||||
TARUnpacker->setTarStatusProgressCallback(
|
||||
BaseUnpacker::defaultTarStatusProgressCallback); // print the filenames as they're expanded
|
||||
TARUnpacker->setTarMessageCallback(BaseUnpacker::targzPrintLoggerCallback); // tar log verbosity
|
||||
|
||||
String contentLengthStr = httpClient.header("Content-Length");
|
||||
contentLengthStr.trim();
|
||||
int64_t streamSize = -1;
|
||||
if (contentLengthStr != "") {
|
||||
streamSize = atoi(contentLengthStr.c_str());
|
||||
Serial.printf("Stream size %d\n", streamSize);
|
||||
res->printf("Stream size %d<br><br>\n", streamSize);
|
||||
}
|
||||
|
||||
if (!TARUnpacker->tarStreamExpander(streamptr, streamSize, FSCom, "/static")) {
|
||||
res->printf("tarStreamExpander failed with return code #%d\n", TARUnpacker->tarGzGetError());
|
||||
Serial.printf("tarStreamExpander failed with return code #%d\n", TARUnpacker->tarGzGetError());
|
||||
// Close the connection on error and free up memory
|
||||
client->stop();
|
||||
|
||||
return;
|
||||
} else {
|
||||
/*
|
||||
// print leftover bytes if any (probably zero-fill from the server)
|
||||
while (httpClient.connected()) {
|
||||
size_t streamSize = streamptr->available();
|
||||
if (streamSize) {
|
||||
Serial.printf("%02x ", streamptr->read());
|
||||
} else
|
||||
break;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
} else {
|
||||
res->printf("Failed to establish http connection\n");
|
||||
Serial.println("Failed to establish http connection");
|
||||
return;
|
||||
// Close the connection on error and free up memory
|
||||
client->stop();
|
||||
}
|
||||
|
||||
res->println("Done! Restarting the device. <a href=/>Click this in 10 seconds</a>");
|
||||
|
||||
/*
|
||||
* This is a work around for a bug where we run out of memory.
|
||||
* TODO: Fixme!
|
||||
*/
|
||||
// ESP.restart();
|
||||
webServerThread->requestRestart = (millis() / 1000) + 5;
|
||||
}
|
||||
|
||||
void handleDeleteFsContent(HTTPRequest *req, HTTPResponse *res)
|
||||
{
|
||||
|
||||
@@ -10,10 +10,13 @@
|
||||
#include "target_specific.h"
|
||||
#include <DNSServer.h>
|
||||
#include <ESPmDNS.h>
|
||||
#include <NTPClient.h>
|
||||
#include <WiFi.h>
|
||||
#include <WiFiUdp.h>
|
||||
|
||||
#ifndef DISABLE_NTP
|
||||
#include <NTPClient.h>
|
||||
#endif
|
||||
|
||||
using namespace concurrency;
|
||||
|
||||
static void WiFiEvent(WiFiEvent_t event);
|
||||
@@ -23,7 +26,10 @@ DNSServer dnsServer;
|
||||
|
||||
// NTP
|
||||
WiFiUDP ntpUDP;
|
||||
|
||||
#ifndef DISABLE_NTP
|
||||
NTPClient timeClient(ntpUDP, "0.pool.ntp.org");
|
||||
#endif
|
||||
|
||||
uint8_t wifiDisconnectReason = 0;
|
||||
|
||||
@@ -67,13 +73,13 @@ static int32_t reconnectWiFi()
|
||||
DEBUG_MSG("... Reconnecting to WiFi access point\n");
|
||||
WiFi.mode(WIFI_MODE_STA);
|
||||
WiFi.begin(wifiName, wifiPsw);
|
||||
|
||||
|
||||
// Starting timeClient;
|
||||
}
|
||||
}
|
||||
|
||||
//if (*wifiName) {
|
||||
#ifndef DISABLE_NTP
|
||||
// if (*wifiName) {
|
||||
if (WiFi.isConnected()) {
|
||||
DEBUG_MSG("Updating NTP time\n");
|
||||
if (timeClient.update()) {
|
||||
@@ -89,6 +95,7 @@ static int32_t reconnectWiFi()
|
||||
DEBUG_MSG("NTP Update failed\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 30 * 1000; // every 30 seconds
|
||||
}
|
||||
@@ -155,9 +162,11 @@ static void onNetworkConnected()
|
||||
MDNS.addService("https", "tcp", 443);
|
||||
}
|
||||
|
||||
#ifndef DISABLE_NTP
|
||||
DEBUG_MSG("Starting NTP time client\n");
|
||||
timeClient.begin();
|
||||
timeClient.setUpdateInterval(60*60); // Update once an hour
|
||||
timeClient.setUpdateInterval(60 * 60); // Update once an hour
|
||||
#endif
|
||||
|
||||
initWebServer();
|
||||
initApiServer();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[VERSION]
|
||||
major = 1
|
||||
minor = 3
|
||||
build = 6
|
||||
build = 8
|
||||
|
||||
Reference in New Issue
Block a user