diff --git a/README.md b/README.md index 9ba829bf5..5eb417171 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![Continuous Integration](https://github.com/meshtastic/Meshtastic-device/actions/workflows/main.yml/badge.svg)](https://github.com/meshtastic/Meshtastic-device/actions/workflows/main.yml) ![GitHub all releases](https://img.shields.io/github/downloads/meshtastic/meshtastic-device/total) [![CLA assistant](https://cla-assistant.io/readme/badge/meshtastic/Meshtastic-device)](https://cla-assistant.io/meshtastic/Meshtastic-device) +[![Fiscal Contributors](https://opencollective.com/meshtastic/tiers/badge.svg)](https://opencollective.com/meshtastic/tiers/badge.svg) ## This repository contains the device firmware used in the [Meshtastic](https://meshtastic.org) project. diff --git a/platformio.ini b/platformio.ini index 7bb2f339e..67c6ae9b3 100644 --- a/platformio.ini +++ b/platformio.ini @@ -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 = diff --git a/proto b/proto index e342be425..a578453b3 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit e342be425503cec75e0d0fc775d6cdbc04456200 +Subproject commit a578453b3c17794b61fb6cf4470ecaac8287d6d2 diff --git a/src/debug/i2cScan.h b/src/debug/i2cScan.h index 7bb5eadd5..9e7a49a62 100644 --- a/src/debug/i2cScan.h +++ b/src/debug/i2cScan.h @@ -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; } diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 6c6be7580..a4bddaf17 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -31,6 +31,7 @@ along with this program. If not, see . #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 . 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) { @@ -813,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(); @@ -867,6 +922,7 @@ void Screen::setup() // twice initially. ui.update(); ui.update(); + serialSinceMsec = millis(); // Subscribe to status updates powerStatusObserver.observe(&powerStatus->onNewStatus); @@ -897,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))) { @@ -906,6 +962,21 @@ int32_t Screen::runOnce() showingBootScreen = false; } + // 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(); diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index a394db13e..ad113e8ab 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -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"); } diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index cb5bea03e..68e53a507 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -340,7 +340,8 @@ Routing_Error perhapsEncode(MeshPacket *p) char compressed_out[Constants_DATA_PAYLOAD_LEN] = {0}; - int compressed_len = unishox2_compress_simple(original_payload, p->decoded.payload.size, compressed_out); + 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); @@ -366,11 +367,11 @@ Routing_Error perhapsEncode(MeshPacket *p) //p->decoded.which_payloadVariant = Data_payload_compressed_tag; } - if (1) { + if (0) { char decompressed_out[Constants_DATA_PAYLOAD_LEN] = {}; int decompressed_len; - decompressed_len = unishox2_decompress_simple(compressed_out, compressed_len, decompressed_out); + // decompressed_len = unishox2_decompress_simple(compressed_out, compressed_len, decompressed_out); Serial.print("Decompressed length - "); Serial.println(decompressed_len); diff --git a/src/mesh/generated/deviceonly.pb.c b/src/mesh/generated/deviceonly.pb.c index a91649052..76aba1aef 100644 --- a/src/mesh/generated/deviceonly.pb.c +++ b/src/mesh/generated/deviceonly.pb.c @@ -12,4 +12,8 @@ PB_BIND(DeviceState, DeviceState, 4) PB_BIND(ChannelFile, ChannelFile, 2) +PB_BIND(OEMStore, OEMStore, 2) + + + diff --git a/src/mesh/generated/deviceonly.pb.h b/src/mesh/generated/deviceonly.pb.h index 8250cf568..a8df04eae 100644 --- a/src/mesh/generated/deviceonly.pb.h +++ b/src/mesh/generated/deviceonly.pb.h @@ -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,40 @@ 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 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 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 OEMStore_init_default {0, 0, {0, {0}}, _ScreenFonts_MIN, ""} +#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 +109,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 +139,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" */ diff --git a/src/mesh/generated/radioconfig.pb.h b/src/mesh/generated/radioconfig.pb.h index db1a82837..b6a50bb90 100644 --- a/src/mesh/generated/radioconfig.pb.h +++ b/src/mesh/generated/radioconfig.pb.h @@ -210,7 +210,12 @@ typedef enum _RadioConfig_UserPreferences_Serial_Baud { /* TODO: REPLACE */ RadioConfig_UserPreferences_Serial_Baud_BAUD_576000 = 10, /* TODO: REPLACE */ - RadioConfig_UserPreferences_Serial_Baud_BAUD_921600 = 11 + RadioConfig_UserPreferences_Serial_Baud_BAUD_921600 = 11, + /* TODO: REPLACE */ + RadioConfig_UserPreferences_Serial_Baud_BAUD_110 = 12, + RadioConfig_UserPreferences_Serial_Baud_BAUD_300 = 13, + RadioConfig_UserPreferences_Serial_Baud_BAUD_600 = 14, + RadioConfig_UserPreferences_Serial_Baud_BAUD_1200 = 15 } RadioConfig_UserPreferences_Serial_Baud; /* Defines the device's role on the Mesh network @@ -381,8 +386,8 @@ typedef struct _RadioConfig { #define _InputEventChar_ARRAYSIZE ((InputEventChar)(InputEventChar_KEY_BACK+1)) #define _RadioConfig_UserPreferences_Serial_Baud_MIN RadioConfig_UserPreferences_Serial_Baud_BAUD_Default -#define _RadioConfig_UserPreferences_Serial_Baud_MAX RadioConfig_UserPreferences_Serial_Baud_BAUD_921600 -#define _RadioConfig_UserPreferences_Serial_Baud_ARRAYSIZE ((RadioConfig_UserPreferences_Serial_Baud)(RadioConfig_UserPreferences_Serial_Baud_BAUD_921600+1)) +#define _RadioConfig_UserPreferences_Serial_Baud_MAX RadioConfig_UserPreferences_Serial_Baud_BAUD_1200 +#define _RadioConfig_UserPreferences_Serial_Baud_ARRAYSIZE ((RadioConfig_UserPreferences_Serial_Baud)(RadioConfig_UserPreferences_Serial_Baud_BAUD_1200+1)) #define _RadioConfig_UserPreferences_Serial_Mode_MIN RadioConfig_UserPreferences_Serial_Mode_MODE_Default #define _RadioConfig_UserPreferences_Serial_Mode_MAX RadioConfig_UserPreferences_Serial_Mode_MODE_PROTO diff --git a/src/mesh/http/ContentHandler.cpp b/src/mesh/http/ContentHandler.cpp index 754360d56..ba78b4ea5 100644 --- a/src/mesh/http/ContentHandler.cpp +++ b/src/mesh/http/ContentHandler.cpp @@ -47,11 +47,9 @@ using namespace httpsserver; #include 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 // 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("\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("

Meshtastic

\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

\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. Click this in 10 seconds"); - - /* - * 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) { diff --git a/src/modules/esp32/SerialModule.cpp b/src/modules/esp32/SerialModule.cpp index 20b41c418..46f778f87 100644 --- a/src/modules/esp32/SerialModule.cpp +++ b/src/modules/esp32/SerialModule.cpp @@ -93,6 +93,18 @@ int32_t SerialModule::runOnce() if (radioConfig.preferences.serial_module_baud == RadioConfig_UserPreferences_Serial_Baud_BAUD_Default) { baud = 38400; + + } else if (radioConfig.preferences.serial_module_baud == RadioConfig_UserPreferences_Serial_Baud_BAUD_110) { + baud = 110; + + } else if (radioConfig.preferences.serial_module_baud == RadioConfig_UserPreferences_Serial_Baud_BAUD_300) { + baud = 300; + + } else if (radioConfig.preferences.serial_module_baud == RadioConfig_UserPreferences_Serial_Baud_BAUD_600) { + baud = 600; + + } else if (radioConfig.preferences.serial_module_baud == RadioConfig_UserPreferences_Serial_Baud_BAUD_1200) { + baud = 1200; } else if (radioConfig.preferences.serial_module_baud == RadioConfig_UserPreferences_Serial_Baud_BAUD_2400) { baud = 2400; diff --git a/version.properties b/version.properties index 73fb57178..d46454914 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 1 minor = 3 -build = 7 +build = 8