diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 000000000..e44b86089 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,11 @@ +# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.162.0/containers/ubuntu/.devcontainer/base.Dockerfile + +# [Choice] Ubuntu version: bionic, focal +ARG VARIANT="focal" +FROM mcr.microsoft.com/vscode/devcontainers/base:0-${VARIANT} + +# [Optional] Uncomment this section to install additional OS packages. +RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ + && apt-get -y install python3-distutils python3-pip +RUN pip3 install platformio meshtastic adafruit-nrfutil +RUN wget https://github.com/protocolbuffers/protobuf/releases/download/v3.15.8/protoc-3.15.8-linux-x86_64.zip -O /tmp/protoc.zip && cd /tmp && unzip protoc.zip && chmod a+x bin/protoc && cp bin/protoc /usr/local/bin diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..e0a284e88 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,32 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.162.0/containers/ubuntu +{ + "name": "Ubuntu", + "build": { + "dockerfile": "Dockerfile", + // Update 'VARIANT' to pick an Ubuntu version: focal, bionic + "args": { "VARIANT": "focal" } + }, + + // Set *default* container specific settings.json values on container create. + "settings": { + "terminal.integrated.shell.linux": "/bin/bash" + }, + + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "platformio.platformio-ide", + "xaver.clang-format" + ], + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "uname -a", + + // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. + "remoteUser": "vscode", + + "postCreateCommand": "git submodule update --init" +} \ No newline at end of file diff --git a/.github/actions/initbuild/action.yml b/.github/actions/initbuild/action.yml index db49b31ad..b852d0a6c 100644 --- a/.github/actions/initbuild/action.yml +++ b/.github/actions/initbuild/action.yml @@ -24,12 +24,13 @@ runs: python -m pip install --upgrade pip pip install -U platformio meshtastic adafruit-nrfutil - - name: Cache platformio - uses: actions/cache@v1 - id: cache-platformio # needed in if test - with: - path: ~/.platformio - key: ${{ runner.os }}-platformio + # Don't cache for now because I want to be lazy with portuino updates githashes + # - name: Cache platformio + # uses: actions/cache@v1 + # id: cache-platformio # needed in if test + # with: + # path: ~/.platformio + # key: ${{ runner.os }}-platformio - name: Upgrade platformio run: | diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1087daacf..0425f13fa 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -36,6 +36,10 @@ jobs: path: ~/.cache/pip key: ${{ runner.os }}-pip + #- name: Install linux apt packages + # run: | + # sudo apt-get install -y libgpiod-dev + - name: Upgrade python tools # We actually want to run this every time # if: steps.cache-pip.outputs.cache-hit != 'true' @@ -43,17 +47,30 @@ jobs: python -m pip install --upgrade pip pip install -U platformio meshtastic adafruit-nrfutil - - name: Cache platformio - uses: actions/cache@v1 - id: cache-platformio # needed in if test - with: - path: ~/.platformio - key: ${{ runner.os }}-platformio + # - name: Cache platformio + # uses: actions/cache@v1 + # id: cache-platformio # needed in if test + # with: + # path: ~/.platformio + # key: ${{ runner.os }}-platformio - name: Upgrade platformio run: | pio upgrade + - name: Pull web ui + uses: dsaltares/fetch-gh-release-asset@master + with: + repo: "meshtastic/meshtastic-web" + file: "build.tar" + target: "build.tar" + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Unpack web ui + run: | + tar -xf build.tar -C data/static + rm build.tar + # We now run integration test before other build steps (to quickly see runtime failures) - name: Build for native run: platformio run -e native @@ -74,9 +91,16 @@ jobs: - name: Build everything run: bin/build-all.sh - - name: Store release zip as an artifact + - name: Store binaries as an artifact uses: actions/upload-artifact@v2 with: name: built path: release/archive/firmware-*.zip retention-days: 30 + + - name: Store debugging elf files as an artifact + uses: actions/upload-artifact@v2 + with: + name: debug-elfs + path: release/archive/elfs-*.zip + retention-days: 7 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7b801d583..7e4e259a6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,7 +9,7 @@ on: branches: - "!*" tags: - - "v*" + - "v1*" jobs: release-build: @@ -47,9 +47,22 @@ jobs: run: | pio upgrade + - name: Pull web ui + uses: dsaltares/fetch-gh-release-asset@master + with: + repo: "meshtastic/meshtastic-web" + file: "build.tar" + target: "build.tar" + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Unpack web ui + run: | + tar -xf build.tar -C data/static + rm build.tar + # Will be available in steps.version.outputs.version - name: Get version string - run: echo "::set-output name=version::$(./bin/buildinfo.py)" + run: echo "::set-output name=version::$(./bin/buildinfo.py long)" id: version - name: Build everything @@ -69,7 +82,7 @@ jobs: env: GITHUB_TOKEN: ${{ github.token }} - - name: Add artifact to release + - name: Add bins to release uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ github.token }} @@ -77,4 +90,14 @@ jobs: upload_url: ${{ steps.create_release.outputs.upload_url }} asset_path: release/archive/firmware-${{ steps.version.outputs.version }}.zip asset_name: firmware-${{ steps.version.outputs.version }}.zip - asset_content_type: application/zip \ No newline at end of file + asset_content_type: application/zip + + - name: Add debug elfs to release + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ github.token }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: release/archive/elfs-${{ steps.version.outputs.version }}.zip + asset_name: debug-elfs-${{ steps.version.outputs.version }}.zip + asset_content_type: application/zip \ No newline at end of file diff --git a/.gitignore b/.gitignore index 67688a0b4..eeb1bcb09 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,8 @@ main/credentials.h !.vscode/extensions.json *.code-workspace +.idea/workspace.xml + .DS_Store Thumbs.db .autotools @@ -19,4 +21,5 @@ Thumbs.db nanopb* flash.uf2 cmake-build* -__pycache__ \ No newline at end of file +__pycache__ + diff --git a/.idea/workspace.xml b/.idea/workspace.xml deleted file mode 100644 index 826eaac58..000000000 --- a/.idea/workspace.xml +++ /dev/null @@ -1,162 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1615788661896 - - - - - - - - - - - - - file://$PROJECT_DIR$/src/mesh/wifi/WiFiServerAPI.cpp - 53 - - - file://$PROJECT_DIR$/src/mesh/wifi/WiFiServerAPI.cpp - 37 - - - file://$PROJECT_DIR$/src/mqtt/MQTT.cpp - 166 - - - file://$PROJECT_DIR$/.pio/libdeps/native/PubSubClient/src/PubSubClient.cpp - 468 - - - file://$PROJECT_DIR$/src/mesh/mesh-pb-constants.cpp - 20 - - - - - - - - - - - - -
"); - res->println(""); - res->println(""); - res->println(""); - - return; - } - - res->println("

Upload new file

"); - res->println("

This form allows you to upload files. Keep your filenames small and files under 200k.

"); - res->println("
"); - res->println("file:
"); - res->println(""); - res->println("
"); - - res->println("

All Files

"); - - File root = SPIFFS.open("/"); - if (root.isDirectory()) { - res->println(""); - - res->println(""); - res->println(""); - res->println(""); - res->println(""); - res->println(""); - res->println(""); - - File file = root.openNextFile(); - while (file) { - String filePath = String(file.name()); - if (filePath.indexOf("/static") == 0) { - res->println(""); - res->println(""); - res->println(""); - res->println(""); - res->println(""); - res->println(""); - } - - file = root.openNextFile(); - } - res->println("
File"); - res->println("Size"); - res->println("Actions"); - res->println("
"); - - if (String(file.name()).substring(1).endsWith(".gz")) { - String modifiedFile = String(file.name()).substring(1); - modifiedFile.remove((modifiedFile.length() - 3), 3); - res->print("" + String(file.name()).substring(1) + ""); - } else { - res->print("" + String(file.name()).substring(1) + - ""); - } - res->println(""); - res->print(String(file.size())); - res->println(""); - res->print("Delete "); - res->println(""); - if (!String(file.name()).substring(1).endsWith(".gz")) { - res->print("Edit"); - } - res->println("
"); - - res->print("
"); - // res->print("Total : " + String(SPIFFS.totalBytes()) + " Bytes
"); - res->print("Used : " + String(SPIFFS.usedBytes()) + " Bytes
"); - res->print("Free : " + String(SPIFFS.totalBytes() - SPIFFS.usedBytes()) + " Bytes
"); - } -} - void handleStatic(HTTPRequest *req, HTTPResponse *res) { // Get access to the parameters @@ -634,35 +336,33 @@ void handleStatic(HTTPRequest *req, HTTPResponse *res) std::string filename = "/static/" + parameter1; std::string filenameGzip = "/static/" + parameter1 + ".gz"; - if (!SPIFFS.exists(filename.c_str()) && !SPIFFS.exists(filenameGzip.c_str())) { - // Send "404 Not Found" as response, as the file doesn't seem to exist - res->setStatusCode(404); - res->setStatusText("Not found"); - res->println("404 Not Found"); - res->printf("

File not found: %s

\n", filename.c_str()); - return; - } // Try to open the file from SPIFFS File file; + bool has_set_content_type = false; + if (SPIFFS.exists(filename.c_str())) { file = SPIFFS.open(filename.c_str()); if (!file.available()) { DEBUG_MSG("File not available - %s\n", filename.c_str()); } - } else if (SPIFFS.exists(filenameGzip.c_str())) { file = SPIFFS.open(filenameGzip.c_str()); res->setHeader("Content-Encoding", "gzip"); if (!file.available()) { DEBUG_MSG("File not available\n"); } + } else { + has_set_content_type = true; + filenameGzip = "/static/index.html.gz"; + file = SPIFFS.open(filenameGzip.c_str()); + res->setHeader("Content-Encoding", "gzip"); + res->setHeader("Content-Type", "text/html"); } res->setHeader("Content-Length", httpsserver::intToString(file.size())); - bool has_set_content_type = false; // Content-Type is guessed using the definition of the contentTypes-table defined above int cTypeIdx = 0; do { @@ -949,30 +649,6 @@ void handleReport(HTTPRequest *req, HTTPResponse *res) res->println("}"); } -// -------- - -void handle404(HTTPRequest *req, HTTPResponse *res) -{ - - // Discard request body, if we received any - // We do this, as this is the default node and may also server POST/PUT requests - req->discardRequestBody(); - - // Set the response status - res->setStatusCode(404); - res->setStatusText("Not Found"); - - // Set content type of the response - res->setHeader("Content-Type", "text/html"); - - // Write a tiny HTTP page - res->println(""); - res->println(""); - res->println("Not Found"); - res->println("

404 Not Found

The requested resource was not found on this server.

