diff --git a/bin/build-all.sh b/bin/build-all.sh index 9f0888f03..ab779e187 100755 --- a/bin/build-all.sh +++ b/bin/build-all.sh @@ -9,7 +9,7 @@ COUNTRIES="US EU433 EU865 CN JP ANZ KR" #COUNTRIES=CN BOARDS_ESP32="tlora-v2 tlora-v1 tlora-v2-1-1.6 tbeam heltec tbeam0.7" -# BOARDS_ESP32=tbeam +#BOARDS_ESP32=tbeam # FIXME note nrf52840dk build is for some reason only generating a BIN file but not a HEX file nrf52840dk-geeksville is fine BOARDS_NRF52="lora-relay-v1" @@ -87,8 +87,12 @@ platformio lib update do_boards "$BOARDS_ESP32" "false" do_boards "$BOARDS_NRF52" "true" +echo "Building SPIFFS for ESP32 targets" +pio run --environment tbeam -t buildfs +cp .pio/build/tbeam/spiffs.bin $OUTDIR/bins/universal/spiffs-$VERSION.bin + # keep the bins in archive also -cp $OUTDIR/bins/firmware* $OUTDIR/elfs/firmware* $OUTDIR/bins/universal/firmware* $OUTDIR/elfs/universal/firmware* $ARCHIVEDIR +cp $OUTDIR/bins/firmware* $OUTDIR/bins/universal/spiffs* $OUTDIR/elfs/firmware* $OUTDIR/bins/universal/firmware* $OUTDIR/elfs/universal/firmware* $ARCHIVEDIR echo Updating android bins $OUTDIR/forandroid rm -rf $OUTDIR/forandroid @@ -109,6 +113,6 @@ XML echo Generating $ARCHIVEDIR/firmware-$VERSION.zip rm -f $ARCHIVEDIR/firmware-$VERSION.zip -zip --junk-paths $ARCHIVEDIR/firmware-$VERSION.zip $OUTDIR/bins/firmware-*-$VERSION.* images/system-info.bin bin/device-install.sh bin/device-update.sh +zip --junk-paths $ARCHIVEDIR/firmware-$VERSION.zip $ARCHIVEDIR/spiffs-$VERSION.bin $OUTDIR/bins/firmware-*-$VERSION.* images/system-info.bin bin/device-install.sh bin/device-update.sh echo BUILT ALL diff --git a/bin/device-install.sh b/bin/device-install.sh index fb374d091..3d5f27af8 100755 --- a/bin/device-install.sh +++ b/bin/device-install.sh @@ -1,5 +1,7 @@ #!/bin/sh +set -e + # Usage info show_help() { cat << EOF @@ -36,6 +38,7 @@ if [ -f "${FILENAME}" ]; then echo "Trying to flash ${FILENAME}, but first erasing and writing system information" esptool.py --baud 921600 erase_flash esptool.py --baud 921600 write_flash 0x1000 system-info.bin + esptool.py --baud 921600 write_flash 0x00390000 spiffs-*.bin esptool.py --baud 921600 write_flash 0x10000 ${FILENAME} else echo "Invalid file: ${FILENAME}" diff --git a/bin/version.sh b/bin/version.sh index 8a7fb3ca3..2e7677737 100644 --- a/bin/version.sh +++ b/bin/version.sh @@ -1,3 +1,3 @@ -export VERSION=1.1.8 \ No newline at end of file +export VERSION=1.1.9 \ No newline at end of file diff --git a/docs/software/device-api.md b/docs/software/device-api.md index 031b586a2..cdf9e1368 100644 --- a/docs/software/device-api.md +++ b/docs/software/device-api.md @@ -111,6 +111,7 @@ Characteristics | e272ebac-d463-4b98-bc84-5cc1a39ee517 | write | data, variable sized, recommended 512 bytes, write one for each block of file | | 4826129c-c22a-43a3-b066-ce8f0d5bacc6 | write | crc32, write last - writing this will complete the OTA operation, now you can read result | | 5e134862-7411-4424-ac4a-210937432c77 | read,notify | result code, readable but will notify when the OTA operation completes | +| 5e134862-7411-4424-ac4a-210937432c67 | write | sets the region for programming, currently only 0 (app) or 100 (spiffs) are defined, if not set app is assumed | | GATT_UUID_SW_VERSION_STR/0x2a28 | read | We also implement these standard GATT entries because SW update probably needs them: | | GATT_UUID_MANU_NAME/0x2a29 | read | | | GATT_UUID_HW_VERSION_STR/0x2a27 | read | | diff --git a/platformio.ini b/platformio.ini index c33784cfe..4f73d1955 100644 --- a/platformio.ini +++ b/platformio.ini @@ -31,6 +31,7 @@ build_flags = -Wno-missing-field-initializers -Isrc -Isrc/mesh -Isrc/gps -Ilib/n -DAPP_VERSION=${sysenv.APP_VERSION} -DHW_VERSION=${sysenv.HW_VERSION} -DUSE_THREAD_NAMES + -DTINYGPSPLUS_OPTION_NO_CUSTOM_FIELDS ; leave this commented out to avoid breaking Windows ;upload_port = /dev/ttyUSB0 @@ -64,7 +65,7 @@ lib_deps = https://github.com/meshtastic/arduino-fsm.git#2f106146071fc7bc620e1e8d4b88dc4e0266ce39 https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git#31015a55e630a2df77d9d714669c621a5bf355ad https://github.com/meshtastic/RadioLib.git#8657380241bce681c33aab46598bbf13b11f876c - https://github.com/meshtastic/TinyGPSPlus.git + https://github.com/meshtastic/TinyGPSPlus.git#9c1d584d2469523381e077b0b9c1bf868d6c0206 https://github.com/meshtastic/AXP202X_Library.git#8404abb6d4b486748636bc6ad72d2a47baaf5460 Wire ; explicitly needed here because the AXP202 library forgets to add it SPI diff --git a/src/FSCommon.cpp b/src/FSCommon.cpp new file mode 100644 index 000000000..2ce7f0bbe --- /dev/null +++ b/src/FSCommon.cpp @@ -0,0 +1,21 @@ +#include "FSCommon.h" + +void fsInit() +{ +#ifdef FS + if (!FSBegin()) + { + DEBUG_MSG("ERROR filesystem mount Failed\n"); + assert(0); // FIXME - report failure to phone + } + + DEBUG_MSG("Filesystem files:\n"); + File dir = FS.open("/"); + File f = dir.openNextFile(); + while (f) { + DEBUG_MSG(" %s\n", f.name()); + f.close(); + f = dir.openNextFile(); + } +#endif +} diff --git a/src/FSCommon.h b/src/FSCommon.h new file mode 100644 index 000000000..a1adb952e --- /dev/null +++ b/src/FSCommon.h @@ -0,0 +1,29 @@ +#pragma once + +#include "configuration.h" + +// Cross platform filesystem API + +#ifdef PORTDUINO +// Portduino version +#include "PortduinoFS.h" +#define FS PortduinoFS +#define FSBegin() true +#define FILE_O_WRITE "w" +#define FILE_O_READ "r" +#elif !defined(NO_ESP32) +// ESP32 version +#include "SPIFFS.h" +#define FS SPIFFS +#define FSBegin() FS.begin(true) +#define FILE_O_WRITE "w" +#define FILE_O_READ "r" +#else +// NRF52 version +#include "InternalFileSystem.h" +#define FS InternalFS +#define FSBegin() FS.begin() +using namespace Adafruit_LittleFS_Namespace; +#endif + +void fsInit(); \ No newline at end of file diff --git a/src/esp32/BluetoothSoftwareUpdate.cpp b/src/esp32/BluetoothSoftwareUpdate.cpp index 12e30d1ce..03e156b0b 100644 --- a/src/esp32/BluetoothSoftwareUpdate.cpp +++ b/src/esp32/BluetoothSoftwareUpdate.cpp @@ -6,6 +6,7 @@ #include "RadioLibInterface.h" #include "configuration.h" #include "nimble/BluetoothUtil.h" +#include "NodeDB.h" #include #include @@ -16,6 +17,8 @@ static CRC32 crc; static uint32_t rebootAtMsec = 0; // If not zero we will reboot at this time (used to reboot shortly after the update completes) static uint32_t updateExpectedSize, updateActualSize; +static uint8_t update_result; +static uint8_t update_region; static concurrency::Lock *updateLock; @@ -32,8 +35,8 @@ int update_size_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_ crc.reset(); if (Update.isRunning()) Update.abort(); - bool canBegin = Update.begin(updateExpectedSize); - DEBUG_MSG("Setting update size %u, result %d\n", updateExpectedSize, canBegin); + bool canBegin = Update.begin(updateExpectedSize, update_region); + DEBUG_MSG("Setting region %d update size %u, result %d\n", update_region, updateExpectedSize, canBegin); if (!canBegin) { // Indicate failure by forcing the size to 0 (client will read it back) updateExpectedSize = 0; @@ -72,13 +75,11 @@ int update_data_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_ crc.update(data, len); Update.write(data, len); updateActualSize += len; - powerFSM.trigger(EVENT_CONTACT_FROM_PHONE); + powerFSM.trigger(EVENT_CONTACT_FROM_PHONE); return 0; } -static uint8_t update_result; - /// Handle writes to crc32 int update_crc32_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) { @@ -100,8 +101,14 @@ int update_crc32_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble result = 0xe0; // FIXME, use real error codes } else { if (Update.end()) { - DEBUG_MSG("OTA done, rebooting in 5 seconds!\n"); - rebootAtMsec = millis() + 5000; + if (update_region == U_SPIFFS) { + DEBUG_MSG("SPIFFS updated!\n"); + nodeDB.saveToDisk(); // Since we just wiped spiffs, we need to save our current state + } + else { + DEBUG_MSG("Appload updated, rebooting in 5 seconds!\n"); + rebootAtMsec = millis() + 5000; + } } else { DEBUG_MSG("Error Occurred. Error #: %d\n", Update.getError()); } @@ -125,6 +132,11 @@ int update_result_callback(uint16_t conn_handle, uint16_t attr_handle, struct bl return chr_readwrite8(&update_result, sizeof(update_result), ctxt); } +int update_region_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) +{ + return chr_readwrite8(&update_region, sizeof(update_region), ctxt); +} + void bluetoothRebootCheck() { if (rebootAtMsec && millis() > rebootAtMsec) { diff --git a/src/esp32/BluetoothSoftwareUpdate.h b/src/esp32/BluetoothSoftwareUpdate.h index c7a412d69..f5e1a1ded 100644 --- a/src/esp32/BluetoothSoftwareUpdate.h +++ b/src/esp32/BluetoothSoftwareUpdate.h @@ -14,10 +14,11 @@ int update_size_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_ int update_data_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); int update_result_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); int update_crc32_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); +int update_region_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); extern const struct ble_gatt_svc_def gatt_update_svcs[]; -extern const ble_uuid128_t update_result_uuid; +extern const ble_uuid128_t update_result_uuid, update_region_uuid; extern int16_t updateResultHandle; diff --git a/src/esp32/NimbleSoftwareUpdate.c b/src/esp32/NimbleSoftwareUpdate.c index e02cd4a9d..956fdf53f 100644 --- a/src/esp32/NimbleSoftwareUpdate.c +++ b/src/esp32/NimbleSoftwareUpdate.c @@ -23,6 +23,10 @@ const ble_uuid128_t update_crc32_uuid = const ble_uuid128_t update_result_uuid = BLE_UUID128_INIT(0x77, 0x2c, 0x43, 0x37, 0x09, 0x21, 0x4a, 0xac, 0x24, 0x44, 0x11, 0x74, 0x62, 0x48, 0x13, 0x5e); +// "5e134862-7411-4424-ac4a-210937432c67" write +const ble_uuid128_t update_region_uuid = + BLE_UUID128_INIT(0x67, 0x2c, 0x43, 0x37, 0x09, 0x21, 0x4a, 0xac, 0x24, 0x44, 0x11, 0x74, 0x62, 0x48, 0x13, 0x5e); + const struct ble_gatt_svc_def gatt_update_svcs[] = { { /*** Service: Security test. */ @@ -47,9 +51,14 @@ const struct ble_gatt_svc_def gatt_update_svcs[] = { }, { .uuid = &update_result_uuid.u, - .access_cb = update_size_callback, + .access_cb = update_result_callback, .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_AUTHEN | BLE_GATT_CHR_F_NOTIFY, }, + { + .uuid = &update_region_uuid.u, + .access_cb = update_region_callback, + .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_AUTHEN, + }, { 0, /* No more characteristics in this service. */ }}, diff --git a/src/main.cpp b/src/main.cpp index 4c0af7f7b..78c1bee16 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,6 +11,7 @@ // #include "rom/rtc.h" #include "DSRRouter.h" // #include "debug.h" +#include "FSCommon.h" #include "RTC.h" #include "SPILock.h" #include "concurrency/OSThread.h" @@ -300,6 +301,8 @@ void setup() ledPeriodic = new Periodic("Blink", ledBlinker); + fsInit(); + router = new DSRRouter(); #ifdef I2C_SDA diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 61be815ec..517845b9b 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -16,6 +16,7 @@ #include "error.h" #include "mesh-pb-constants.h" #include "meshwifi/meshwifi.h" +#include "FSCommon.h" #include #include @@ -35,27 +36,7 @@ DeviceState versions used to be defined in the .proto file but really only this #define DEVICESTATE_CUR_VER 11 #define DEVICESTATE_MIN_VER DEVICESTATE_CUR_VER -#ifdef PORTDUINO -// Portduino version -#include "PortduinoFS.h" -#define FS PortduinoFS -#define FSBegin() true -#define FILE_O_WRITE "w" -#define FILE_O_READ "r" -#elif !defined(NO_ESP32) -// ESP32 version -#include "SPIFFS.h" -#define FS SPIFFS -#define FSBegin() FS.begin(true) -#define FILE_O_WRITE "w" -#define FILE_O_READ "r" -#else -// NRF52 version -#include "InternalFileSystem.h" -#define FS InternalFS -#define FSBegin() FS.begin() -using namespace Adafruit_LittleFS_Namespace; -#endif + // FIXME - move this somewhere else extern void getMacAddr(uint8_t *dmac); @@ -210,12 +191,6 @@ void NodeDB::init() { installDefaultDeviceState(); - if (!FSBegin()) // FIXME - do this in main? - { - DEBUG_MSG("ERROR filesystem mount Failed\n"); - assert(0); // FIXME - report failure to phone - } - // saveToDisk(); loadFromDisk(); // saveToDisk(); diff --git a/src/nimble/BluetoothUtil.cpp b/src/nimble/BluetoothUtil.cpp index 8009f5d22..8a0dd779b 100644 --- a/src/nimble/BluetoothUtil.cpp +++ b/src/nimble/BluetoothUtil.cpp @@ -392,6 +392,7 @@ void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg) } } + /** * A helper function that implements simple read and write handling for a uint32_t * @@ -415,6 +416,7 @@ int chr_readwrite32le(uint32_t *v, struct ble_gatt_access_ctxt *ctxt) if (len < sizeof(le)) { DEBUG_MSG("Error: wrongsized write32\n"); *v = 0; + return BLE_ATT_ERR_UNLIKELY; } else { *v = get_le32(le); DEBUG_MSG("BLE writing a uint32\n"); @@ -441,8 +443,10 @@ int chr_readwrite8(uint8_t *v, size_t vlen, struct ble_gatt_access_ctxt *ctxt) auto rc = ble_hs_mbuf_to_flat(ctxt->om, v, vlen, &len); assert(rc == 0); - if (len < vlen) + if (len < vlen) { DEBUG_MSG("Error: wrongsized write\n"); + return BLE_ATT_ERR_UNLIKELY; + } else { DEBUG_MSG("BLE writing bytes\n"); }