"); - res->println(""); -} - /* This supports the Apple Captive Network Assistant (CNA) Portal */ diff --git a/src/mesh/http/ContentHandler.h b/src/mesh/http/ContentHandler.h index 8e22faefc..779058d6b 100644 --- a/src/mesh/http/ContentHandler.h +++ b/src/mesh/http/ContentHandler.h @@ -5,25 +5,18 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer); // Declare some handler functions for the various URLs on the server void handleAPIv1FromRadio(HTTPRequest *req, HTTPResponse *res); void handleAPIv1ToRadio(HTTPRequest *req, HTTPResponse *res); -void handleStyleCSS(HTTPRequest *req, HTTPResponse *res); void handleHotspot(HTTPRequest *req, HTTPResponse *res); -void handleRoot(HTTPRequest *req, HTTPResponse *res); -void handleStaticBrowse(HTTPRequest *req, HTTPResponse *res); -void handleStaticPost(HTTPRequest *req, HTTPResponse *res); void handleStatic(HTTPRequest *req, HTTPResponse *res); void handleRestart(HTTPRequest *req, HTTPResponse *res); -void handle404(HTTPRequest *req, HTTPResponse *res); void handleFormUpload(HTTPRequest *req, HTTPResponse *res); void handleScanNetworks(HTTPRequest *req, HTTPResponse *res); void handleSpiffsBrowseStatic(HTTPRequest *req, HTTPResponse *res); void handleSpiffsDeleteStatic(HTTPRequest *req, HTTPResponse *res); void handleBlinkLED(HTTPRequest *req, HTTPResponse *res); void handleReport(HTTPRequest *req, HTTPResponse *res); -void handleFavicon(HTTPRequest *req, HTTPResponse *res); void middlewareSpeedUp240(HTTPRequest *req, HTTPResponse *res, std::function next); void middlewareSpeedUp160(HTTPRequest *req, HTTPResponse *res, std::function next); -void middlewareSession(HTTPRequest *req, HTTPResponse *res, std::function next); uint32_t getTimeSpeedUp(); void setTimeSpeedUp(); @@ -40,7 +33,9 @@ class HttpAPI : public PhoneAPI // Nothing here yet protected: - // Nothing here yet + + /// Check the current underlying physical link to see if the client is currently connected + virtual bool checkIsConnected() { return true; } // FIXME, be smarter about this }; diff --git a/src/mesh/http/ContentStatic.h b/src/mesh/http/ContentStatic.h deleted file mode 100644 index 324276476..000000000 --- a/src/mesh/http/ContentStatic.h +++ /dev/null @@ -1,119 +0,0 @@ -#include -#include - -/* - This file contains static content. -*/ - -// Length of the binary data -const int FAVICON_LENGTH = 2238; - -// Binary data for the favicon -const byte FAVICON_DATA[] = { - 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x20, 0x20, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0xA8, 0x08, 0x00, 0x00, 0x16, 0x00, 0x00, - 0x00, 0x28, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x84, - 0xDC, 0x3D, 0x00, 0x84, 0xDC, 0x3C, 0x00, 0x85, 0xDC, 0x3F, 0x00, 0x86, 0xDD, 0x40, 0x00, 0x83, 0xDC, 0x3C, 0x00, 0x85, 0xDC, - 0x3E, 0x00, 0x82, 0xDC, 0x3A, 0x00, 0x8B, 0xDE, 0x49, 0x00, 0x84, 0xDB, 0x3E, 0x00, 0x82, 0xD9, 0x3C, 0x00, 0x89, 0xDD, 0x45, - 0x00, 0x83, 0xDB, 0x3C, 0x00, 0x83, 0xD8, 0x3D, 0x00, 0x81, 0xD8, 0x3A, 0x00, 0x8D, 0xE0, 0x49, 0x00, 0x88, 0xE4, 0x3F, 0x00, - 0x89, 0xE9, 0x3E, 0x00, 0x84, 0xD8, 0x40, 0x00, 0x85, 0xDF, 0x3C, 0x00, 0x8E, 0xF2, 0x40, 0x00, 0x8D, 0xF6, 0x3D, 0x00, 0x90, - 0xEA, 0x49, 0x00, 0x82, 0xD5, 0x3E, 0x00, 0x78, 0xC1, 0x3A, 0x00, 0x90, 0xE9, 0x4A, 0x00, 0x8E, 0xF5, 0x3D, 0x00, 0x84, 0xDD, - 0x3D, 0x00, 0x91, 0xF7, 0x43, 0x00, 0x87, 0xE5, 0x3D, 0x00, 0x6C, 0xA2, 0x38, 0x00, 0x53, 0x65, 0x31, 0x00, 0x41, 0x39, 0x2E, - 0x00, 0x3A, 0x27, 0x2B, 0x00, 0x34, 0x1A, 0x2A, 0x00, 0x41, 0x38, 0x2E, 0x00, 0x82, 0xD8, 0x3D, 0x00, 0x88, 0xE7, 0x3D, 0x00, - 0x8E, 0xF3, 0x41, 0x00, 0x69, 0x95, 0x39, 0x00, 0x3E, 0x33, 0x2C, 0x00, 0x31, 0x11, 0x29, 0x00, 0x2E, 0x0A, 0x29, 0x00, 0x2D, - 0x0B, 0x27, 0x00, 0x30, 0x10, 0x29, 0x00, 0x34, 0x18, 0x2A, 0x00, 0x3E, 0x31, 0x2C, 0x00, 0x68, 0x95, 0x39, 0x00, 0x88, 0xE7, - 0x3E, 0x00, 0x82, 0xD7, 0x3C, 0x00, 0x84, 0xDD, 0x3C, 0x00, 0x8B, 0xEE, 0x3E, 0x00, 0x85, 0xDF, 0x3D, 0x00, 0x47, 0x48, 0x2E, - 0x00, 0x30, 0x0F, 0x29, 0x00, 0x31, 0x13, 0x29, 0x00, 0x48, 0x4D, 0x2E, 0x00, 0x61, 0x7F, 0x39, 0x00, 0x6A, 0x9C, 0x38, 0x00, - 0x75, 0xB8, 0x39, 0x00, 0x85, 0xDE, 0x3D, 0x00, 0x8C, 0xEF, 0x3E, 0x00, 0x89, 0xDE, 0x44, 0x00, 0x80, 0xD1, 0x3C, 0x00, 0x3A, - 0x28, 0x2C, 0x00, 0x32, 0x16, 0x2A, 0x00, 0x33, 0x17, 0x2A, 0x00, 0x4B, 0x50, 0x30, 0x00, 0x76, 0xBA, 0x3A, 0x00, 0x8A, 0xEF, - 0x3C, 0x00, 0x9A, 0xFE, 0x4D, 0x00, 0x95, 0xFF, 0x43, 0x00, 0x93, 0xFF, 0x40, 0x00, 0x4B, 0x52, 0x30, 0x00, 0x7E, 0xCE, 0x3C, - 0x00, 0x87, 0xD9, 0x44, 0x00, 0x34, 0x1B, 0x2A, 0x00, 0x65, 0x90, 0x36, 0x00, 0x8E, 0xF6, 0x3D, 0x00, 0x8F, 0xF7, 0x40, 0x00, - 0x8B, 0xDD, 0x48, 0x00, 0x73, 0xB1, 0x3A, 0x00, 0x66, 0x95, 0x35, 0x00, 0x66, 0x93, 0x35, 0x00, 0x35, 0x1B, 0x2A, 0x00, 0x8D, - 0xE8, 0x45, 0x00, 0x82, 0xD9, 0x3B, 0x00, 0x72, 0xAA, 0x3C, 0x00, 0x95, 0xFD, 0x46, 0x00, 0x8D, 0xF0, 0x40, 0x00, 0x57, 0x70, - 0x32, 0x00, 0x3C, 0x2D, 0x2C, 0x00, 0x2F, 0x0D, 0x29, 0x00, 0x81, 0xD4, 0x3D, 0x00, 0x8D, 0xF1, 0x40, 0x00, 0x94, 0xFC, 0x46, - 0x00, 0x73, 0xAE, 0x3D, 0x00, 0x45, 0x44, 0x2D, 0x00, 0x94, 0xF5, 0x49, 0x00, 0x90, 0xF0, 0x45, 0x00, 0x73, 0xAF, 0x3B, 0x00, - 0x38, 0x21, 0x2C, 0x00, 0x30, 0x11, 0x29, 0x00, 0x2F, 0x0F, 0x28, 0x00, 0x72, 0xAC, 0x3B, 0x00, 0x6A, 0x93, 0x3D, 0x00, 0x2E, - 0x0D, 0x27, 0x00, 0x35, 0x1C, 0x2B, 0x00, 0x36, 0x20, 0x2A, 0x00, 0x5E, 0x77, 0x39, 0x00, 0x78, 0xBE, 0x3B, 0x00, 0x36, 0x21, - 0x2A, 0x00, 0x71, 0xAB, 0x3B, 0x00, 0x4C, 0x54, 0x30, 0x00, 0x3D, 0x31, 0x2B, 0x00, 0x82, 0xD6, 0x3D, 0x00, 0x79, 0xC5, 0x39, - 0x00, 0x9A, 0xFF, 0x4D, 0x00, 0x8A, 0xE8, 0x40, 0x00, 0x8A, 0xE7, 0x40, 0x00, 0x7A, 0xC6, 0x39, 0x00, 0x3D, 0x2E, 0x2C, 0x00, - 0x81, 0xD5, 0x3D, 0x00, 0x77, 0xBC, 0x3A, 0x00, 0x31, 0x12, 0x2A, 0x00, 0x69, 0x9B, 0x37, 0x00, 0x8E, 0xF3, 0x40, 0x00, 0x83, - 0xDC, 0x3B, 0x00, 0x8C, 0xF6, 0x3B, 0x00, 0x88, 0xD9, 0x45, 0x00, 0x86, 0xE1, 0x3D, 0x00, 0x85, 0xE0, 0x3D, 0x00, 0x7B, 0xC8, - 0x39, 0x00, 0x36, 0x1F, 0x29, 0x00, 0x55, 0x6B, 0x32, 0x00, 0x8A, 0xEE, 0x3C, 0x00, 0x48, 0x4B, 0x2E, 0x00, 0x51, 0x61, 0x31, - 0x00, 0x8C, 0xE0, 0x48, 0x00, 0x8B, 0xDE, 0x47, 0x00, 0x98, 0xEE, 0x55, 0x00, 0x5D, 0x79, 0x36, 0x00, 0x3A, 0x2A, 0x2B, 0x00, - 0x3A, 0x29, 0x2B, 0x00, 0x5C, 0x78, 0x36, 0x00, 0x60, 0x7C, 0x3A, 0x00, 0x3D, 0x30, 0x2C, 0x00, 0x99, 0xFD, 0x4C, 0x00, 0x66, - 0x8A, 0x3C, 0x00, 0x2D, 0x0C, 0x27, 0x00, 0x42, 0x3C, 0x2E, 0x00, 0x84, 0xDA, 0x3E, 0x00, 0x88, 0xE5, 0x3F, 0x00, 0x37, 0x22, - 0x2B, 0x00, 0x2E, 0x0B, 0x28, 0x00, 0x6A, 0x9B, 0x37, 0x00, 0x72, 0xAF, 0x3A, 0x00, 0x32, 0x15, 0x29, 0x00, 0x2A, 0x00, 0x28, - 0x00, 0x5B, 0x75, 0x35, 0x00, 0x89, 0xE8, 0x3D, 0x00, 0x78, 0xBF, 0x3A, 0x00, 0x73, 0xB4, 0x38, 0x00, 0x83, 0xDA, 0x3C, 0x00, - 0x84, 0xDE, 0x3C, 0x00, 0x85, 0xDD, 0x3E, 0x00, 0x86, 0xDE, 0x40, 0x00, 0x84, 0xDE, 0x3B, 0x00, 0x86, 0xE2, 0x3C, 0x00, 0x85, - 0xDD, 0x3F, 0x00, 0x87, 0xE2, 0x3F, 0x00, 0x87, 0xE1, 0x3E, 0x00, 0x85, 0xDE, 0x3E, 0x00, 0x89, 0xE2, 0x41, 0x00, 0x89, 0xE2, - 0x43, 0x00, 0x84, 0xDC, 0x3E, 0x00, 0x83, 0xD8, 0x3E, 0x00, 0x90, 0xF6, 0x41, 0x00, 0x2B, 0x04, 0x28, 0x00, 0x8C, 0xE3, 0x47, - 0x00, 0x8B, 0xDE, 0x48, 0x00, 0x8A, 0xDC, 0x47, 0x00, 0x8A, 0xDD, 0x47, 0x00, 0x8D, 0xDD, 0x4A, 0x00, 0x8A, 0xDE, 0x47, 0x00, - 0x8B, 0xDD, 0x49, 0x00, 0x8B, 0xE0, 0x46, 0x00, 0x9A, 0xF2, 0x55, 0x00, 0x59, 0x70, 0x35, 0x00, 0x8F, 0xDE, 0x4F, 0x00, 0x82, - 0xDC, 0x3B, 0x00, 0x82, 0xDB, 0x39, 0x00, 0x7F, 0xD7, 0x38, 0x00, 0x92, 0xF0, 0x48, 0x00, 0x33, 0x19, 0x29, 0x00, 0x87, 0xDD, - 0x42, 0x00, 0x87, 0xDD, 0x41, 0x00, 0x92, 0xEC, 0x4B, 0x00, 0x78, 0xBD, 0x3C, 0x00, 0x86, 0xDD, 0x3F, 0x00, 0x81, 0xD9, 0x39, - 0x00, 0x7B, 0xC4, 0x3C, 0x00, 0x34, 0x1A, 0x29, 0x00, 0x89, 0xDD, 0x44, 0x00, 0x86, 0xDC, 0x40, 0x00, 0x88, 0xDD, 0x44, 0x00, - 0x87, 0xDE, 0x41, 0x00, 0x99, 0xFA, 0x4F, 0x00, 0x7B, 0xC3, 0x3E, 0x00, 0x83, 0xD7, 0x3F, 0x00, 0x8B, 0xED, 0x3E, 0x00, 0x40, - 0x33, 0x2F, 0x00, 0x39, 0x27, 0x2B, 0x00, 0x81, 0xD7, 0x3B, 0x00, 0x3B, 0x2C, 0x2A, 0x00, 0x33, 0x18, 0x29, 0x00, 0x38, 0x22, - 0x2B, 0x00, 0x85, 0xDA, 0x40, 0x00, 0x89, 0xEA, 0x3D, 0x00, 0x6F, 0xA9, 0x38, 0x00, 0x70, 0xAB, 0x38, 0x00, 0x85, 0xDD, 0x3D, - 0x00, 0x88, 0xE1, 0x40, 0x00, 0x36, 0x1F, 0x2B, 0x00, 0x30, 0x13, 0x28, 0x00, 0x68, 0x9A, 0x36, 0x00, 0x90, 0xFB, 0x3F, 0x00, - 0x8A, 0xDD, 0x46, 0x00, 0x8D, 0xE9, 0x45, 0x00, 0x5A, 0x71, 0x36, 0x00, 0x27, 0x00, 0x24, 0x00, 0x73, 0x9F, 0x45, 0x00, 0x97, - 0xFE, 0x4A, 0x00, 0x86, 0xD8, 0x43, 0x00, 0x73, 0xA1, 0x45, 0x00, 0x8E, 0xDF, 0x4C, 0x00, 0x85, 0xDB, 0x40, 0x00, 0x72, 0xB5, - 0x37, 0x00, 0x95, 0xF4, 0x4B, 0x00, 0x73, 0xB6, 0x37, 0x00, 0x88, 0xE9, 0x3C, 0x00, 0x8A, 0xDB, 0x48, 0x00, 0x8C, 0xDE, 0x49, - 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x02, 0x03, 0x04, 0xAE, 0x06, 0xF1, 0x02, 0x04, 0x04, 0x02, 0xF1, 0x06, 0xAE, 0x04, 0x03, 0x02, 0x01, 0x00, 0x01, - 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0xAE, 0xC7, 0xF1, 0x02, 0x04, - 0x04, 0x02, 0xF1, 0xC7, 0xAE, 0x04, 0x03, 0x02, 0x01, 0x00, 0x01, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x02, 0x03, 0x0B, 0xAE, 0xEF, 0xF0, 0x02, 0x01, 0x01, 0x02, 0xB4, 0xEF, 0xAE, 0x0B, 0x03, 0x02, 0x01, 0x00, - 0x01, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x05, 0xEB, 0xA7, 0xD1, 0xEC, 0xED, 0x96, - 0x04, 0x04, 0x96, 0xED, 0xEE, 0xD1, 0xA7, 0xEB, 0x05, 0x04, 0x01, 0x04, 0xCA, 0x04, 0x01, 0x01, 0x01, 0xCA, 0xCA, 0xCA, 0xCA, - 0xCA, 0xCA, 0xCA, 0xCC, 0xE2, 0x8A, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE8, 0xE7, 0xE9, 0xE5, 0xBB, 0xE3, 0x8A, 0xE2, 0xCC, - 0xCA, 0xCC, 0xEA, 0xCC, 0xCA, 0xCA, 0xCA, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x08, 0xDD, 0x55, 0xDE, 0x2C, 0xDF, - 0xE0, 0xE1, 0xE1, 0xE0, 0xDF, 0x2C, 0xDE, 0x55, 0xDD, 0x08, 0x04, 0x01, 0x04, 0xCA, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0xC6, 0xD8, 0xD9, 0xAB, 0x78, 0x6A, 0x28, 0xDA, 0xDB, 0x28, 0x6A, 0x5A, 0xDC, 0xD9, 0xD8, 0xC6, - 0x01, 0x00, 0x01, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x05, 0x03, 0xD4, 0xD1, 0x31, - 0xD5, 0xD6, 0x98, 0xD7, 0xD6, 0xD5, 0x0B, 0x32, 0xD4, 0x03, 0x05, 0x04, 0x01, 0x04, 0xCA, 0x04, 0x01, 0x01, 0x01, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x05, 0xC3, 0xC2, 0xA4, 0xD0, 0xD1, 0xB3, 0xD2, 0xD3, 0xD3, 0xD2, 0x4F, 0x32, 0xD0, 0xA4, 0xC2, - 0xC3, 0x05, 0x02, 0x05, 0xB7, 0x05, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0xCB, 0xC2, 0xCC, 0x02, 0xCD, - 0x79, 0xCE, 0xCF, 0xC1, 0xC1, 0xCF, 0xCE, 0x79, 0xCD, 0x02, 0xCC, 0xC2, 0xCB, 0x03, 0xCB, 0xB3, 0xCB, 0x03, 0x03, 0x03, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x7E, 0x05, 0xC6, 0x7E, 0x00, 0xC7, 0x15, 0xC8, 0xC9, 0xC9, 0xC8, 0x15, 0xC7, 0x00, 0x7E, - 0xC6, 0x05, 0x7E, 0x04, 0x7E, 0xCA, 0x7E, 0x04, 0x04, 0x04, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0x00, 0x03, 0xC3, 0x00, - 0x05, 0x55, 0xC4, 0xC5, 0xC1, 0xC1, 0xC5, 0xC4, 0x55, 0x05, 0x00, 0xC3, 0x03, 0x00, 0xAE, 0x00, 0x3D, 0x00, 0xAE, 0xAE, 0xAE, - 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0x7E, 0xBE, 0x00, 0x05, 0xBE, 0x7E, 0xBF, 0xC0, 0x5C, 0xC1, 0xC1, 0x5C, 0xC0, 0xBF, 0x7E, - 0xBE, 0x05, 0x00, 0xBE, 0x7E, 0xBE, 0xC2, 0x06, 0xBD, 0xBD, 0xBD, 0xB3, 0xB3, 0xB3, 0xB4, 0xB5, 0xB3, 0xB3, 0xB5, 0xB6, 0xB6, - 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0x6B, 0x6B, 0xBB, 0xBA, 0xB9, 0xB8, 0xB7, 0xB6, 0xB6, 0xB5, 0xB3, 0xB5, 0xBC, 0xB4, 0xB3, 0xB3, - 0xB3, 0x02, 0x02, 0xA8, 0xA9, 0xAA, 0xA8, 0x02, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0x8F, 0xB1, 0x71, 0x2D, 0xB1, 0x9E, 0xB0, - 0xAF, 0xAE, 0xAD, 0xAC, 0xAB, 0x02, 0xA4, 0xB2, 0xAA, 0xA8, 0x02, 0x02, 0x04, 0x31, 0xA3, 0x04, 0x31, 0x82, 0x3B, 0xA3, 0xA4, - 0xA5, 0xA6, 0x82, 0xA7, 0x8E, 0x20, 0x78, 0x78, 0x20, 0x8E, 0xA7, 0x82, 0xA6, 0xA5, 0xA4, 0xA3, 0x3B, 0x82, 0x3D, 0x04, 0xA3, - 0x31, 0x04, 0x09, 0x9F, 0xA0, 0x21, 0x2C, 0xA1, 0x47, 0x52, 0x5B, 0x5A, 0xA2, 0x1C, 0x81, 0x8D, 0x8E, 0x91, 0x91, 0x8E, 0x8D, - 0x81, 0x1C, 0xA2, 0x5A, 0x5B, 0x52, 0x47, 0xA1, 0x2C, 0x21, 0xA0, 0x9F, 0x09, 0x96, 0x97, 0x16, 0x98, 0x99, 0x9A, 0x46, 0x9B, - 0x28, 0x9C, 0x6D, 0x76, 0x7D, 0x8C, 0x9D, 0x8E, 0x8E, 0x9D, 0x9E, 0x7D, 0x75, 0x6D, 0x9C, 0x65, 0x9B, 0x46, 0x39, 0x99, 0x98, - 0x16, 0x97, 0x96, 0x4F, 0x89, 0x15, 0x1F, 0x69, 0x38, 0x45, 0x8A, 0x78, 0x66, 0x6C, 0x74, 0x4A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, - 0x8B, 0x80, 0x45, 0x90, 0x66, 0x91, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x15, 0x89, 0x4F, 0x7E, 0x0D, 0x14, 0x1E, 0x29, 0x37, 0x44, - 0x14, 0x59, 0x65, 0x6B, 0x73, 0x7F, 0x80, 0x25, 0x81, 0x82, 0x25, 0x80, 0x7F, 0x83, 0x84, 0x65, 0x85, 0x4D, 0x86, 0x87, 0x29, - 0x88, 0x14, 0x0D, 0x7E, 0x05, 0x0C, 0x13, 0x1D, 0x28, 0x2C, 0x43, 0x4E, 0x72, 0x64, 0x53, 0x5A, 0x73, 0x74, 0x75, 0x1C, 0x1C, - 0x76, 0x74, 0x77, 0x78, 0x6A, 0x64, 0x79, 0x4E, 0x7A, 0x2C, 0x7B, 0x7C, 0x7D, 0x0C, 0x05, 0x04, 0x0B, 0x12, 0x1C, 0x27, 0x36, - 0x42, 0x4D, 0x5D, 0x63, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x1A, 0x1A, 0x6D, 0x6C, 0x6E, 0x53, 0x69, 0x6F, 0x5D, 0x19, 0x70, 0x36, - 0x71, 0x24, 0x12, 0x0B, 0x04, 0x03, 0x03, 0x11, 0x1B, 0x2E, 0x35, 0x41, 0x4C, 0x5E, 0x62, 0x63, 0x64, 0x65, 0x66, 0x2C, 0x5A, - 0x5A, 0x2C, 0x66, 0x65, 0x64, 0x67, 0x62, 0x5E, 0x52, 0x40, 0x65, 0x68, 0x1B, 0x11, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x25, - 0x34, 0x40, 0x4B, 0x56, 0x57, 0x58, 0x16, 0x59, 0x5A, 0x41, 0x5B, 0x5B, 0x41, 0x5A, 0x59, 0x5C, 0x5D, 0x5E, 0x5F, 0x21, 0x41, - 0x60, 0x61, 0x05, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x09, 0x24, 0x33, 0x3F, 0x2C, 0x4B, 0x4C, 0x4D, 0x4E, 0x14, 0x4F, 0x50, - 0x51, 0x51, 0x50, 0x4F, 0x14, 0x4E, 0x4D, 0x52, 0x53, 0x2C, 0x3F, 0x01, 0x54, 0x55, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x1A, - 0x23, 0x32, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x47, 0x46, 0x45, 0x44, 0x43, 0x48, 0x41, 0x40, 0x3F, - 0x49, 0x3C, 0x4A, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x30, 0x32, 0x33, 0x34, 0x35, 0x36, 0x2C, 0x37, 0x38, - 0x39, 0x3A, 0x3A, 0x39, 0x38, 0x37, 0x2C, 0x36, 0x35, 0x34, 0x3B, 0x3C, 0x30, 0x3D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1A, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2C, 0x2B, 0x2A, 0x29, 0x28, 0x2D, 0x2E, 0x13, - 0x2F, 0x30, 0x31, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x09, 0x02, 0x1B, 0x1C, 0x1D, 0x1E, - 0x1F, 0x20, 0x21, 0x21, 0x20, 0x22, 0x1E, 0x1D, 0x1C, 0x1B, 0x02, 0x09, 0x1A, 0x01, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x17, 0x16, 0x18, 0x19, 0x13, 0x12, 0x11, - 0x02, 0x01, 0x00, 0x01, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x0B, 0x0C, - 0x0D, 0x0E, 0x0F, 0x10, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x03, 0x02, 0x01, 0x00, 0x01, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, - 0x03, 0x02, 0x01, 0x00, 0x01, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/src/mesh/http/WebServer.cpp b/src/mesh/http/WebServer.cpp index 2633de529..0f3ae5cd7 100644 --- a/src/mesh/http/WebServer.cpp +++ b/src/mesh/http/WebServer.cpp @@ -5,7 +5,6 @@ #include #include - #include #include @@ -13,7 +12,6 @@ #include "esp_task_wdt.h" #endif - // Persistant Data Storage #include Preferences prefs; @@ -42,46 +40,41 @@ Preferences prefs; using namespace httpsserver; #include "mesh/http/ContentHandler.h" -SSLCert *cert; -HTTPSServer *secureServer; -HTTPServer *insecureServer; +static SSLCert *cert; +static HTTPSServer *secureServer; +static HTTPServer *insecureServer; +volatile bool isWebServerReady; +volatile bool isCertReady; - - -bool isWebServerReady = 0; -bool isCertReady = 0; - - -void handleWebResponse() +static void handleWebResponse() { - if (isWifiAvailable() == 0) { - return; - } + if (isWifiAvailable()) { - if (isWebServerReady) { - // We're going to handle the DNS responder here so it - // will be ignored by the NRF boards. - handleDNSResponse(); + if (isWebServerReady) { + // We're going to handle the DNS responder here so it + // will be ignored by the NRF boards. + handleDNSResponse(); - secureServer->loop(); - insecureServer->loop(); - } + if(secureServer) + secureServer->loop(); + insecureServer->loop(); + } - /* - Slow down the CPU if we have not received a request within the last few - seconds. - */ - - if (millis() - getTimeSpeedUp() >= (25 * 1000)) { - setCpuFrequencyMhz(80); - setTimeSpeedUp(); + /* + Slow down the CPU if we have not received a request within the last few + seconds. + */ + + if (millis() - getTimeSpeedUp() >= (25 * 1000)) { + setCpuFrequencyMhz(80); + setTimeSpeedUp(); + } } } -void taskCreateCert(void *parameter) +static void taskCreateCert(void *parameter) { - prefs.begin("MeshtasticHTTPS", false); // Delete the saved certs @@ -92,13 +85,32 @@ void taskCreateCert(void *parameter) prefs.remove("cert"); } + DEBUG_MSG("Checking if we have a previously saved SSL Certificate.\n"); + size_t pkLen = prefs.getBytesLength("PK"); size_t certLen = prefs.getBytesLength("cert"); - DEBUG_MSG("Checking if we have a previously saved SSL Certificate.\n"); - if (pkLen && certLen) { DEBUG_MSG("Existing SSL Certificate found!\n"); + + uint8_t *pkBuffer = new uint8_t[pkLen]; + prefs.getBytes("PK", pkBuffer, pkLen); + + uint8_t *certBuffer = new uint8_t[certLen]; + prefs.getBytes("cert", certBuffer, certLen); + + cert = new SSLCert(certBuffer, certLen, pkBuffer, pkLen); + + DEBUG_MSG("Retrieved Private Key: %d Bytes\n", cert->getPKLength()); + // DEBUG_MSG("Retrieved Private Key: " + String(cert->getPKLength()) + " Bytes"); + // for (int i = 0; i < cert->getPKLength(); i++) + // Serial.print(cert->getPKData()[i], HEX); + // Serial.println(); + + DEBUG_MSG("Retrieved Certificate: %d Bytes\n", cert->getCertLength()); + // for (int i = 0; i < cert->getCertLength(); i++) + // Serial.print(cert->getCertData()[i], HEX); + // Serial.println(); } else { DEBUG_MSG("Creating the certificate. This may take a while. Please wait...\n"); yield(); @@ -133,35 +145,35 @@ void taskCreateCert(void *parameter) } } - isCertReady = 1; + isCertReady = true; + + // Must delete self, can't just fall out vTaskDelete(NULL); } void createSSLCert() { + if (isWifiAvailable() && !isCertReady) { - if (isWifiAvailable() == 0) { - return; + // Create a new process just to handle creating the cert. + // This is a workaround for Bug: https://github.com/fhessel/esp32_https_server/issues/48 + // jm@casler.org (Oct 2020) + xTaskCreate(taskCreateCert, /* Task function. */ + "createCert", /* String with name of task. */ + 16384, /* Stack size in bytes. */ + NULL, /* Parameter passed as input of the task */ + 16, /* Priority of the task. */ + NULL); /* Task handle. */ + + DEBUG_MSG("Waiting for SSL Cert to be generated.\n"); + while (!isCertReady) { + DEBUG_MSG("."); + delay(1000); + yield(); + esp_task_wdt_reset(); + } + DEBUG_MSG("SSL Cert Ready!\n"); } - - // Create a new process just to handle creating the cert. - // This is a workaround for Bug: https://github.com/fhessel/esp32_https_server/issues/48 - // jm@casler.org (Oct 2020) - xTaskCreate(taskCreateCert, /* Task function. */ - "createCert", /* String with name of task. */ - 16384, /* Stack size in bytes. */ - NULL, /* Parameter passed as input of the task */ - 16, /* Priority of the task. */ - NULL); /* Task handle. */ - - DEBUG_MSG("Waiting for SSL Cert to be generated.\n"); - while (!isCertReady) { - DEBUG_MSG("."); - delay(1000); - yield(); - esp_task_wdt_reset(); - } - DEBUG_MSG("SSL Cert Ready!\n"); } WebServerThread *webServerThread; @@ -181,6 +193,8 @@ void initWebServer() { DEBUG_MSG("Initializing Web Server ...\n"); +#if 0 +// this seems to be a copypaste dup of taskCreateCert prefs.begin("MeshtasticHTTPS", false); size_t pkLen = prefs.getBytesLength("PK"); @@ -211,6 +225,7 @@ void initWebServer() } else { DEBUG_MSG("Web Server started without SSL keys! How did this happen?\n"); } +#endif // We can now use the new certificate to setup our server as usual. secureServer = new HTTPSServer(cert); @@ -218,14 +233,16 @@ void initWebServer() registerHandlers(insecureServer, secureServer); - DEBUG_MSG("Starting Web Servers...\n"); - secureServer->start(); + if(secureServer) { + DEBUG_MSG("Starting Secure Web Server...\n"); + secureServer->start(); + } + DEBUG_MSG("Starting Insecure Web Server...\n"); insecureServer->start(); - if (secureServer->isRunning() && insecureServer->isRunning()) { - DEBUG_MSG("HTTP and HTTPS Web Servers Ready! :-) \n"); - isWebServerReady = 1; + if (insecureServer->isRunning()) { + DEBUG_MSG("Web Servers Ready! :-) \n"); + isWebServerReady = true; } else { - DEBUG_MSG("HTTP and HTTPS Web Servers Failed! ;-( \n"); + DEBUG_MSG("Web Servers Failed! ;-( \n"); } } - diff --git a/src/mesh/http/WebServer.h b/src/mesh/http/WebServer.h index aacb2e00a..74b299dcf 100644 --- a/src/mesh/http/WebServer.h +++ b/src/mesh/http/WebServer.h @@ -8,10 +8,6 @@ void initWebServer(); void createSSLCert(); - -void handleWebResponse(); - - class WebServerThread : private concurrency::OSThread { diff --git a/src/mesh/http/WiFiAPClient.cpp b/src/mesh/http/WiFiAPClient.cpp index bf8ee9624..4408739dd 100644 --- a/src/mesh/http/WiFiAPClient.cpp +++ b/src/mesh/http/WiFiAPClient.cpp @@ -1,7 +1,9 @@ #include "mesh/http/WiFiAPClient.h" #include "NodeDB.h" +#include "concurrency/Periodic.h" #include "configuration.h" #include "main.h" +#include "mqtt/MQTT.h" #include "mesh/http/WebServer.h" #include "mesh/wifi/WiFiServerAPI.h" #include "target_specific.h" @@ -9,6 +11,8 @@ #include #include +using namespace concurrency; + static void WiFiEvent(WiFiEvent_t event); // DNS Server for the Captive Portal @@ -23,6 +27,47 @@ bool forcedSoftAP = 0; bool APStartupComplete = 0; +static bool needReconnect = true; // If we create our reconnector, run it once at the beginning + +// FIXME, veto light sleep if we have a TCP server running +#if 0 +class WifiSleepObserver : public Observer { +protected: + + /// Return 0 if sleep is okay + virtual int onNotify(uint32_t newValue) { + + } +}; + +static WifiSleepObserver wifiSleepObserver; +//preflightSleepObserver.observe(&preflightSleep); +#endif + +static int32_t reconnectWiFi() +{ + if (radioConfig.has_preferences && needReconnect) { + + const char *wifiName = radioConfig.preferences.wifi_ssid; + const char *wifiPsw = radioConfig.preferences.wifi_password; + + if (!*wifiPsw) // Treat empty password as no password + wifiPsw = NULL; + + if (*wifiName) { + needReconnect = false; + + DEBUG_MSG("... Reconnecting to WiFi access point"); + WiFi.mode(WIFI_MODE_STA); + WiFi.begin(wifiName, wifiPsw); + } + } + + return 30 * 1000; // every 30 seconds +} + +static Periodic *wifiReconnect; + bool isSoftAPForced() { return forcedSoftAP; @@ -32,25 +77,15 @@ bool isWifiAvailable() { // If wifi status is connected, return true regardless of the radio configuration. if (isSoftAPForced()) { - return 1; + return true; } const char *wifiName = radioConfig.preferences.wifi_ssid; - const char *wifiPsw = radioConfig.preferences.wifi_password; - // strcpy(radioConfig.preferences.wifi_ssid, "meshtastic"); - // strcpy(radioConfig.preferences.wifi_password, "meshtastic!"); - - // strcpy(radioConfig.preferences.wifi_ssid, "meshtasticAdmin"); - // strcpy(radioConfig.preferences.wifi_password, "12345678"); - - // radioConfig.preferences.wifi_ap_mode = true; - // radioConfig.preferences.wifi_ap_mode = false; - - if (*wifiName && *wifiPsw) { - return 1; + if (*wifiName) { + return true; } else { - return 0; + return false; } } @@ -75,28 +110,48 @@ void deinitWifi() } } -// Startup WiFi -void initWifi(bool forceSoftAP) +static void onNetworkConnected() { + if (!APStartupComplete) { + // Start web server + DEBUG_MSG("... Starting network services\n"); - if (forceSoftAP) { - // do nothing - // DEBUG_MSG("----- Forcing SoftAP\n"); - } else { - if (isWifiAvailable() == 0) { - return; + // start mdns + if (!MDNS.begin("Meshtastic")) { + DEBUG_MSG("Error setting up MDNS responder!\n"); + } else { + DEBUG_MSG("mDNS responder started\n"); + DEBUG_MSG("mDNS Host: Meshtastic.local\n"); + MDNS.addService("http", "tcp", 80); + MDNS.addService("https", "tcp", 443); } - } + initWebServer(); + initApiServer(); + + APStartupComplete = true; + } + + // FIXME this is kinda yucky, instead we should just have an observable for 'wifireconnected' + if(mqtt) + mqtt->reconnect(); +} + +// Startup WiFi +bool initWifi(bool forceSoftAP) +{ forcedSoftAP = forceSoftAP; - createSSLCert(); - - if (radioConfig.has_preferences || forceSoftAP) { + if ((radioConfig.has_preferences && radioConfig.preferences.wifi_ssid[0]) || forceSoftAP) { const char *wifiName = radioConfig.preferences.wifi_ssid; const char *wifiPsw = radioConfig.preferences.wifi_password; - if ((*wifiName && *wifiPsw) || forceSoftAP) { + createSSLCert(); + + if (!*wifiPsw) // Treat empty password as no password + wifiPsw = NULL; + + if (*wifiName || forceSoftAP) { if (forceSoftAP) { DEBUG_MSG("Forcing SoftAP\n"); @@ -153,33 +208,17 @@ void initWifi(bool forceSoftAP) }, WiFiEvent_t::SYSTEM_EVENT_STA_DISCONNECTED); - DEBUG_MSG("JOINING WIFI: ssid=%s\n", wifiName); - if (WiFi.begin(wifiName, wifiPsw) == WL_CONNECTED) { - DEBUG_MSG("MY IP ADDRESS: %s\n", WiFi.localIP().toString().c_str()); - } else { - DEBUG_MSG("Started Joining WIFI\n"); - } + DEBUG_MSG("JOINING WIFI soon: ssid=%s\n", wifiName); + wifiReconnect = new Periodic("WifiConnect", reconnectWiFi); } } - - if (!MDNS.begin("Meshtastic")) { - DEBUG_MSG("Error setting up MDNS responder!\n"); - - while (1) { - delay(1000); - } - } - DEBUG_MSG("mDNS responder started\n"); - DEBUG_MSG("mDNS Host: Meshtastic.local\n"); - MDNS.addService("http", "tcp", 80); - MDNS.addService("https", "tcp", 443); - - } else + return true; + } else { DEBUG_MSG("Not using WIFI\n"); + return false; + } } - - // Called by the Espressif SDK to static void WiFiEvent(WiFiEvent_t event) { @@ -193,10 +232,10 @@ static void WiFiEvent(WiFiEvent_t event) DEBUG_MSG("Completed scan for access points\n"); break; case SYSTEM_EVENT_STA_START: - DEBUG_MSG("WiFi client started\n"); + DEBUG_MSG("WiFi station started\n"); break; case SYSTEM_EVENT_STA_STOP: - DEBUG_MSG("WiFi clients stopped\n"); + DEBUG_MSG("WiFi station stopped\n"); break; case SYSTEM_EVENT_STA_CONNECTED: DEBUG_MSG("Connected to access point\n"); @@ -205,7 +244,7 @@ static void WiFiEvent(WiFiEvent_t event) DEBUG_MSG("Disconnected from WiFi access point\n"); // Event 5 - reconnectWiFi(); + needReconnect = true; break; case SYSTEM_EVENT_STA_AUTHMODE_CHANGE: DEBUG_MSG("Authentication mode of access point has changed\n"); @@ -213,18 +252,7 @@ static void WiFiEvent(WiFiEvent_t event) case SYSTEM_EVENT_STA_GOT_IP: DEBUG_MSG("Obtained IP address: \n"); Serial.println(WiFi.localIP()); - - if (!APStartupComplete) { - // Start web server - DEBUG_MSG("... Starting network services\n"); - initWebServer(); - initApiServer(); - - APStartupComplete = true; - } else { - DEBUG_MSG("... Not starting network services (They're already running)\n"); - } - + onNetworkConnected(); break; case SYSTEM_EVENT_STA_LOST_IP: DEBUG_MSG("Lost IP address and IP address is reset to 0\n"); @@ -244,18 +272,7 @@ static void WiFiEvent(WiFiEvent_t event) case SYSTEM_EVENT_AP_START: DEBUG_MSG("WiFi access point started\n"); Serial.println(WiFi.softAPIP()); - - if (!APStartupComplete) { - // Start web server - DEBUG_MSG("... Starting network services\n"); - initWebServer(); - initApiServer(); - - APStartupComplete = true; - } else { - DEBUG_MSG("... Not starting network services (They're already running)\n"); - } - + onNetworkConnected(); break; case SYSTEM_EVENT_AP_STOP: DEBUG_MSG("WiFi access point stopped\n"); @@ -302,23 +319,6 @@ void handleDNSResponse() } } -void reconnectWiFi() -{ - const char *wifiName = radioConfig.preferences.wifi_ssid; - const char *wifiPsw = radioConfig.preferences.wifi_password; - - if (radioConfig.has_preferences) { - - if (*wifiName && *wifiPsw) { - - DEBUG_MSG("... Reconnecting to WiFi access point"); - - WiFi.mode(WIFI_MODE_STA); - WiFi.begin(wifiName, wifiPsw); - } - } -} - uint8_t getWifiDisconnectReason() { return wifiDisconnectReason; diff --git a/src/mesh/http/WiFiAPClient.h b/src/mesh/http/WiFiAPClient.h index 9e2f8ad78..acbbdb19b 100644 --- a/src/mesh/http/WiFiAPClient.h +++ b/src/mesh/http/WiFiAPClient.h @@ -9,15 +9,15 @@ #include #endif -void initWifi(bool forceSoftAP); +/// @return true if wifi is now in use +bool initWifi(bool forceSoftAP); + void deinitWifi(); bool isWifiAvailable(); void handleDNSResponse(); -void reconnectWiFi(); - bool isSoftAPForced(); uint8_t getWifiDisconnectReason(); diff --git a/src/mesh/mesh-pb-constants.cpp b/src/mesh/mesh-pb-constants.cpp index eab15799a..e7ccf45a3 100644 --- a/src/mesh/mesh-pb-constants.cpp +++ b/src/mesh/mesh-pb-constants.cpp @@ -18,7 +18,7 @@ size_t pb_encode_to_bytes(uint8_t *destbuf, size_t destbufsize, const pb_msgdesc pb_ostream_t stream = pb_ostream_from_buffer(destbuf, destbufsize); if (!pb_encode(&stream, fields, src_struct)) { - DEBUG_MSG("Panic: can't encode protobuf reason='%s', reason=%s\n", PB_GET_ERROR(&stream)); + DEBUG_MSG("Panic: can't encode protobuf reason='%s'\n", PB_GET_ERROR(&stream)); assert(0); // If this asser fails it probably means you made a field too large for the max limits specified in mesh.options } else { return stream.bytes_written; @@ -30,7 +30,7 @@ bool pb_decode_from_bytes(const uint8_t *srcbuf, size_t srcbufsize, const pb_msg { pb_istream_t stream = pb_istream_from_buffer(srcbuf, srcbufsize); if (!pb_decode(&stream, fields, dest_struct)) { - DEBUG_MSG("Error: can't decode protobuf reason='%s', pb_msgdesc 0x%p, reason=%s\n", PB_GET_ERROR(&stream), fields); + DEBUG_MSG("Error: can't decode protobuf reason='%s', pb_msgdesc 0x%p\n", PB_GET_ERROR(&stream), fields); return false; } else { return true; diff --git a/src/mesh/wifi/WiFiServerAPI.cpp b/src/mesh/wifi/WiFiServerAPI.cpp index c0be8bc4a..6014f8324 100644 --- a/src/mesh/wifi/WiFiServerAPI.cpp +++ b/src/mesh/wifi/WiFiServerAPI.cpp @@ -1,5 +1,4 @@ #include "WiFiServerAPI.h" -#include "PowerFSM.h" #include "configuration.h" #include @@ -26,19 +25,6 @@ WiFiServerAPI::~WiFiServerAPI() // FIXME - delete this if the client dropps the connection! } -/// Hookable to find out when connection changes -void WiFiServerAPI::onConnectionChanged(bool connected) -{ - // FIXME - we really should be doing global reference counting to see if anyone is currently using serial or wifi and if so, - // block sleep - - if (connected) { // To prevent user confusion, turn off bluetooth while using the serial port api - powerFSM.trigger(EVENT_SERIAL_CONNECTED); - } else { - powerFSM.trigger(EVENT_SERIAL_DISCONNECTED); - } -} - /// override close to also shutdown the TCP link void WiFiServerAPI::close() { @@ -46,6 +32,12 @@ void WiFiServerAPI::close() StreamAPI::close(); } +/// Check the current underlying physical link to see if the client is currently connected +bool WiFiServerAPI::checkIsConnected() +{ + return client.connected(); +} + int32_t WiFiServerAPI::runOnce() { if (client.connected()) { @@ -57,6 +49,13 @@ int32_t WiFiServerAPI::runOnce() } } +/// If an api server is running, we try to spit out debug 'serial' characters there +void WiFiServerPort::debugOut(char c) +{ + if (apiPort && apiPort->openAPI) + apiPort->openAPI->debugOut(c); +} + #define MESHTASTIC_PORTNUM 4403 WiFiServerPort::WiFiServerPort() : WiFiServer(MESHTASTIC_PORTNUM), concurrency::OSThread("ApiServer") {} diff --git a/src/mesh/wifi/WiFiServerAPI.h b/src/mesh/wifi/WiFiServerAPI.h index 96cfb2bb0..b7b8c335a 100644 --- a/src/mesh/wifi/WiFiServerAPI.h +++ b/src/mesh/wifi/WiFiServerAPI.h @@ -21,10 +21,14 @@ class WiFiServerAPI : public StreamAPI virtual void close(); protected: - /// Hookable to find out when connection changes - virtual void onConnectionChanged(bool connected); + /// We override this method to prevent publishing EVENT_SERIAL_CONNECTED/DISCONNECTED for wifi links (we want the board to + /// stay in the POWERED state to prevent disabling wifi) + virtual void onConnectionChanged(bool connected) {} virtual int32_t runOnce(); // Check for dropped client connections + + /// Check the current underlying physical link to see if the client is currently connected + virtual bool checkIsConnected(); }; /** @@ -44,6 +48,10 @@ class WiFiServerPort : public WiFiServer, private concurrency::OSThread void init(); + /// If an api server is running, we try to spit out debug 'serial' characters there + static void debugOut(char c); + + protected: int32_t runOnce(); }; diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 8a2cb7607..c60ae50e8 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -1,9 +1,11 @@ #include "MQTT.h" #include "NodeDB.h" +#include "PowerFSM.h" #include "main.h" #include "mesh/Channels.h" #include "mesh/Router.h" #include "mesh/generated/mqtt.pb.h" +#include "sleep.h" #include #include @@ -57,33 +59,45 @@ MQTT::MQTT() : concurrency::OSThread("mqtt"), pubSub(mqttClient) mqtt = this; pubSub.setCallback(mqttCallback); + + // preflightSleepObserver.observe(&preflightSleep); } void MQTT::reconnect() { - // pubSub.setServer("devsrv.ezdevice.net", 1883); or 192.168.10.188 - const char *serverAddr = "mqtt.meshtastic.org"; // default hostname + if (wantsLink()) { + const char *serverAddr = "mqtt.meshtastic.org"; // default hostname + int serverPort = 1883; // default server port - if (*radioConfig.preferences.mqtt_server) - serverAddr = radioConfig.preferences.mqtt_server; // Override the default + if (*radioConfig.preferences.mqtt_server) + serverAddr = radioConfig.preferences.mqtt_server; // Override the default - pubSub.setServer(serverAddr, 1883); + String server = String(serverAddr); + int delimIndex = server.indexOf(':'); + if (delimIndex > 0) { + String port = server.substring(delimIndex + 1, server.length()); + server[delimIndex] = 0; + serverPort = port.toInt(); + serverAddr = server.c_str(); + } + pubSub.setServer(serverAddr, serverPort); - DEBUG_MSG("Connecting to MQTT server\n", serverAddr); - auto myStatus = (statusTopic + owner.id); - bool connected = pubSub.connect(owner.id, "meshdev", "large4cats", myStatus.c_str(), 1, true, "offline"); - if (connected) { - DEBUG_MSG("MQTT connected\n"); - enabled = true; // Start running background process again - runASAP = true; + DEBUG_MSG("Connecting to MQTT server %s, port: %d\n", serverAddr, serverPort); + auto myStatus = (statusTopic + owner.id); + bool connected = pubSub.connect(owner.id, "meshdev", "large4cats", myStatus.c_str(), 1, true, "offline"); + if (connected) { + DEBUG_MSG("MQTT connected\n"); + enabled = true; // Start running background process again + runASAP = true; - /// FIXME, include more information in the status text - bool ok = pubSub.publish(myStatus.c_str(), "online", true); - DEBUG_MSG("published %d\n", ok); + /// FIXME, include more information in the status text + bool ok = pubSub.publish(myStatus.c_str(), "online", true); + DEBUG_MSG("published %d\n", ok); - sendSubscriptions(); - } else - DEBUG_MSG("Failed to contact MQTT server...\n"); + sendSubscriptions(); + } else + DEBUG_MSG("Failed to contact MQTT server...\n"); + } } void MQTT::sendSubscriptions() @@ -140,6 +154,7 @@ int32_t MQTT::runOnce() pubSub.disconnect(); } + powerFSM.trigger(EVENT_CONTACT_FROM_PHONE); // Suppress entering light sleep (because that would turn off bluetooth) return 20; } } diff --git a/src/mqtt/MQTT.h b/src/mqtt/MQTT.h index 2f98c3111..3f4c8f80c 100644 --- a/src/mqtt/MQTT.h +++ b/src/mqtt/MQTT.h @@ -19,6 +19,9 @@ class MQTT : private concurrency::OSThread WiFiClient mqttClient; PubSubClient pubSub; + // instead we supress sleep from our runOnce() callback + // CallbackObserver preflightSleepObserver = CallbackObserver(this, &MQTT::preflightSleepCb); + public: MQTT(); @@ -32,6 +35,10 @@ class MQTT : private concurrency::OSThread */ void onSend(const MeshPacket &mp, ChannelIndex chIndex); + /** Attempt to connect to server if necessary + */ + void reconnect(); + protected: virtual int32_t runOnce(); @@ -40,10 +47,6 @@ class MQTT : private concurrency::OSThread */ bool wantsLink() const; - /** Attempt to connect to server if necessary - */ - void reconnect(); - /** Tell the server what subscriptions we want (based on channels.downlink_enabled) */ void sendSubscriptions(); @@ -53,6 +56,9 @@ class MQTT : private concurrency::OSThread /// Called when a new publish arrives from the MQTT server void onPublish(char *topic, byte *payload, unsigned int length); + + /// Return 0 if sleep is okay, veto sleep if we are connected to pubsub server + // int preflightSleepCb(void *unused = NULL) { return pubSub.connected() ? 1 : 0; } }; void mqttInit(); diff --git a/src/nimble/BluetoothUtil.cpp b/src/nimble/BluetoothUtil.cpp index 0618c73e6..cd95c91ed 100644 --- a/src/nimble/BluetoothUtil.cpp +++ b/src/nimble/BluetoothUtil.cpp @@ -21,6 +21,8 @@ static bool pinShowing; static uint32_t doublepressed; +static bool bluetoothActive; + static void startCb(uint32_t pin) { pinShowing = true; @@ -52,23 +54,27 @@ void updateBatteryLevel(uint8_t level) void deinitBLE() { - // DEBUG_MSG("Shutting down bluetooth\n"); - // ble_gatts_show_local(); + if (bluetoothActive) { + bluetoothActive = false; - // FIXME - do we need to dealloc things? - what needs to stay alive across light sleep? - auto ret = nimble_port_stop(); - assert(ret == ESP_OK); + // DEBUG_MSG("Shutting down bluetooth\n"); + // ble_gatts_show_local(); - nimble_port_deinit(); // teardown nimble datastructures + // FIXME - do we need to dealloc things? - what needs to stay alive across light sleep? + auto ret = nimble_port_stop(); + assert(ret == ESP_OK); - // DEBUG_MSG("BLE port_deinit done\n"); + nimble_port_deinit(); // teardown nimble datastructures - ret = esp_nimble_hci_and_controller_deinit(); - assert(ret == ESP_OK); + // DEBUG_MSG("BLE port_deinit done\n"); - // DEBUG_MSG("BLE task exiting\n"); + ret = esp_nimble_hci_and_controller_deinit(); + assert(ret == ESP_OK); - DEBUG_MSG("Done shutting down bluetooth\n"); + // DEBUG_MSG("BLE task exiting\n"); + + DEBUG_MSG("Done shutting down bluetooth\n"); + } } void loopBLE() @@ -479,6 +485,8 @@ void disablePin() doublepressed = millis(); } + + // This routine is called multiple times, once each time we come back from sleep void reinitBluetooth() { @@ -536,10 +544,10 @@ void reinitBluetooth() ble_store_config_init(); nimble_port_freertos_init(ble_host_task); + bluetoothActive = true; } bool bluetoothOn; -bool firstTime = 1; // Enable/disable bluetooth. void setBluetoothEnable(bool on) @@ -549,32 +557,15 @@ void setBluetoothEnable(bool on) bluetoothOn = on; if (on) { - Serial.printf("Pre BT: %u heap size\n", ESP.getFreeHeap()); - // ESP_ERROR_CHECK( heap_trace_start(HEAP_TRACE_LEAKS) ); - reinitBluetooth(); - - // Don't try to reconnect wifi before bluetooth is configured. - // WiFi is initialized from main.cpp in setup() . - if (firstTime) { - firstTime = 0; - } else { -#ifndef NO_ESP32 - initWifi(0); -#endif + if (!initWifi(0)) // if we are using wifi, don't turn on bluetooth also + { + Serial.printf("Pre BT: %u heap size\n", ESP.getFreeHeap()); + // ESP_ERROR_CHECK( heap_trace_start(HEAP_TRACE_LEAKS) ); + reinitBluetooth(); } } else { - - /* - // If WiFi is in use, disable shutting down the radio. - if (isWifiAvailable()) { - return; - } - */ - // shutdown wifi -#ifndef NO_ESP32 deinitWifi(); -#endif // We have to totally teardown our bluetooth objects to prevent leaks deinitBLE(); diff --git a/src/nimble/NimbleBluetoothAPI.cpp b/src/nimble/NimbleBluetoothAPI.cpp index dde9171a3..da2f80ea1 100644 --- a/src/nimble/NimbleBluetoothAPI.cpp +++ b/src/nimble/NimbleBluetoothAPI.cpp @@ -31,6 +31,10 @@ void BluetoothPhoneAPI::onNowHasData(uint32_t fromRadioNum) } } +bool BluetoothPhoneAPI::checkIsConnected() { + return curConnectionHandle >= 0; +} + int toradio_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) { auto om = ctxt->om; diff --git a/src/nimble/NimbleBluetoothAPI.h b/src/nimble/NimbleBluetoothAPI.h index 5fa66cc24..e2260ba4d 100644 --- a/src/nimble/NimbleBluetoothAPI.h +++ b/src/nimble/NimbleBluetoothAPI.h @@ -6,10 +6,14 @@ extern uint16_t fromNumValHandle; class BluetoothPhoneAPI : public PhoneAPI { +protected: /** * Subclasses can use this as a hook to provide custom notifications for their transport (i.e. bluetooth notifies) */ virtual void onNowHasData(uint32_t fromRadioNum); + + /// Check the current underlying physical link to see if the client is currently connected + virtual bool checkIsConnected(); }; extern PhoneAPI *bluetoothPhoneAPI; \ No newline at end of file diff --git a/src/nrf52/BQ25713.cpp b/src/nrf52/BQ25713.cpp deleted file mode 100644 index 2018ea7da..000000000 --- a/src/nrf52/BQ25713.cpp +++ /dev/null @@ -1,100 +0,0 @@ -#include "BQ25713.h" -#include "configuration.h" - -#include - -#ifdef BQ25703A_ADDR - -const uint8_t BQ25713::devAddr = BQ25703A_ADDR; - -bool BQ25713::setup() -{ - DEBUG_MSG("Init BQ25713\n"); - - // if(!writeReg(0x34,0x9034)) return false; - // - // if(!writeReg(0x34,0x8034)) return false; - - if (!writeReg(0x00, 0x0F0A)) - return false; // Config Charge Option 0 - - if (!writeReg(0x02, 0x0224)) // 512mA, FIXME, this seems to be setting a number of bits marked as reserved, why? - return false; // Config Charge Current - - if (!writeReg(0x04, 0x1070)) // about 4.29V - return false; // Config Charge Voltage - - if (!writeReg(0x06, 0x099C)) - return false; // Config OTG Voltage - - if (!writeReg(0x08, 0x5000)) - return false; // Config OTG Current - - // if(!writeReg(0x0A,0x0100)) return false;//Config Input Voltage - - if (!writeReg(0x0C, 0x1800)) // 4.2Vish FIXME, we could lower this? - return false; // Config Minimum System Voltage - - if (!writeReg(0x0E, 0x4900)) - return false; // Config Input Current - - if (!writeReg(0x30, 0xE210)) - return false; // Config Charge Option 1 - - if (!writeReg(0x32, 0x32BF)) - return false; // Config Charge Option 2 - - if (!writeReg(0x34, 0x0834)) - return false; // Config Charge Option 3 - - if (!writeReg(0x36, 0x4A65)) - return false; // Config Prochot Option 0 - - if (!writeReg(0x38, 0x81FF)) - return false; // Config Prochot Option 1 - - if (!writeReg(0x3A, 0xA0FF)) - return false; // Config ADC Option - - return true; -} - -uint16_t BQ25713::readReg(uint8_t reg) -{ - Wire.beginTransmission(devAddr); - Wire.write(reg); - byte err = Wire.endTransmission(); - if (!err) { - int readLen = 2; - Wire.requestFrom(devAddr, (int)(readLen + 1)); - if (Wire.available() >= readLen) { - uint8_t lsb = Wire.read(), msb = Wire.read(); - - return (((uint16_t)msb) << 8) + lsb; - } else - return 0; - } else { - return 0; - } -} - -bool BQ25713::writeReg(uint8_t reg, uint16_t v) -{ - Wire.beginTransmission(devAddr); - Wire.write(reg); - Wire.write(v & 0xff); - Wire.write((v >> 8) & 0xff); - byte err = Wire.endTransmission(); // 0 for success - - if (!err) { - // Do a test readback for early debugging - uint16_t found = readReg(reg); - if (found != v) { - DEBUG_MSG("Readback reg=0x%0x test failed, expected 0x%0x, found 0x%0x!\n", reg, v, found); - return true; // claim success - FIXME - } - } - return !err; -} - -#endif \ No newline at end of file diff --git a/src/nrf52/BQ25713.h b/src/nrf52/BQ25713.h deleted file mode 100644 index 7dd62bac1..000000000 --- a/src/nrf52/BQ25713.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include - -/** - * Driver class to control/monitor BQ25713 charge controller - */ -class BQ25713 { - static const uint8_t devAddr; - -public: - - /// Return true for success - bool setup(); - -private: - uint16_t readReg(uint8_t reg); - - /// Return true for success - bool writeReg(uint8_t reg, uint16_t v); -}; - diff --git a/src/nrf52/NRF52Bluetooth.cpp b/src/nrf52/NRF52Bluetooth.cpp index e67607c94..efe8dc6e1 100644 --- a/src/nrf52/NRF52Bluetooth.cpp +++ b/src/nrf52/NRF52Bluetooth.cpp @@ -1,6 +1,6 @@ +#include "configuration.h" #include "NRF52Bluetooth.h" #include "BluetoothCommon.h" -#include "configuration.h" #include "main.h" #include "mesh/PhoneAPI.h" #include "mesh/mesh-pb-constants.h" @@ -21,6 +21,8 @@ static BLEDfu bledfu; // DFU software update helper service static uint8_t fromRadioBytes[FromRadio_size]; static uint8_t toRadioBytes[ToRadio_size]; +static bool bleConnected; + class BluetoothPhoneAPI : public PhoneAPI { /** @@ -33,6 +35,11 @@ class BluetoothPhoneAPI : public PhoneAPI DEBUG_MSG("BLE notify fromNum\n"); fromNum.notify32(fromRadioNum); } + + /// Check the current underlying physical link to see if the client is currently connected + virtual bool checkIsConnected() { + return bleConnected; + } }; static BluetoothPhoneAPI *bluetoothPhoneAPI; @@ -46,6 +53,7 @@ void connect_callback(uint16_t conn_handle) connection->getPeerName(central_name, sizeof(central_name)); DEBUG_MSG("BLE Connected to %s\n", central_name); + bleConnected = true; } /** @@ -55,7 +63,8 @@ void connect_callback(uint16_t conn_handle) */ void disconnect_callback(uint16_t conn_handle, uint8_t reason) { - (void)conn_handle; + // FIXME - we currently assume only one active connection + bleConnected = false; DEBUG_MSG("BLE Disconnected, reason = 0x%x\n", reason); } diff --git a/src/nrf52/NRF52CryptoEngine.cpp b/src/nrf52/NRF52CryptoEngine.cpp index 431fa2e9c..435925f9c 100644 --- a/src/nrf52/NRF52CryptoEngine.cpp +++ b/src/nrf52/NRF52CryptoEngine.cpp @@ -1,6 +1,5 @@ - -#include "CryptoEngine.h" #include "configuration.h" +#include "CryptoEngine.h" #include "ocrypto_aes_ctr.h" class NRF52CryptoEngine : public CryptoEngine diff --git a/src/nrf52/alloc.cpp b/src/nrf52/alloc.cpp index ddbbdab05..0a610bbe3 100644 --- a/src/nrf52/alloc.cpp +++ b/src/nrf52/alloc.cpp @@ -1,3 +1,4 @@ +#include "configuration.h" #include "rtos.h" #include #include diff --git a/src/nrf52/main-nrf52.cpp b/src/nrf52/main-nrf52.cpp index abb99042c..ab109205b 100644 --- a/src/nrf52/main-nrf52.cpp +++ b/src/nrf52/main-nrf52.cpp @@ -1,12 +1,13 @@ +#include "configuration.h" #include #include #include #include #include #include +// #include #include "NRF52Bluetooth.h" -#include "configuration.h" #include "error.h" #ifdef BQ25703A_ADDR @@ -19,6 +20,13 @@ static inline void debugger_break(void) "mov pc, lr\n\t"); } +bool loopCanSleep() { + // turn off sleep only while connected via USB + // return true; + return !Serial; // the bool operator on the nrf52 serial class returns true if connected to a PC currently + // return !(TinyUSBDevice.mounted() && !TinyUSBDevice.suspended()); +} + // handle standard gcc assert failures void __attribute__((noreturn)) __assert_func(const char *file, int line, const char *func, const char *failedexpr) { @@ -33,7 +41,7 @@ void getMacAddr(uint8_t *dmac) ble_gap_addr_t addr; if (sd_ble_gap_addr_get(&addr) == NRF_SUCCESS) { memcpy(dmac, addr.addr, 6); - } else { + } else { const uint8_t *src = (const uint8_t *)NRF_FICR->DEVICEADDR; dmac[5] = src[0]; dmac[4] = src[1]; @@ -86,7 +94,7 @@ void setBluetoothEnable(bool on) } /** - * Override printf to use the SEGGER output library + * Override printf to use the SEGGER output library (note - this does not effect the printf method on the debug console) */ int printf(const char *fmt, ...) { @@ -104,7 +112,7 @@ void checkSDEvents() while (NRF_SUCCESS == sd_evt_get(&evt)) { switch (evt) { case NRF_EVT_POWER_FAILURE_WARNING: - recordCriticalError(CriticalErrorCode_Brownout); + RECORD_CRITICALERROR(CriticalErrorCode_Brownout); break; default: @@ -114,7 +122,7 @@ void checkSDEvents() } } else { if (NRF_POWER->EVENTS_POFWARN) - recordCriticalError(CriticalErrorCode_Brownout); + RECORD_CRITICALERROR(CriticalErrorCode_Brownout); } } diff --git a/src/plugins/AdminPlugin.cpp b/src/plugins/AdminPlugin.cpp index 9ec305ec7..f642308da 100644 --- a/src/plugins/AdminPlugin.cpp +++ b/src/plugins/AdminPlugin.cpp @@ -1,9 +1,9 @@ +#include "configuration.h" #include "AdminPlugin.h" #include "Channels.h" #include "MeshService.h" #include "NodeDB.h" #include "Router.h" -#include "configuration.h" #include "main.h" #ifdef PORTDUINO @@ -12,6 +12,24 @@ AdminPlugin *adminPlugin; +/// A special reserved string to indicate strings we can not share with external nodes. We will use this 'reserved' word instead. +/// Also, to make setting work correctly, if someone tries to set a string to this reserved value we assume they don't really want a change. +static const char *secretReserved = "sekrit"; + +/// If buf is !empty, change it to secret +static void hideSecret(char *buf) { + if(*buf) { + strcpy(buf, secretReserved); + } +} + +/// If buf is the reserved secret word, replace the buffer with currentVal +static void writeSecret(char *buf, const char *currentVal) { + if(strcmp(buf, secretReserved) == 0) { + strcpy(buf, currentVal); + } +} + void AdminPlugin::handleGetChannel(const MeshPacket &req, uint32_t channelIndex) { if (req.decoded.want_response) { @@ -30,17 +48,20 @@ void AdminPlugin::handleGetRadio(const MeshPacket &req) AdminMessage r = AdminMessage_init_default; r.get_radio_response = radioConfig; - // NOTE: The phone app needs to know the ls_secs value so it can properly expect sleep behavior. + // NOTE: The phone app needs to know the ls_secs & phone_timeout value so it can properly expect sleep behavior. // So even if we internally use 0 to represent 'use default' we still need to send the value we are // using to the app (so that even old phone apps work with new device loads). r.get_radio_response.preferences.ls_secs = getPref_ls_secs(); + r.get_radio_response.preferences.phone_timeout_secs = getPref_phone_timeout_secs(); + // hideSecret(r.get_radio_response.preferences.wifi_ssid); // hmm - leave public for now, because only minimally private and useful for users to know current provisioning) + hideSecret(r.get_radio_response.preferences.wifi_password); r.which_variant = AdminMessage_get_radio_response_tag; myReply = allocDataProtobuf(r); } } -bool AdminPlugin::handleReceivedProtobuf(const MeshPacket &mp, const AdminMessage *r) +bool AdminPlugin::handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *r) { assert(r); switch (r->which_variant) { @@ -138,8 +159,9 @@ void AdminPlugin::handleSetChannel(const Channel &cc) } } -void AdminPlugin::handleSetRadio(const RadioConfig &r) +void AdminPlugin::handleSetRadio(RadioConfig &r) { + writeSecret(r.preferences.wifi_password, radioConfig.preferences.wifi_password); radioConfig = r; service.reloadConfig(); diff --git a/src/plugins/AdminPlugin.h b/src/plugins/AdminPlugin.h index e4fc91d6c..bbd0d14ad 100644 --- a/src/plugins/AdminPlugin.h +++ b/src/plugins/AdminPlugin.h @@ -17,12 +17,12 @@ class AdminPlugin : public ProtobufPlugin @return true if you've guaranteed you've handled this message and no other handlers should be considered for it */ - virtual bool handleReceivedProtobuf(const MeshPacket &mp, const AdminMessage *p); + virtual bool handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *p); private: void handleSetOwner(const User &o); void handleSetChannel(const Channel &cc); - void handleSetRadio(const RadioConfig &r); + void handleSetRadio(RadioConfig &r); void handleGetChannel(const MeshPacket &req, uint32_t channelIndex); void handleGetRadio(const MeshPacket &req); diff --git a/src/plugins/ExternalNotificationPlugin.cpp b/src/plugins/ExternalNotificationPlugin.cpp index e48b7beda..b19e9ad48 100644 --- a/src/plugins/ExternalNotificationPlugin.cpp +++ b/src/plugins/ExternalNotificationPlugin.cpp @@ -1,9 +1,9 @@ +#include "configuration.h" #include "ExternalNotificationPlugin.h" #include "MeshService.h" #include "NodeDB.h" #include "RTC.h" #include "Router.h" -#include "configuration.h" #include //#include @@ -143,7 +143,7 @@ ExternalNotificationPlugin::ExternalNotificationPlugin() #endif } -bool ExternalNotificationPlugin::handleReceived(const MeshPacket &mp) +ProcessMessage ExternalNotificationPlugin::handleReceived(const MeshPacket &mp) { #ifndef NO_ESP32 @@ -176,5 +176,5 @@ bool ExternalNotificationPlugin::handleReceived(const MeshPacket &mp) #endif - return true; // Let others look at this message also if they want + return ProcessMessage::CONTINUE; // Let others look at this message also if they want } diff --git a/src/plugins/ExternalNotificationPlugin.h b/src/plugins/ExternalNotificationPlugin.h index cb430b1b7..b56b78288 100644 --- a/src/plugins/ExternalNotificationPlugin.h +++ b/src/plugins/ExternalNotificationPlugin.h @@ -24,9 +24,9 @@ class ExternalNotificationPlugin : public SinglePortPlugin, private concurrency: /** Called to handle a particular incoming message - @return true if you've guaranteed you've handled this message and no other handlers should be considered for it + @return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for it */ - virtual bool handleReceived(const MeshPacket &mp); + virtual ProcessMessage handleReceived(const MeshPacket &mp); virtual int32_t runOnce(); }; diff --git a/src/plugins/NodeInfoPlugin.cpp b/src/plugins/NodeInfoPlugin.cpp index 5111d7b87..51303ac57 100644 --- a/src/plugins/NodeInfoPlugin.cpp +++ b/src/plugins/NodeInfoPlugin.cpp @@ -1,14 +1,14 @@ +#include "configuration.h" #include "NodeInfoPlugin.h" #include "MeshService.h" #include "NodeDB.h" #include "RTC.h" #include "Router.h" -#include "configuration.h" #include "main.h" NodeInfoPlugin *nodeInfoPlugin; -bool NodeInfoPlugin::handleReceivedProtobuf(const MeshPacket &mp, const User *pptr) +bool NodeInfoPlugin::handleReceivedProtobuf(const MeshPacket &mp, User *pptr) { auto p = *pptr; diff --git a/src/plugins/NodeInfoPlugin.h b/src/plugins/NodeInfoPlugin.h index eb2a16da1..d2b29c91a 100644 --- a/src/plugins/NodeInfoPlugin.h +++ b/src/plugins/NodeInfoPlugin.h @@ -26,7 +26,7 @@ class NodeInfoPlugin : public ProtobufPlugin, private concurrency::OSThrea @return true if you've guaranteed you've handled this message and no other handlers should be considered for it */ - virtual bool handleReceivedProtobuf(const MeshPacket &mp, const User *p); + virtual bool handleReceivedProtobuf(const MeshPacket &mp, User *p); /** Messages can be received that have the want_response bit set. If set, this callback will be invoked * so that subclasses can (optionally) send a response back to the original sender. */ diff --git a/src/plugins/Plugins.cpp b/src/plugins/Plugins.cpp index ca4cb52f4..2a9e326d5 100644 --- a/src/plugins/Plugins.cpp +++ b/src/plugins/Plugins.cpp @@ -1,3 +1,4 @@ +#include "configuration.h" #include "plugins/ExternalNotificationPlugin.h" #include "plugins/NodeInfoPlugin.h" #include "plugins/PositionPlugin.h" diff --git a/src/plugins/PositionPlugin.cpp b/src/plugins/PositionPlugin.cpp index 2aaa31a5e..5f03ec6b2 100644 --- a/src/plugins/PositionPlugin.cpp +++ b/src/plugins/PositionPlugin.cpp @@ -1,9 +1,9 @@ +#include "configuration.h" #include "PositionPlugin.h" #include "MeshService.h" #include "NodeDB.h" #include "RTC.h" #include "Router.h" -#include "configuration.h" PositionPlugin *positionPlugin; @@ -14,10 +14,36 @@ PositionPlugin::PositionPlugin() setIntervalFromNow(60 * 1000); // Send our initial position 60 seconds after we start (to give GPS time to setup) } -bool PositionPlugin::handleReceivedProtobuf(const MeshPacket &mp, const Position *pptr) +bool PositionPlugin::handleReceivedProtobuf(const MeshPacket &mp, Position *pptr) { auto p = *pptr; + // If inbound message is a replay (or spoof!) of our own messages, do not process + // (why use second-hand sources for our own data?) + if (nodeDB.getNodeNum() == getFrom(&mp)) { + DEBUG_MSG("Ignored an incoming update from MYSELF\n"); + return false; + } + + // Log packet size and list of fields + DEBUG_MSG("POSITION node=%08x l=%d %s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", + getFrom(&mp), + mp.decoded.payload.size, + p.latitude_i ? "LAT ":"", + p.longitude_i ? "LON ":"", + p.altitude ? "MSL ":"", + p.altitude_hae ? "HAE ":"", + p.alt_geoid_sep ? "GEO ":"", + p.PDOP ? "PDOP ":"", + p.HDOP ? "HDOP ":"", + p.VDOP ? "VDOP ":"", + p.sats_in_view ? "SIV ":"", + p.fix_quality ? "FXQ ":"", + p.fix_type ? "FXT ":"", + p.pos_timestamp ? "PTS ":"", + p.time ? "TIME ":"", + p.battery_level ? "BAT ":""); + if (p.time) { struct timeval tv; uint32_t secs = p.time; @@ -38,7 +64,44 @@ MeshPacket *PositionPlugin::allocReply() NodeInfo *node = service.refreshMyNodeInfo(); // should guarantee there is now a position assert(node->has_position); - Position p = node->position; + // configuration of POSITION packet + // consider making this a function argument? + uint32_t pos_flags = radioConfig.preferences.position_flags; + + // Populate a Position struct with ONLY the requested fields + Position p = Position_init_default; // Start with an empty structure + + // lat/lon are unconditionally included - IF AVAILABLE! + p.latitude_i = node->position.latitude_i; + p.longitude_i = node->position.longitude_i; + p.time = node->position.time; + + if (pos_flags & PositionFlags_POS_BATTERY) + p.battery_level = node->position.battery_level; + + if (pos_flags & PositionFlags_POS_ALTITUDE) { + if (pos_flags & PositionFlags_POS_ALT_MSL) + p.altitude = node->position.altitude; + else + p.altitude_hae = node->position.altitude_hae; + + if (pos_flags & PositionFlags_POS_GEO_SEP) + p.alt_geoid_sep = node->position.alt_geoid_sep; + } + + if (pos_flags & PositionFlags_POS_DOP) { + if (pos_flags & PositionFlags_POS_HVDOP) { + p.HDOP = node->position.HDOP; + p.VDOP = node->position.VDOP; + } else + p.PDOP = node->position.PDOP; + } + + if (pos_flags & PositionFlags_POS_SATINVIEW) + p.sats_in_view = node->position.sats_in_view; + + if (pos_flags & PositionFlags_POS_TIMESTAMP) + p.pos_timestamp = node->position.pos_timestamp; // Strip out any time information before sending packets to other nodes - to keep the wire size small (and because other // nodes shouldn't trust it anyways) Note: we allow a device with a local GPS to include the time, so that gpsless @@ -69,17 +132,20 @@ void PositionPlugin::sendOurPosition(NodeNum dest, bool wantReplies) int32_t PositionPlugin::runOnce() { + NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum()); // We limit our GPS broadcasts to a max rate uint32_t now = millis(); if (lastGpsSend == 0 || now - lastGpsSend >= getPref_position_broadcast_secs() * 1000) { + lastGpsSend = now; // If we changed channels, ask everyone else for their latest info bool requestReplies = currentGeneration != radioGeneration; currentGeneration = radioGeneration; - DEBUG_MSG("Sending position to mesh (wantReplies=%d)\n", requestReplies); + DEBUG_MSG("Sending pos@%x:6 to mesh (wantReplies=%d)\n", + node->position.pos_timestamp, requestReplies); sendOurPosition(NODENUM_BROADCAST, requestReplies); } diff --git a/src/plugins/PositionPlugin.h b/src/plugins/PositionPlugin.h index 45c4884a5..3e4034d4f 100644 --- a/src/plugins/PositionPlugin.h +++ b/src/plugins/PositionPlugin.h @@ -33,7 +33,7 @@ class PositionPlugin : public ProtobufPlugin, private concurrency::OST @return true if you've guaranteed you've handled this message and no other handlers should be considered for it */ - virtual bool handleReceivedProtobuf(const MeshPacket &mp, const Position *p); + virtual bool handleReceivedProtobuf(const MeshPacket &mp, Position *p); /** Messages can be received that have the want_response bit set. If set, this callback will be invoked * so that subclasses can (optionally) send a response back to the original sender. */ diff --git a/src/plugins/RemoteHardwarePlugin.cpp b/src/plugins/RemoteHardwarePlugin.cpp index d31e70608..60ef816d9 100644 --- a/src/plugins/RemoteHardwarePlugin.cpp +++ b/src/plugins/RemoteHardwarePlugin.cpp @@ -1,9 +1,9 @@ +#include "configuration.h" #include "RemoteHardwarePlugin.h" #include "MeshService.h" #include "NodeDB.h" #include "RTC.h" #include "Router.h" -#include "configuration.h" #include "main.h" #define NUM_GPIOS 64 @@ -48,7 +48,7 @@ RemoteHardwarePlugin::RemoteHardwarePlugin() { } -bool RemoteHardwarePlugin::handleReceivedProtobuf(const MeshPacket &req, const HardwareMessage *pptr) +bool RemoteHardwarePlugin::handleReceivedProtobuf(const MeshPacket &req, HardwareMessage *pptr) { auto p = *pptr; DEBUG_MSG("Received RemoteHardware typ=%d\n", p.typ); diff --git a/src/plugins/RemoteHardwarePlugin.h b/src/plugins/RemoteHardwarePlugin.h index fad6e8386..86a0bbd35 100644 --- a/src/plugins/RemoteHardwarePlugin.h +++ b/src/plugins/RemoteHardwarePlugin.h @@ -27,7 +27,7 @@ class RemoteHardwarePlugin : public ProtobufPlugin, private con @return true if you've guaranteed you've handled this message and no other handlers should be considered for it */ - virtual bool handleReceivedProtobuf(const MeshPacket &mp, const HardwareMessage *p); + virtual bool handleReceivedProtobuf(const MeshPacket &mp, HardwareMessage *p); /** * Periodically read the gpios we have been asked to WATCH, if they have changed, diff --git a/src/plugins/ReplyPlugin.cpp b/src/plugins/ReplyPlugin.cpp index 69903aa36..b0aa08673 100644 --- a/src/plugins/ReplyPlugin.cpp +++ b/src/plugins/ReplyPlugin.cpp @@ -1,6 +1,6 @@ +#include "configuration.h" #include "ReplyPlugin.h" #include "MeshService.h" -#include "configuration.h" #include "main.h" #include diff --git a/src/plugins/RoutingPlugin.cpp b/src/plugins/RoutingPlugin.cpp index e04239b27..82b0403fe 100644 --- a/src/plugins/RoutingPlugin.cpp +++ b/src/plugins/RoutingPlugin.cpp @@ -1,13 +1,13 @@ +#include "configuration.h" #include "RoutingPlugin.h" #include "MeshService.h" #include "NodeDB.h" #include "Router.h" -#include "configuration.h" #include "main.h" RoutingPlugin *routingPlugin; -bool RoutingPlugin::handleReceivedProtobuf(const MeshPacket &mp, const Routing *r) +bool RoutingPlugin::handleReceivedProtobuf(const MeshPacket &mp, Routing *r) { printPacket("Routing sniffing", &mp); router->sniffReceived(&mp, r); diff --git a/src/plugins/RoutingPlugin.h b/src/plugins/RoutingPlugin.h index ff659de2a..c0288f603 100644 --- a/src/plugins/RoutingPlugin.h +++ b/src/plugins/RoutingPlugin.h @@ -22,7 +22,7 @@ class RoutingPlugin : public ProtobufPlugin @return true if you've guaranteed you've handled this message and no other handlers should be considered for it */ - virtual bool handleReceivedProtobuf(const MeshPacket &mp, const Routing *p); + virtual bool handleReceivedProtobuf(const MeshPacket &mp, Routing *p); /** Messages can be received that have the want_response bit set. If set, this callback will be invoked * so that subclasses can (optionally) send a response back to the original sender. */ diff --git a/src/plugins/SerialPlugin.cpp b/src/plugins/SerialPlugin.cpp index a79982129..f6f3326fc 100644 --- a/src/plugins/SerialPlugin.cpp +++ b/src/plugins/SerialPlugin.cpp @@ -1,9 +1,9 @@ +#include "configuration.h" #include "SerialPlugin.h" #include "MeshService.h" #include "NodeDB.h" #include "RTC.h" #include "Router.h" -#include "configuration.h" #include #include @@ -157,7 +157,7 @@ void SerialPluginRadio::sendPayload(NodeNum dest, bool wantReplies) service.sendToMesh(p); } -bool SerialPluginRadio::handleReceived(const MeshPacket &mp) +ProcessMessage SerialPluginRadio::handleReceived(const MeshPacket &mp) { #ifndef NO_ESP32 @@ -207,5 +207,5 @@ bool SerialPluginRadio::handleReceived(const MeshPacket &mp) #endif - return true; // Let others look at this message also if they want + return ProcessMessage::CONTINUE; // Let others look at this message also if they want } diff --git a/src/plugins/SerialPlugin.h b/src/plugins/SerialPlugin.h index 54776ec6a..c83d3689b 100644 --- a/src/plugins/SerialPlugin.h +++ b/src/plugins/SerialPlugin.h @@ -45,9 +45,9 @@ class SerialPluginRadio : public SinglePortPlugin /** Called to handle a particular incoming message - @return true if you've guaranteed you've handled this message and no other handlers should be considered for it + @return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for it */ - virtual bool handleReceived(const MeshPacket &mp); + virtual ProcessMessage handleReceived(const MeshPacket &mp); }; extern SerialPluginRadio *serialPluginRadio; \ No newline at end of file diff --git a/src/plugins/TextMessagePlugin.cpp b/src/plugins/TextMessagePlugin.cpp index b285363aa..c2b1f08b2 100644 --- a/src/plugins/TextMessagePlugin.cpp +++ b/src/plugins/TextMessagePlugin.cpp @@ -5,7 +5,7 @@ TextMessagePlugin *textMessagePlugin; -bool TextMessagePlugin::handleReceived(const MeshPacket &mp) +ProcessMessage TextMessagePlugin::handleReceived(const MeshPacket &mp) { auto &p = mp.decoded; DEBUG_MSG("Received text msg from=0x%0x, id=0x%x, msg=%.*s\n", mp.from, mp.id, p.payload.size, p.payload.bytes); @@ -18,5 +18,5 @@ bool TextMessagePlugin::handleReceived(const MeshPacket &mp) powerFSM.trigger(EVENT_RECEIVED_TEXT_MSG); notifyObservers(&mp); - return false; // Let others look at this message also if they want + return ProcessMessage::CONTINUE; // Let others look at this message also if they want } diff --git a/src/plugins/TextMessagePlugin.h b/src/plugins/TextMessagePlugin.h index f7eba65f6..87eb82e35 100644 --- a/src/plugins/TextMessagePlugin.h +++ b/src/plugins/TextMessagePlugin.h @@ -17,9 +17,9 @@ class TextMessagePlugin : public SinglePortPlugin, public Observable +#include #include #include +#include -#define DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000 // Some sensors (the DHT11) have a minimum required duration between read attempts +#define DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000 +#define DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000 +#define DS18B20_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000 #define FAILED_STATE_SENSOR_READ_MULTIPLIER 10 #define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true - #ifdef HAS_EINK // The screen is bigger so use bigger fonts #define FONT_SMALL ArialMT_Plain_16 @@ -31,123 +34,136 @@ #define FONT_HEIGHT_SMALL fontHeight(FONT_SMALL) #define FONT_HEIGHT_MEDIUM fontHeight(FONT_MEDIUM) - -int32_t EnvironmentalMeasurementPlugin::runOnce() { +int32_t EnvironmentalMeasurementPlugin::runOnce() +{ #ifndef NO_ESP32 // this only works on ESP32 devices /* Uncomment the preferences below if you want to use the plugin without having to configure it from the PythonAPI or WebUI. */ - + /*radioConfig.preferences.environmental_measurement_plugin_measurement_enabled = 1; radioConfig.preferences.environmental_measurement_plugin_screen_enabled = 1; radioConfig.preferences.environmental_measurement_plugin_read_error_count_threshold = 5; - radioConfig.preferences.environmental_measurement_plugin_update_interval = 30; + radioConfig.preferences.environmental_measurement_plugin_update_interval = 600; radioConfig.preferences.environmental_measurement_plugin_recovery_interval = 60; - radioConfig.preferences.environmental_measurement_plugin_display_farenheit = true; + radioConfig.preferences.environmental_measurement_plugin_display_farenheit = false; radioConfig.preferences.environmental_measurement_plugin_sensor_pin = 13; - radioConfig.preferences.environmental_measurement_plugin_sensor_type = RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType::RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT11;*/ + radioConfig.preferences.environmental_measurement_plugin_sensor_type = + RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType:: + RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DS18B20; + */ - if (! (radioConfig.preferences.environmental_measurement_plugin_measurement_enabled || radioConfig.preferences.environmental_measurement_plugin_screen_enabled)){ + if (!(radioConfig.preferences.environmental_measurement_plugin_measurement_enabled || + radioConfig.preferences.environmental_measurement_plugin_screen_enabled)) { // If this plugin is not enabled, and the user doesn't want the display screen don't waste any OSThread time on it return (INT32_MAX); } if (firstTime) { // This is the first time the OSThread library has called this function, so do some setup - firstTime = 0; - - if (radioConfig.preferences.environmental_measurement_plugin_measurement_enabled) - { + + if (radioConfig.preferences.environmental_measurement_plugin_measurement_enabled) { DEBUG_MSG("EnvironmentalMeasurement: Initializing\n"); // it's possible to have this plugin enabled, only for displaying values on the screen. // therefore, we should only enable the sensor loop if measurement is also enabled - switch(radioConfig.preferences.environmental_measurement_plugin_sensor_type) { - case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT11: - dht = new DHT(radioConfig.preferences.environmental_measurement_plugin_sensor_pin,DHT11); - this->dht->begin(); - this->dht->read(); - DEBUG_MSG("EnvironmentalMeasurement: Opened DHT11 on pin: %d\n",radioConfig.preferences.environmental_measurement_plugin_sensor_pin); + switch (radioConfig.preferences.environmental_measurement_plugin_sensor_type) { + case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT11: + dht = new DHT(radioConfig.preferences.environmental_measurement_plugin_sensor_pin, DHT11); + this->dht->begin(); + this->dht->read(); + DEBUG_MSG("EnvironmentalMeasurement: Opened DHT11 on pin: %d\n", + radioConfig.preferences.environmental_measurement_plugin_sensor_pin); + return (DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); + case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DS18B20: + oneWire = new OneWire(radioConfig.preferences.environmental_measurement_plugin_sensor_pin); + ds18b20 = new DS18B20(oneWire); + this->ds18b20->begin(); + this->ds18b20->setResolution(12); + this->ds18b20->requestTemperatures(); + DEBUG_MSG("EnvironmentalMeasurement: Opened DS18B20 on pin: %d\n", + radioConfig.preferences.environmental_measurement_plugin_sensor_pin); + return (DS18B20_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); + default: + DEBUG_MSG("EnvironmentalMeasurement: Invalid sensor type selected; Disabling plugin"); + return (INT32_MAX); break; - default: - DEBUG_MSG("EnvironmentalMeasurement: Invalid sensor type selected; Disabling plugin"); - return (INT32_MAX); - break; } - // begin reading measurements from the sensor - // DHT have a max read-rate of 1HZ, so we should wait at least 1 second - // after initializing the sensor before we try to read from it. - // returning the interval here means that the next time OSThread - // calls our plugin, we'll run the other branch of this if statement - // and actually do a "sendOurEnvironmentalMeasurement()" - return(DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); } return (INT32_MAX); - } - else { - if (!radioConfig.preferences.environmental_measurement_plugin_measurement_enabled) - { + } else { + if (!radioConfig.preferences.environmental_measurement_plugin_measurement_enabled) { // if we somehow got to a second run of this plugin with measurement disabled, then just wait forever // I can't imagine we'd ever get here though. return (INT32_MAX); } // this is not the first time OSThread library has called this function // so just do what we intend to do on the interval - if(sensor_read_error_count > radioConfig.preferences.environmental_measurement_plugin_read_error_count_threshold) - { - if (radioConfig.preferences.environmental_measurement_plugin_recovery_interval > 0 ) { - DEBUG_MSG( - "EnvironmentalMeasurement: TEMPORARILY DISABLED; The environmental_measurement_plugin_read_error_count_threshold has been exceed: %d. Will retry reads in %d seconds\n", - radioConfig.preferences.environmental_measurement_plugin_read_error_count_threshold, - radioConfig.preferences.environmental_measurement_plugin_recovery_interval); - sensor_read_error_count = 0; - return(radioConfig.preferences.environmental_measurement_plugin_recovery_interval*1000); + if (sensor_read_error_count > radioConfig.preferences.environmental_measurement_plugin_read_error_count_threshold) { + if (radioConfig.preferences.environmental_measurement_plugin_recovery_interval > 0) { + DEBUG_MSG("EnvironmentalMeasurement: TEMPORARILY DISABLED; The " + "environmental_measurement_plugin_read_error_count_threshold has been exceed: %d. Will retry reads in " + "%d seconds\n", + radioConfig.preferences.environmental_measurement_plugin_read_error_count_threshold, + radioConfig.preferences.environmental_measurement_plugin_recovery_interval); + sensor_read_error_count = 0; + return (radioConfig.preferences.environmental_measurement_plugin_recovery_interval * 1000); } - DEBUG_MSG( - "EnvironmentalMeasurement: DISABLED; The environmental_measurement_plugin_read_error_count_threshold has been exceed: %d. Reads will not be retried until after device reset\n", - radioConfig.preferences.environmental_measurement_plugin_read_error_count_threshold); - return(INT32_MAX); + DEBUG_MSG("EnvironmentalMeasurement: DISABLED; The environmental_measurement_plugin_read_error_count_threshold has " + "been exceed: %d. Reads will not be retried until after device reset\n", + radioConfig.preferences.environmental_measurement_plugin_read_error_count_threshold); + return (INT32_MAX); - + } else if (sensor_read_error_count > 0) { + DEBUG_MSG("EnvironmentalMeasurement: There have been %d sensor read failures. Will retry %d more times\n", + sensor_read_error_count, sensor_read_error_count, sensor_read_error_count, + radioConfig.preferences.environmental_measurement_plugin_read_error_count_threshold - + sensor_read_error_count); } - else if (sensor_read_error_count > 0){ - DEBUG_MSG("EnvironmentalMeasurement: There have been %d sensor read failures. Will retry %d more times\n", - sensor_read_error_count, - radioConfig.preferences.environmental_measurement_plugin_read_error_count_threshold-sensor_read_error_count); - } - if (!sendOurEnvironmentalMeasurement() ){ - // if we failed to read the sensor, then try again + if (!sendOurEnvironmentalMeasurement()) { + // if we failed to read the sensor, then try again // as soon as we can according to the maximum polling frequency - return(DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); + // return (DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); + + switch (radioConfig.preferences.environmental_measurement_plugin_sensor_type) { + case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT11: + return (DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); + case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DS18B20: + return (DS18B20_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); + default: + return (DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); + } } } - // The return of runOnce is an int32 representing the desired number of - // miliseconds until the function should be called again by the + // The return of runOnce is an int32 representing the desired number of + // miliseconds until the function should be called again by the // OSThread library. Multiply the preference value by 1000 to convert seconds to miliseconds - return(radioConfig.preferences.environmental_measurement_plugin_update_interval * 1000); + return (radioConfig.preferences.environmental_measurement_plugin_update_interval * 1000); #endif } -bool EnvironmentalMeasurementPlugin::wantUIFrame() { +bool EnvironmentalMeasurementPlugin::wantUIFrame() +{ return radioConfig.preferences.environmental_measurement_plugin_screen_enabled; } -String GetSenderName(const MeshPacket &mp) { +String GetSenderName(const MeshPacket &mp) +{ String sender; auto node = nodeDB.getNode(getFrom(&mp)); - if (node){ + if (node) { sender = node->user.short_name; - } - else { + } else { sender = "UNK"; } return sender; } -uint32_t GetTimeSinceMeshPacket(const MeshPacket *mp) { +uint32_t GetTimeSinceMeshPacket(const MeshPacket *mp) +{ uint32_t now = getTime(); uint32_t last_seen = mp->rx_time; @@ -156,15 +172,13 @@ uint32_t GetTimeSinceMeshPacket(const MeshPacket *mp) { delta = 0; return delta; - } - -float EnvironmentalMeasurementPlugin::CelsiusToFarenheit(float c) { - return (c*9)/5 + 32; +float EnvironmentalMeasurementPlugin::CelsiusToFarenheit(float c) +{ + return (c * 9) / 5 + 32; } - void EnvironmentalMeasurementPlugin::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { display->setTextAlignment(TEXT_ALIGN_LEFT); @@ -173,21 +187,16 @@ void EnvironmentalMeasurementPlugin::drawFrame(OLEDDisplay *display, OLEDDisplay if (lastMeasurementPacket == nullptr) { display->setFont(FONT_SMALL); display->drawString(x, y += fontHeight(FONT_MEDIUM), "No measurement"); - //DEBUG_MSG("EnvironmentalMeasurement: No previous measurement; not drawing frame\n"); return; } EnvironmentalMeasurement lastMeasurement; - - + uint32_t agoSecs = GetTimeSinceMeshPacket(lastMeasurementPacket); String lastSender = GetSenderName(*lastMeasurementPacket); auto &p = lastMeasurementPacket->decoded; - if (!pb_decode_from_bytes(p.payload.bytes, - p.payload.size, - EnvironmentalMeasurement_fields, - &lastMeasurement)) { + if (!pb_decode_from_bytes(p.payload.bytes, p.payload.size, EnvironmentalMeasurement_fields, &lastMeasurement)) { display->setFont(FONT_SMALL); display->drawString(x, y += fontHeight(FONT_MEDIUM), "Measurement Error"); DEBUG_MSG("EnvironmentalMeasurement: unable to decode last packet"); @@ -195,20 +204,23 @@ void EnvironmentalMeasurementPlugin::drawFrame(OLEDDisplay *display, OLEDDisplay } display->setFont(FONT_SMALL); - String last_temp = String(lastMeasurement.temperature,0) +"°C"; - if (radioConfig.preferences.environmental_measurement_plugin_display_farenheit){ - last_temp = String(CelsiusToFarenheit(lastMeasurement.temperature),0) +"°F";; + String last_temp = String(lastMeasurement.temperature, 0) + "°C"; + if (radioConfig.preferences.environmental_measurement_plugin_display_farenheit) { + last_temp = String(CelsiusToFarenheit(lastMeasurement.temperature), 0) + "°F"; + ; } - display->drawString(x, y += fontHeight(FONT_MEDIUM), lastSender+": "+last_temp +"/"+ String(lastMeasurement.relative_humidity,0) + "%("+String(agoSecs)+"s)"); - + display->drawString(x, y += fontHeight(FONT_MEDIUM), + lastSender + ": " + last_temp + "/" + String(lastMeasurement.relative_humidity, 0) + "%(" + + String(agoSecs) + "s)"); } -bool EnvironmentalMeasurementPlugin::handleReceivedProtobuf(const MeshPacket &mp, const EnvironmentalMeasurement *p) +bool EnvironmentalMeasurementPlugin::handleReceivedProtobuf(const MeshPacket &mp, EnvironmentalMeasurement *p) { - if (!(radioConfig.preferences.environmental_measurement_plugin_measurement_enabled || radioConfig.preferences.environmental_measurement_plugin_screen_enabled)){ - // If this plugin is not enabled in any capacity, don't handle the packet, and allow other plugins to consume - return false; + if (!(radioConfig.preferences.environmental_measurement_plugin_measurement_enabled || + radioConfig.preferences.environmental_measurement_plugin_screen_enabled)) { + // If this plugin is not enabled in any capacity, don't handle the packet, and allow other plugins to consume + return false; } String sender = GetSenderName(mp); @@ -230,13 +242,32 @@ bool EnvironmentalMeasurementPlugin::sendOurEnvironmentalMeasurement(NodeNum des DEBUG_MSG("-----------------------------------------\n"); DEBUG_MSG("EnvironmentalMeasurement: Read data\n"); - if (!this->dht->read(true)){ - sensor_read_error_count++; - DEBUG_MSG("EnvironmentalMeasurement: FAILED TO READ DATA\n"); + + switch (radioConfig.preferences.environmental_measurement_plugin_sensor_type) { + case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT11: + if (!this->dht->read(true)) { + sensor_read_error_count++; + DEBUG_MSG("EnvironmentalMeasurement: FAILED TO READ DATA\n"); + return false; + } + m.relative_humidity = this->dht->readHumidity(); + m.temperature = this->dht->readTemperature(); + break; + case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DS18B20: + if (this->ds18b20->isConversionComplete()) { + m.temperature = this->ds18b20->getTempC(); + m.relative_humidity = 0; // This sensor is temperature only + this->ds18b20->requestTemperatures(); + break; + } else { + sensor_read_error_count++; + DEBUG_MSG("EnvironmentalMeasurement: FAILED TO READ DATA\n"); + return false; + } + default: + DEBUG_MSG("EnvironmentalMeasurement: Invalid sensor type selected; Disabling plugin"); return false; } - m.relative_humidity = this->dht->readHumidity(); - m.temperature = this->dht->readTemperature(); DEBUG_MSG("EnvironmentalMeasurement->relative_humidity: %f\n", m.relative_humidity); DEBUG_MSG("EnvironmentalMeasurement->temperature: %f\n", m.temperature); @@ -250,4 +281,3 @@ bool EnvironmentalMeasurementPlugin::sendOurEnvironmentalMeasurement(NodeNum des service.sendToMesh(p); return true; } - diff --git a/src/plugins/esp32/EnvironmentalMeasurementPlugin.h b/src/plugins/esp32/EnvironmentalMeasurementPlugin.h index 3123cc0f0..e60a84c8b 100644 --- a/src/plugins/esp32/EnvironmentalMeasurementPlugin.h +++ b/src/plugins/esp32/EnvironmentalMeasurementPlugin.h @@ -1,15 +1,20 @@ #pragma once -#include "ProtobufPlugin.h" #include "../mesh/generated/environmental_measurement.pb.h" +#include "ProtobufPlugin.h" +#include +#include #include #include -#include +#include class EnvironmentalMeasurementPlugin : private concurrency::OSThread, public ProtobufPlugin { public: - EnvironmentalMeasurementPlugin(): concurrency::OSThread("EnvironmentalMeasurementPlugin"), ProtobufPlugin("EnvironmentalMeasurement", PortNum_ENVIRONMENTAL_MEASUREMENT_APP, &EnvironmentalMeasurement_msg) { - lastMeasurementPacket = nullptr; + EnvironmentalMeasurementPlugin() + : concurrency::OSThread("EnvironmentalMeasurementPlugin"), + ProtobufPlugin("EnvironmentalMeasurement", PortNum_ENVIRONMENTAL_MEASUREMENT_APP, &EnvironmentalMeasurement_msg) + { + lastMeasurementPacket = nullptr; } virtual bool wantUIFrame(); virtual void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y); @@ -18,17 +23,19 @@ class EnvironmentalMeasurementPlugin : private concurrency::OSThread, public Pro /** Called to handle a particular incoming message @return true if you've guaranteed you've handled this message and no other handlers should be considered for it */ - virtual bool handleReceivedProtobuf(const MeshPacket &mp, const EnvironmentalMeasurement *p); + virtual bool handleReceivedProtobuf(const MeshPacket &mp, EnvironmentalMeasurement *p); virtual int32_t runOnce(); /** * Send our EnvironmentalMeasurement into the mesh */ bool sendOurEnvironmentalMeasurement(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false); - + private: float CelsiusToFarenheit(float c); bool firstTime = 1; - DHT* dht; + DHT *dht; + OneWire *oneWire; + DS18B20 *ds18b20; const MeshPacket *lastMeasurementPacket; uint32_t sensor_read_error_count = 0; }; \ No newline at end of file diff --git a/src/plugins/esp32/RangeTestPlugin.cpp b/src/plugins/esp32/RangeTestPlugin.cpp index b28bd8c9c..0af123c16 100644 --- a/src/plugins/esp32/RangeTestPlugin.cpp +++ b/src/plugins/esp32/RangeTestPlugin.cpp @@ -5,6 +5,7 @@ #include "RTC.h" #include "Router.h" #include "configuration.h" +#include "gps/GeoCoord.h" #include #include //#include @@ -123,7 +124,7 @@ void RangeTestPluginRadio::sendPayload(NodeNum dest, bool wantReplies) powerFSM.trigger(EVENT_CONTACT_FROM_PHONE); } -bool RangeTestPluginRadio::handleReceived(const MeshPacket &mp) +ProcessMessage RangeTestPluginRadio::handleReceived(const MeshPacket &mp) { #ifndef NO_ESP32 @@ -181,28 +182,7 @@ bool RangeTestPluginRadio::handleReceived(const MeshPacket &mp) #endif - return true; // Let others look at this message also if they want -} - -/// Ported from my old java code, returns distance in meters along the globe -/// surface (by magic?) -float RangeTestPluginRadio::latLongToMeter(double lat_a, double lng_a, double lat_b, double lng_b) -{ - double pk = (180 / 3.14169); - double a1 = lat_a / pk; - double a2 = lng_a / pk; - double b1 = lat_b / pk; - double b2 = lng_b / pk; - double cos_b1 = cos(b1); - double cos_a1 = cos(a1); - double t1 = cos_a1 * cos(a2) * cos_b1 * cos(b2); - double t2 = cos_a1 * sin(a2) * cos_b1 * sin(b2); - double t3 = sin(a1) * sin(b1); - double tt = acos(t1 + t2 + t3); - if (isnan(tt)) - tt = 0.0; // Must have been the same point? - - return (float)(6366000 * tt); + return ProcessMessage::CONTINUE; // Let others look at this message also if they want } bool RangeTestPluginRadio::appendFile(const MeshPacket &mp) @@ -303,7 +283,7 @@ bool RangeTestPluginRadio::appendFile(const MeshPacket &mp) fileToAppend.printf("%f,", mp.rx_snr); // RX SNR if (n->position.latitude_i && n->position.longitude_i && gpsStatus->getLatitude() && gpsStatus->getLongitude()) { - float distance = latLongToMeter(n->position.latitude_i * 1e-7, n->position.longitude_i * 1e-7, + float distance = GeoCoord::latLongToMeter(n->position.latitude_i * 1e-7, n->position.longitude_i * 1e-7, gpsStatus->getLatitude() * 1e-7, gpsStatus->getLongitude() * 1e-7); fileToAppend.printf("%f,", distance); // Distance in meters } else { diff --git a/src/plugins/esp32/RangeTestPlugin.h b/src/plugins/esp32/RangeTestPlugin.h index be998e510..d20a253a0 100644 --- a/src/plugins/esp32/RangeTestPlugin.h +++ b/src/plugins/esp32/RangeTestPlugin.h @@ -50,9 +50,9 @@ class RangeTestPluginRadio : public SinglePortPlugin /** Called to handle a particular incoming message - @return true if you've guaranteed you've handled this message and no other handlers should be considered for it + @return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for it */ - virtual bool handleReceived(const MeshPacket &mp); + virtual ProcessMessage handleReceived(const MeshPacket &mp); }; extern RangeTestPluginRadio *rangeTestPluginRadio; diff --git a/src/plugins/esp32/StoreForwardPlugin.cpp b/src/plugins/esp32/StoreForwardPlugin.cpp index 3c6c3bbd8..ae725422f 100644 --- a/src/plugins/esp32/StoreForwardPlugin.cpp +++ b/src/plugins/esp32/StoreForwardPlugin.cpp @@ -191,7 +191,7 @@ void StoreForwardPlugin::sendPayloadWelcome(NodeNum dest, bool wantReplies) service.sendToMesh(p); } -bool StoreForwardPlugin::handleReceived(const MeshPacket &mp) +ProcessMessage StoreForwardPlugin::handleReceived(const MeshPacket &mp) { #ifndef NO_ESP32 if (radioConfig.preferences.store_forward_plugin_enabled) { @@ -217,7 +217,7 @@ bool StoreForwardPlugin::handleReceived(const MeshPacket &mp) #endif - return true; // Let others look at this message also if they want + return ProcessMessage::CONTINUE; // Let others look at this message also if they want } StoreForwardPlugin::StoreForwardPlugin() diff --git a/src/plugins/esp32/StoreForwardPlugin.h b/src/plugins/esp32/StoreForwardPlugin.h index b444b6159..acdac6f63 100644 --- a/src/plugins/esp32/StoreForwardPlugin.h +++ b/src/plugins/esp32/StoreForwardPlugin.h @@ -51,9 +51,9 @@ class StoreForwardPlugin : public SinglePortPlugin, private concurrency::OSThrea /** Called to handle a particular incoming message - @return true if you've guaranteed you've handled this message and no other handlers should be considered for it + @return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for it */ - virtual bool handleReceived(const MeshPacket &mp); + virtual ProcessMessage handleReceived(const MeshPacket &mp); }; extern StoreForwardPlugin *storeForwardPlugin; diff --git a/src/portduino/PortduinoGlue.cpp b/src/portduino/PortduinoGlue.cpp index 876168891..46abd6b85 100644 --- a/src/portduino/PortduinoGlue.cpp +++ b/src/portduino/PortduinoGlue.cpp @@ -1,11 +1,13 @@ #include "CryptoEngine.h" #include "PortduinoGPIO.h" +#include "SPIChip.h" #include "mesh/RF95Interface.h" #include "sleep.h" #include "target_specific.h" #include #include +#include // FIXME - move setBluetoothEnable into a HALPlatform class @@ -21,33 +23,14 @@ void cpuDeepSleep(uint64_t msecs) void updateBatteryLevel(uint8_t level) NOT_IMPLEMENTED("updateBatteryLevel"); -/** Dear pinetab hardware geeks! - * - * The current pinetab lora module has a slight bug. The ch341 part only provides ISR assertions on edges. - * This makes sense because USB interrupts happen through fast/repeated special irq urbs that are constantly - * chattering on the USB bus. - * - * But this isn't sufficient for level triggered ISR sources like the sx127x radios. The common way that seems to - * be addressed by cs341 users is to **always** connect the INT# (pin 26 on the ch341f) signal to one of the GPIO signals - * on the part. I'd recommend connecting that LORA_DIO0/INT# line to pin 19 (data 4) on the pinetab board. This would - * provide an efficent mechanism so that the (kernel) code in the cs341 driver that I've slightly hacked up to see the - * current state of LORA_DIO0. Without that access, I can't know if the interrupt is still pending - which would create - * race conditions in packet handling. - * - * My workaround is to poll the status register internally to the sx127x. Which is expensive because it involves a number of - * i2c transactions and many trips back and forth between kernel and my userspace app. I think shipping the current version - * of the pinetab lora device would be fine because I can poll slowly (because lora is slow). But if you ever have cause to - * rev this board. I highly encourage this small change. - * - * Btw - your little "USB lora dongle" is really neat. I encourage you to sell it, because even non pinetab customers could - * use it to easily add lora to rasberry pi, desktop pcs etc... - * + +/** a simulated pin for busted IRQ hardware * Porduino helper class to do this i2c based polling: */ -class R595PolledIrqPin : public GPIOPin +class PolledIrqPin : public GPIOPin { public: - R595PolledIrqPin() : GPIOPin(LORA_DIO0, "LORA_DIO0") {} + PolledIrqPin() : GPIOPin(LORA_DIO1, "loraIRQ") {} /// Read the low level hardware for this pin virtual PinStatus readPinHardware() @@ -58,14 +41,16 @@ class R595PolledIrqPin : public GPIOPin extern RadioInterface *rIf; // FIXME, temporary hack until we know if we need to keep this assert(rIf); - RF95Interface *rIf95 = static_cast(rIf); + RadioLibInterface *rIf95 = static_cast(rIf); bool p = rIf95->isIRQPending(); - // log(SysGPIO, LogDebug, "R595PolledIrqPin::readPinHardware(%s, %d, %d)", getName(), getPinNum(), p); + log(SysGPIO, LogDebug, "PolledIrqPin::readPinHardware(%s, %d, %d)", getName(), getPinNum(), p); return p ? HIGH : LOW; } } }; +static GPIOPin *loraIrq; + /** apps run under portduino can optionally define a portduinoSetup() to * use portduino specific init code (such as gpioBind) to setup portduino on their host machine, * before running 'arduino' code. @@ -74,8 +59,45 @@ void portduinoSetup() { printf("Setting up Meshtastic on Porduino...\n"); - // FIXME: disable while not testing with real hardware - // gpioBind(new R595PolledIrqPin()); +#ifdef PORTDUINO_LINUX_HARDWARE + SPI.begin(); // We need to create SPI + bool usePineLora = !spiChip->isSimulated(); + if(usePineLora) { + printf("Connecting to PineLora board...\n"); + + // FIXME: remove this hack once interrupts are confirmed to work on new pine64 board + // loraIrq = new PolledIrqPin(); + loraIrq = new LinuxGPIOPin(LORA_DIO1, "ch341", "int", "loraIrq"); // or "err"? + loraIrq->setSilent(); + gpioBind(loraIrq); + + // BUSY hw was busted on current board - just use the simulated pin (which will read low) + auto busy = new LinuxGPIOPin(SX126X_BUSY, "ch341", "slct", "loraBusy"); + busy->setSilent(); + gpioBind(busy); + + gpioBind(new LinuxGPIOPin(SX126X_RESET, "ch341", "ini", "loraReset")); + + auto loraCs = new LinuxGPIOPin(SX126X_CS, "ch341", "cs0", "loraCs"); + loraCs->setSilent(); + gpioBind(loraCs); + } + else +#endif + + { + auto fakeBusy = new SimGPIOPin(SX126X_BUSY, "fakeBusy"); + fakeBusy->writePin(LOW); + fakeBusy->setSilent(true); + gpioBind(fakeBusy); + + auto cs = new SimGPIOPin(SX126X_CS, "fakeLoraCS"); + cs->setSilent(true); + gpioBind(cs); + + gpioBind(new SimGPIOPin(SX126X_RESET, "fakeLoraReset")); + gpioBind(new SimGPIOPin(LORA_DIO1, "fakeLoraIrq")); + } // gpioBind((new SimGPIOPin(LORA_RESET, "LORA_RESET"))); // gpioBind((new SimGPIOPin(RF95_NSS, "RF95_NSS"))->setSilent()); diff --git a/src/portduino/wifi-stubs.cpp b/src/portduino/wifi-stubs.cpp deleted file mode 120000 index b90e66295..000000000 --- a/src/portduino/wifi-stubs.cpp +++ /dev/null @@ -1 +0,0 @@ -../nrf52/wifi-stubs.cpp \ No newline at end of file diff --git a/src/power.h b/src/power.h index 815e22675..8168e09c0 100644 --- a/src/power.h +++ b/src/power.h @@ -37,6 +37,9 @@ class Power : private concurrency::OSThread /// Setup a simple ADC input based battery sensor bool analogInit(); + + private: + uint8_t low_voltage_counter; }; extern Power *power; \ No newline at end of file diff --git a/src/sleep.cpp b/src/sleep.cpp index ae175eed2..44720b4c5 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -1,9 +1,9 @@ +#include "configuration.h" #include "sleep.h" #include "GPS.h" #include "MeshRadio.h" #include "MeshService.h" #include "NodeDB.h" -#include "configuration.h" #include "error.h" #include "main.h" #include "target_specific.h" @@ -127,7 +127,7 @@ static void waitEnterSleep() delay(100); // Kinda yucky - wait until radio says say we can shutdown (finished in process sends/receives) if (millis() - now > 30 * 1000) { // If we wait too long just report an error and go to sleep - recordCriticalError(CriticalErrorCode_SleepEnterWait); + RECORD_CRITICALERROR(CriticalErrorCode_SleepEnterWait); assert(0); // FIXME - for now we just restart, need to fix bug #167 break; } diff --git a/src/nrf52/wifi-stubs.cpp b/src/wifi-stubs.cpp similarity index 71% rename from src/nrf52/wifi-stubs.cpp rename to src/wifi-stubs.cpp index 6051e195c..87470c528 100644 --- a/src/nrf52/wifi-stubs.cpp +++ b/src/wifi-stubs.cpp @@ -1,11 +1,13 @@ //#include "mesh/wifi/WebServer.h" #include "configuration.h" -#ifndef NO_ESP32 +#ifdef NO_ESP32 //#include "mesh/wifi/WiFiAPClient.h" -void initWifi(bool forceSoftAP) {} +bool initWifi(bool forceSoftAP) { + return false; +} void deinitWifi() {} diff --git a/variants/WisCore_RAK4631_Board/variant.h b/variants/WisCore_RAK4631_Board/variant.h index d882f80d4..bea410c3c 100644 --- a/variants/WisCore_RAK4631_Board/variant.h +++ b/variants/WisCore_RAK4631_Board/variant.h @@ -151,13 +151,14 @@ static const uint8_t SCK = PIN_SPI_SCK; */ // RAK4630 LoRa module -#define SX1262_CS (42) -#define SX1262_DIO1 (47) -#define SX1262_BUSY (46) -#define SX1262_RESET (38) -#define SX1262_TXEN (39) -#define SX1262_RXEN (37) -#define SX1262_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3 +#define USE_SX1262 +#define SX126X_CS (42) +#define SX126X_DIO1 (47) +#define SX126X_BUSY (46) +#define SX126X_RESET (38) +#define SX126X_TXEN (39) +#define SX126X_RXEN (37) +#define SX126X_E22 // DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3 // RAK1910 GPS module // If using the wisblock GPS module and pluged into Port A on WisBlock base @@ -171,8 +172,25 @@ static const uint8_t SCK = PIN_SPI_SCK; #define GPS_RX_PIN PIN_SERIAL1_RX #define GPS_TX_PIN PIN_SERIAL1_TX -// The battery sense is hooked to pin A0 +// Battery +// The battery sense is hooked to pin A0 (5) #define BATTERY_PIN PIN_A0 +// and has 12 bit resolution +#define BATTERY_SENSE_RESOLUTION_BITS 12 +#define BATTERY_SENSE_RESOLUTION 4096.0 +// Definition of milliVolt per LSB => 3.0V ADC range and 12-bit ADC resolution = 3000mV/4096 +#define VBAT_MV_PER_LSB (0.73242188F) +// Voltage divider value => 1.5M + 1M voltage divider on VBAT = (1.5M / (1M + 1.5M)) +#define VBAT_DIVIDER (0.4F) +// Compensation factor for the VBAT divider +#define VBAT_DIVIDER_COMP (1.73) +// Fixed calculation of milliVolt from compensation value +#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB) +#undef AREF_VOLTAGE +#define AREF_VOLTAGE 3.0 +#define VBAT_AR_INTERNAL AR_INTERNAL_3_0 +#define ADC_MULTIPLIER VBAT_DIVIDER_COMP //REAL_VBAT_MV_PER_LSB +#define VBAT_RAW_TO_SCALED(x) (REAL_VBAT_MV_PER_LSB * x) #ifdef __cplusplus } diff --git a/variants/eink0.1/variant.h b/variants/eink0.1/variant.h index 1b30ca21c..b53f04811 100644 --- a/variants/eink0.1/variant.h +++ b/variants/eink0.1/variant.h @@ -178,15 +178,16 @@ External serial flash WP25R1635FZUIL0 * Lora radio */ -#define SX1262_CS (0 + 24) // FIXME - we really should define LORA_CS instead -#define SX1262_DIO1 (0 + 20) +#define USE_SX1262 +#define SX126X_CS (0 + 24) // FIXME - we really should define LORA_CS instead +#define SX126X_DIO1 (0 + 20) // Note DIO2 is attached internally to the module to an analog switch for TX/RX switching #define SX1262_DIO3 \ (0 + 21) // This is used as an *output* from the sx1262 and connected internally to power the tcxo, do not drive from the main // CPU? -#define SX1262_BUSY (0 + 17) -#define SX1262_RESET (0 + 25) -#define SX1262_E22 // Not really an E22 but TTGO seems to be trying to clone that +#define SX126X_BUSY (0 + 17) +#define SX126X_RESET (0 + 25) +#define SX126X_E22 // Not really an E22 but TTGO seems to be trying to clone that // Internally the TTGO module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for the sx1262interface // code) diff --git a/variants/lora_isp4520/variant.h b/variants/lora_isp4520/variant.h index 9bf5cd502..3f26ce3da 100644 --- a/variants/lora_isp4520/variant.h +++ b/variants/lora_isp4520/variant.h @@ -57,10 +57,11 @@ #define WIRE_INTERFACES_COUNT 0 // GPIOs the SX1262 is connected -#define SX1262_CS 1 // aka SPI_NSS -#define SX1262_DIO1 (4) -#define SX1262_BUSY (5) -#define SX1262_RESET (6) +#define USE_SX1262 +#define SX126X_CS 1 // aka SPI_NSS +#define SX126X_DIO1 (4) +#define SX126X_BUSY (5) +#define SX126X_RESET (6) /* * Serial interfaces @@ -91,7 +92,7 @@ #define BATTERY_PIN 3 #define ADC_MULTIPLIER 1.436 -#define SX1262_E22 // Not really an E22 but this board clones using DIO3 for tcxo control +#define SX126X_E22 // Not really an E22 but this board clones using DIO3 for tcxo control #define NO_WIRE #define NO_GPS diff --git a/variants/lora_relay_v1/variant.h b/variants/lora_relay_v1/variant.h index f7ade9586..3ee0406ae 100644 --- a/variants/lora_relay_v1/variant.h +++ b/variants/lora_relay_v1/variant.h @@ -116,22 +116,25 @@ static const uint8_t SCK = PIN_SPI_SCK; // I2C device addresses #define I2C_ADDR_BQ27441 0x55 // Battery gauge +// SX1262 declaration +#define USE_SX1262 + // CUSTOM GPIOs the SX1262 -#define SX1262_CS (32) +#define SX126X_CS (32) // If you would prefer to get console debug output over the JTAG ICE connection rather than the CDC-ACM USB serial device, just // define this. #define USE_SEGGER -#define SX1262_DIO1 (29) +#define SX126X_DIO1 (29) #define SX1262_DIO2 (30) -#define SX1262_BUSY (33) // Supposed to be P0.18 but because of reworks, now on P0.31 (18) -#define SX1262_RESET (34) -// #define SX1262_ANT_SW (32 + 10) -#define SX1262_RXEN (14) -#define SX1262_TXEN (31) -#define SX1262_POWER_EN \ +#define SX126X_BUSY (33) // Supposed to be P0.18 but because of reworks, now on P0.31 (18) +#define SX126X_RESET (34) +// #define SX126X_ANT_SW (32 + 10) +#define SX126X_RXEN (14) +#define SX126X_TXEN (31) +#define SX126X_POWER_EN \ (15) // FIXME, see warning hre https://github.com/BigCorvus/SX1262-LoRa-BLE-Relay/blob/master/LORA_RELAY_NRF52840.ino -#define SX1262_E22 // Indicates this SX1262 is inside of an ebyte E22 module and special config should be done for that +#define SX126X_E22 // Indicates this SX1262 is inside of an ebyte E22 module and special config should be done for that #define ST7735_RESET (11) // Output #define ST7735_CS (12) diff --git a/variants/lora_relay_v2/variant.h b/variants/lora_relay_v2/variant.h index 6814fdb3c..0ff47745e 100644 --- a/variants/lora_relay_v2/variant.h +++ b/variants/lora_relay_v2/variant.h @@ -136,22 +136,25 @@ static const uint8_t SCK = PIN_SPI_SCK; // I2C device addresses #define I2C_ADDR_BQ27441 0x55 // Battery gauge +// SX1262 declaration +#define USE_SX1262 + // CUSTOM GPIOs the SX1262 -#define SX1262_CS (32) +#define SX126X_CS (32) // If you would prefer to get console debug output over the JTAG ICE connection rather than the CDC-ACM USB serial device, just // define this. #define USE_SEGGER -#define SX1262_DIO1 (29) +#define SX126X_DIO1 (29) #define SX1262_DIO2 (30) -#define SX1262_BUSY (33) // Supposed to be P0.18 but because of reworks, now on P0.31 (18) -#define SX1262_RESET (34) -// #define SX1262_ANT_SW (32 + 10) -#define SX1262_RXEN (14) -#define SX1262_TXEN (31) -#define SX1262_POWER_EN \ +#define SX126X_BUSY (33) // Supposed to be P0.18 but because of reworks, now on P0.31 (18) +#define SX126X_RESET (34) +// #define SX126X_ANT_SW (32 + 10) +#define SX126X_RXEN (14) +#define SX126X_TXEN (31) +#define SX126X_POWER_EN \ (15) // FIXME, see warning hre https://github.com/BigCorvus/SX1262-LoRa-BLE-Relay/blob/master/LORA_RELAY_NRF52840.ino -#define SX1262_E22 // Indicates this SX1262 is inside of an ebyte E22 module and special config should be done for that +#define SX126X_E22 // Indicates this SX1262 is inside of an ebyte E22 module and special config should be done for that // ST7565 SPI #define ST7735_RESET (11) // Output diff --git a/variants/pca10056-rc-clock/variant.h b/variants/pca10056-rc-clock/variant.h index 9d35325c8..20aed8cb6 100644 --- a/variants/pca10056-rc-clock/variant.h +++ b/variants/pca10056-rc-clock/variant.h @@ -140,11 +140,12 @@ static const uint8_t SCK = PIN_SPI_SCK; #define EXTERNAL_FLASH_USE_QSPI // CUSTOM GPIOs the SX1262MB2CAS shield when installed on the NRF52840-DK development board -#define SX1262_CS (32 + 8) // P1.08 -#define SX1262_DIO1 (32 + 6) // P1.06 -#define SX1262_BUSY (32 + 4) // P1.04 -#define SX1262_RESET (0 + 3) // P0.03 -#define SX1262_ANT_SW (32 + 10) // P1.10 +#define USE_SX1262 +#define SX126X_CS (32 + 8) // P1.08 +#define SX126X_DIO1 (32 + 6) // P1.06 +#define SX126X_BUSY (32 + 4) // P1.04 +#define SX126X_RESET (0 + 3) // P0.03 +#define SX126X_ANT_SW (32 + 10) // P1.10 // To debug via the segger JLINK console rather than the CDC-ACM serial device // #define USE_SEGGER diff --git a/variants/ppr/variant.h b/variants/ppr/variant.h index bbdda3065..24ddc09ca 100644 --- a/variants/ppr/variant.h +++ b/variants/ppr/variant.h @@ -129,15 +129,16 @@ static const uint8_t SCK = PIN_SPI_SCK; #define PIN_WIRE_SCL (32) // CUSTOM GPIOs the SX1262 -#define SX1262_CS (10) -#define SX1262_DIO1 (20) +#define USE_SX1262 +#define SX126X_CS (10) +#define SX126X_DIO1 (20) #define SX1262_DIO2 (26) -#define SX1262_BUSY (31) // Supposed to be P0.18 but because of reworks, now on P0.31 (18) -#define SX1262_RESET (17) -// #define SX1262_ANT_SW (32 + 10) -#define SX1262_RXEN (22) -#define SX1262_TXEN (24) -#define SX1262_E22 // Indicates this SX1262 is inside of an ebyte E22 module and special config should be done for that +#define SX126X_BUSY (31) // Supposed to be P0.18 but because of reworks, now on P0.31 (18) +#define SX126X_RESET (17) +// #define SX126X_ANT_SW (32 + 10) +#define SX126X_RXEN (22) +#define SX126X_TXEN (24) +#define SX126X_E22 // Indicates this SX1262 is inside of an ebyte E22 module and special config should be done for that // ERC12864-10 LCD #define ERC12864_CS (32 + 4) diff --git a/variants/ppr1/variant.h b/variants/ppr1/variant.h index 04a6e3c06..8b9bc7c13 100644 --- a/variants/ppr1/variant.h +++ b/variants/ppr1/variant.h @@ -152,18 +152,19 @@ static const uint8_t SCK = PIN_SPI_SCK; #define PIN_WIRE_SCL (32) // CUSTOM GPIOs the SX1262 -#define SX1262_CS (0 + 10) // FIXME - we really should define LORA_CS instead -#define SX1262_DIO1 (0 + 20) +#define USE_SX1262 +#define SX126X_CS (0 + 10) // FIXME - we really should define LORA_CS instead +#define SX126X_DIO1 (0 + 20) #define SX1262_DIO2 (0 + 26) -#define SX1262_BUSY (0 + 19) -#define SX1262_RESET (0 + 17) -#define SX1262_TXEN (0 + 24) -#define SX1262_RXEN (0 + 22) -#define SX1262_E22 // Not really an E22 but this board clones using DIO3 for tcxo control +#define SX126X_BUSY (0 + 19) +#define SX126X_RESET (0 + 17) +#define SX126X_TXEN (0 + 24) +#define SX126X_RXEN (0 + 22) +#define SX126X_E22 // Not really an E22 but this board clones using DIO3 for tcxo control // FIXME, to prevent burning out parts I've set the power level super low, because I don't have // an antenna wired up -#define SX1262_MAX_POWER 1 +#define SX126X_MAX_POWER 1 #define LORA_DISABLE_SENDING // Define this to disable transmission for testing (power testing etc...) diff --git a/variants/eink/variant.cpp b/variants/t-echo/variant.cpp similarity index 100% rename from variants/eink/variant.cpp rename to variants/t-echo/variant.cpp diff --git a/variants/eink/variant.h b/variants/t-echo/variant.h similarity index 87% rename from variants/eink/variant.h rename to variants/t-echo/variant.h index 66a42421f..df57ee913 100644 --- a/variants/eink/variant.h +++ b/variants/t-echo/variant.h @@ -92,6 +92,8 @@ Note: Turning off EINK PWR_ON produces no noticeable power savings over just put extern "C" { #endif // __cplusplus +#define TTGO_T_ECHO + // Number of pins defined in PinDescription array #define PINS_COUNT (48) #define NUM_DIGITAL_PINS (48) @@ -178,21 +180,22 @@ External serial flash WP25R1635FZUIL0 * Lora radio */ -#define SX1262_CS (0 + 24) // FIXME - we really should define LORA_CS instead -#define SX1262_DIO1 (0 + 20) +#define USE_SX1262 +#define SX126X_CS (0 + 24) // FIXME - we really should define LORA_CS instead +#define SX126X_DIO1 (0 + 20) // Note DIO2 is attached internally to the module to an analog switch for TX/RX switching #define SX1262_DIO3 \ (0 + 21) // This is used as an *output* from the sx1262 and connected internally to power the tcxo, do not drive from the main // CPU? -#define SX1262_BUSY (0 + 17) -#define SX1262_RESET (0 + 25) -#define SX1262_E22 // Not really an E22 but TTGO seems to be trying to clone that +#define SX126X_BUSY (0 + 17) +#define SX126X_RESET (0 + 25) +#define SX126X_E22 // Not really an E22 but TTGO seems to be trying to clone that // Internally the TTGO module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for the sx1262interface // code) // #define LORA_DISABLE_SENDING // Define this to disable transmission for testing (power testing etc...) -// #undef SX1262_CS +// #undef SX126X_CS // #define USE_SIM_RADIO // define to not use the lora radio hardware at all /* @@ -231,8 +234,6 @@ External serial flash WP25R1635FZUIL0 #define PIN_GPS_TX (32 + 9) // This is for bits going TOWARDS the CPU #define PIN_GPS_RX (32 + 8) // This is for bits going TOWARDS the GPS -#define HAS_AIR530_GPS - #define PIN_SERIAL1_RX PIN_GPS_TX #define PIN_SERIAL1_TX PIN_GPS_RX @@ -251,6 +252,26 @@ External serial flash WP25R1635FZUIL0 // To debug via the segger JLINK console rather than the CDC-ACM serial device // #define USE_SEGGER +// Battery +// The battery sense is hooked to pin A0 (4) +// it is defined in the anlaolgue pin section of this file +// and has 12 bit resolution +#define BATTERY_SENSE_RESOLUTION_BITS 12 +#define BATTERY_SENSE_RESOLUTION 4096.0 +// Definition of milliVolt per LSB => 3.0V ADC range and 12-bit ADC resolution = 3000mV/4096 +#define VBAT_MV_PER_LSB (0.73242188F) +// Voltage divider value => 100K + 100K voltage divider on VBAT = (100K / (100K + 100K)) +#define VBAT_DIVIDER (0.5F) +// Compensation factor for the VBAT divider +#define VBAT_DIVIDER_COMP (2.0) +// Fixed calculation of milliVolt from compensation value +#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB) +#undef AREF_VOLTAGE +#define AREF_VOLTAGE 3.0 +#define VBAT_AR_INTERNAL AR_INTERNAL_3_0 +#define ADC_MULTIPLIER VBAT_DIVIDER_COMP +#define VBAT_RAW_TO_SCALED(x) (REAL_VBAT_MV_PER_LSB * x) + #ifdef __cplusplus } #endif diff --git a/version.properties b/version.properties index e0d2b5841..787339cd5 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 1 minor = 2 -build = 29 +build = 46