diff --git a/.github/actions/setup-build-environment/action.yml b/.github/actions/setup-build-environment/action.yml index 02aaf4249b..cba2d2e562 100644 --- a/.github/actions/setup-build-environment/action.yml +++ b/.github/actions/setup-build-environment/action.yml @@ -25,5 +25,14 @@ runs: - name: Extract Version from Git Tag shell: bash run: | - GIT_TAG_NAME="${GITHUB_REF#refs/tags/}" - echo "GIT_TAG_VERSION=${GIT_TAG_NAME##*-}" >> $GITHUB_ENV + if [[ "${GITHUB_REF}" == refs/tags/* ]]; then + # triggered by a tag push (e.g: refs/tags/companion-v1.2.3) + GIT_TAG_NAME="${GITHUB_REF#refs/tags/}" + VERSION_STRING="${GIT_TAG_NAME##*-}" + else + # triggered by a workflow dispatch (e.g: refs/heads/main) + # strip "refs/heads/" prefix and replace any remaining "/" with "-" to protect file paths + BRANCH_NAME="${GITHUB_REF#refs/heads/}" + VERSION_STRING=$(echo "$BRANCH_NAME" | tr '/' '-') + fi + echo "GIT_TAG_VERSION=${VERSION_STRING}" >> $GITHUB_ENV diff --git a/.github/workflows/build-companion-firmwares.yml b/.github/workflows/build-companion-firmwares.yml index 771fa6d5bc..8fd796f74b 100644 --- a/.github/workflows/build-companion-firmwares.yml +++ b/.github/workflows/build-companion-firmwares.yml @@ -10,33 +10,8 @@ on: - 'companion-*' jobs: - - build: - runs-on: ubuntu-latest - steps: - - - name: Clone Repo - uses: actions/checkout@v6 - - - name: Setup Build Environment - uses: ./.github/actions/setup-build-environment - - - name: Build Firmwares - env: - FIRMWARE_VERSION: ${{ env.GIT_TAG_VERSION }} - run: /usr/bin/env bash build.sh build-companion-firmwares - - - name: Upload Workflow Artifacts - uses: actions/upload-artifact@v7 - with: - name: companion-firmwares - path: out - - - name: Create Release - uses: softprops/action-gh-release@v3 - if: startsWith(github.ref, 'refs/tags/') - with: - name: Companion Firmware ${{ env.GIT_TAG_VERSION }} - body: "" - draft: true - files: out/* \ No newline at end of file + build-companion-firmwares: + uses: ./.github/workflows/firmware-builder.yml + with: + firmware_type: 'companion' + release_title_prefix: 'Companion Firmware' diff --git a/.github/workflows/build-repeater-firmwares.yml b/.github/workflows/build-repeater-firmwares.yml index 3185d4b21c..46b9076cc0 100644 --- a/.github/workflows/build-repeater-firmwares.yml +++ b/.github/workflows/build-repeater-firmwares.yml @@ -10,33 +10,8 @@ on: - 'repeater-*' jobs: - - build: - runs-on: ubuntu-latest - steps: - - - name: Clone Repo - uses: actions/checkout@v6 - - - name: Setup Build Environment - uses: ./.github/actions/setup-build-environment - - - name: Build Firmwares - env: - FIRMWARE_VERSION: ${{ env.GIT_TAG_VERSION }} - run: /usr/bin/env bash build.sh build-repeater-firmwares - - - name: Upload Workflow Artifacts - uses: actions/upload-artifact@v7 - with: - name: repeater-firmwares - path: out - - - name: Create Release - uses: softprops/action-gh-release@v3 - if: startsWith(github.ref, 'refs/tags/') - with: - name: Repeater Firmware ${{ env.GIT_TAG_VERSION }} - body: "" - draft: true - files: out/* \ No newline at end of file + build-repeater-firmwares: + uses: ./.github/workflows/firmware-builder.yml + with: + firmware_type: 'repeater' + release_title_prefix: 'Repeater Firmware' diff --git a/.github/workflows/build-room-server-firmwares.yml b/.github/workflows/build-room-server-firmwares.yml index 127095a8df..c8bd19f7f2 100644 --- a/.github/workflows/build-room-server-firmwares.yml +++ b/.github/workflows/build-room-server-firmwares.yml @@ -10,33 +10,8 @@ on: - 'room-server-*' jobs: - - build: - runs-on: ubuntu-latest - steps: - - - name: Clone Repo - uses: actions/checkout@v6 - - - name: Setup Build Environment - uses: ./.github/actions/setup-build-environment - - - name: Build Firmwares - env: - FIRMWARE_VERSION: ${{ env.GIT_TAG_VERSION }} - run: /usr/bin/env bash build.sh build-room-server-firmwares - - - name: Upload Workflow Artifacts - uses: actions/upload-artifact@v7 - with: - name: room-server-firmwares - path: out - - - name: Create Release - uses: softprops/action-gh-release@v3 - if: startsWith(github.ref, 'refs/tags/') - with: - name: Room Server Firmware ${{ env.GIT_TAG_VERSION }} - body: "" - draft: true - files: out/* \ No newline at end of file + build-room-server-firmwares: + uses: ./.github/workflows/firmware-builder.yml + with: + firmware_type: 'room-server' + release_title_prefix: 'Room Server Firmware' diff --git a/.github/workflows/firmware-builder.yml b/.github/workflows/firmware-builder.yml new file mode 100644 index 0000000000..adc9e42488 --- /dev/null +++ b/.github/workflows/firmware-builder.yml @@ -0,0 +1,90 @@ +name: Firmware Builder + +on: + workflow_call: + inputs: + firmware_type: + required: true + type: string + release_title_prefix: + required: true + type: string + +jobs: + + generate-build-matrix: + runs-on: ubuntu-latest + outputs: + targets: ${{ steps.get-build-targets.outputs.targets }} + steps: + + - name: Clone Repo + uses: actions/checkout@v6 + + - name: Setup Build Environment + uses: ./.github/actions/setup-build-environment + + - name: Get Build Targets + id: get-build-targets + run: | + # get list of firmwares to build + TARGET_LIST=$(/usr/bin/env bash build.sh get-${{ inputs.firmware_type }}-firmwares-to-build) + + # convert targets separated by new line into a json array string + JSON_ARRAY=$(echo "$TARGET_LIST" | jq -R -s -c 'split("\n") | map(select(length > 0))') + + # use json array as targets result + echo "targets=$JSON_ARRAY" >> $GITHUB_OUTPUT + + build: + needs: generate-build-matrix + runs-on: ubuntu-latest + continue-on-error: true # don't fail entire build if one board fails to build + strategy: + matrix: + target: ${{ fromJson(needs.generate-build-matrix.outputs.targets) }} + fail-fast: false # don't cancel other builds if one board fails to build + steps: + + - name: Clone Repo + uses: actions/checkout@v6 + + - name: Setup Build Environment + uses: ./.github/actions/setup-build-environment + + - name: Build Firmware + env: + FIRMWARE_VERSION: ${{ env.GIT_TAG_VERSION }} + run: /usr/bin/env bash build.sh build-firmware ${{ matrix.target }} + + - name: Upload Workflow Artifacts + uses: actions/upload-artifact@v7 + with: + name: "${{ matrix.target }}" + path: out + + create-release: + needs: build + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/') # only create release for tagged builds + steps: + + - name: Clone Repo + uses: actions/checkout@v6 + + - name: Setup Build Environment + uses: ./.github/actions/setup-build-environment + + - name: Download All Artifacts + uses: actions/download-artifact@v8 + with: + merge-multiple: true + path: out + + - name: Create Release + uses: softprops/action-gh-release@v3 + with: + name: "${{ inputs.release_title_prefix }} ${{ env.GIT_TAG_VERSION }}" + body: "" + draft: true + files: out/* diff --git a/.github/workflows/stale-bot.yml b/.github/workflows/stale-bot.yml new file mode 100644 index 0000000000..ec16658756 --- /dev/null +++ b/.github/workflows/stale-bot.yml @@ -0,0 +1,32 @@ +name: 'Run Stale Bot' +on: + schedule: + - cron: '30 1 * * *' # daily at 1:30am + workflow_dispatch: {} + +permissions: + actions: write + issues: write + pull-requests: write + +jobs: + close-issues: + # only run on main repo, not forks + if: github.repository == 'meshcore-dev/MeshCore' + runs-on: ubuntu-latest + steps: + - name: Close Stale Issues + uses: actions/stale@v10 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + # auto close issues + days-before-issue-stale: 60 + days-before-issue-close: 7 + exempt-issue-labels: "keep-open" + stale-issue-label: "stale" + stale-issue-message: "This issue is stale because it has been open for 60 days with no activity. Remove the stale label or add a comment if this issue is still relevant, otherwise this issue will automatically close in 7 days." + close-issue-message: "This issue was closed because it has been inactive for 7 days since being marked as stale." + # don't auto close prs + days-before-pr-stale: -1 + days-before-pr-close: -1 + \ No newline at end of file diff --git a/FLASHING.md b/FLASHING.md new file mode 100644 index 0000000000..1cb0776e0e --- /dev/null +++ b/FLASHING.md @@ -0,0 +1,35 @@ +# Flashing RAK13800 Ethernet Companion Targets + +Use the canonical PlatformIO target names: + +- `RAK_RAK13800_companion_radio_eth` +- `RAK_RAK13800_companion_radio_eth_static_diag` + +These are RAK13800 Ethernet Companion board-support targets built on the RAK4631 MCU platform. The MCU, bootloader, SoftDevice, and board package remain RAK4631 / nRF52840, but the hardware stack being supported is `RAK 4631 / RAK13800 + W5100S`. + +## Production Target + +- Target: `RAK_RAK13800_companion_radio_eth` +- Networking: DHCP first, or DHCP with static fallback +- TCP port: `4403` +- `ETH_DEBUG_LOGGING=0` +- `FORCE_CLIENT_REPEAT=0` +- `MAX_CONTACTS=128` unless RAM testing proves a higher value is safe + +## Static Diagnostic Target + +- Target: `RAK_RAK13800_companion_radio_eth_static_diag` +- IP: `10.245.94.47` +- Gateway: `10.245.94.33` +- DNS: `10.245.94.33` +- Subnet: `255.255.255.224` +- TCP port: `4403` +- `ETH_STATIC_ONLY=1` +- `ETH_DEBUG_LOGGING=1` + +## Compatibility Aliases + +The following names may remain temporarily for compatibility: + +- `RAK_4631_companion_radio_eth_clean` -> `RAK_RAK13800_companion_radio_eth` +- `RAK_4631_companion_radio_eth_static_diag` -> `RAK_RAK13800_companion_radio_eth_static_diag` diff --git a/README.md b/README.md index af56aaf33b..255b2b281e 100644 --- a/README.md +++ b/README.md @@ -34,10 +34,32 @@ MeshCore provides the ability to create wireless mesh networks, similar to Mesht - Flash the MeshCore firmware on a supported device. - Connect with a supported client. +### RAK13800 Ethernet Companion Targets + +- `RAK_RAK13800_companion_radio_eth` is the production board-support target. +- `RAK_RAK13800_companion_radio_eth_static_diag` is the static diagnostic target. +- The old `RAK_4631_companion_radio_eth_clean` and `RAK_4631_companion_radio_eth_static_diag` names remain compatibility aliases only. +- Static diagnostic settings: + - IP `10.245.94.47` + - Gateway `10.245.94.33` + - DNS `10.245.94.33` + - Subnet `255.255.255.224` + - TCP port `4403` + - `ETH_STATIC_ONLY=1` + - `ETH_DEBUG_LOGGING=1` +- Production settings: + - DHCP first or DHCP with static fallback + - TCP port `4403` + - `ETH_DEBUG_LOGGING=0` + - `FORCE_CLIENT_REPEAT=0` + - `MAX_CONTACTS=128` unless RAM testing proves a higher value is safe + For developers: - Install [PlatformIO](https://docs.platformio.org) in [Visual Studio Code](https://code.visualstudio.com). - Clone and open the MeshCore repository in Visual Studio Code. +- The RAK13800 Ethernet Companion board-support targets use the canonical PlatformIO env names `RAK_RAK13800_companion_radio_eth` and `RAK_RAK13800_companion_radio_eth_static_diag`. +- These targets extend the RAK4631 MCU platform, but the supported hardware stack is `RAK 4631 / RAK13800 + W5100S`. - See the example applications you can modify and run: - [Companion Radio](./examples/companion_radio) - For use with an external chat app, over BLE, USB or Wi-Fi. - [KISS Modem](./examples/kiss_modem) - Serial KISS protocol bridge for host applications. ([protocol docs](./docs/kiss_modem_protocol.md)) diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000..a4b2207d55 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,57 @@ +# Security Policy + +## Supported Versions + +Security fixes are applied to the latest release only. We do not backport +fixes to older versions. + +| Version | Supported | +|---------|-----------| +| 1.15+ | ✅ | +| <1.15 | ❌ | + +## Reporting a Vulnerability + +**Please do not report security vulnerabilities through public GitHub issues.** + +Use GitHub's private vulnerability reporting instead: +1. Go to the **Security** tab of this repository +2. Click **Report a vulnerability** +3. Fill in the details and submit + +### What to include + +A useful report tells us: +- Which component or file is affected +- What an attacker can do (impact) and under what conditions +- A minimal reproduction case or proof-of-concept if you have one +- Whether you believe it is remotely exploitable + +You do not need a working exploit to report. An incomplete report is better +than no report. + +## What to expect + +This is a volunteer-maintained open-source project. We will do our best to +respond in a reasonable timeframe, but cannot commit to specific deadlines. + +We ask that you give us a fair opportunity to investigate and address the +issue before any public disclosure. If you have not heard back after +**90 days**, feel free to follow up or proceed with disclosure at your +discretion. + +## Scope + +In scope: +- Remote code execution, memory corruption, or denial-of-service via crafted + radio packets +- Authentication or encryption bypasses +- Vulnerabilities in the packet routing or path handling logic + +Out of scope: +- Physical access attacks (e.g., JTAG, UART extraction of keys) +- Regulatory compliance (duty cycle, frequency restrictions) +- Jamming or other physical-layer radio interference +- Issues in third-party libraries (RadioLib, Crypto, etc.) — report those + upstream +- "Best practice" suggestions without a demonstrated attack path diff --git a/VALIDATION.md b/VALIDATION.md new file mode 100644 index 0000000000..610079e9e4 --- /dev/null +++ b/VALIDATION.md @@ -0,0 +1,30 @@ +# Validation for RAK13800 Ethernet Companion Targets + +Validate the canonical targets: + +- `RAK_RAK13800_companion_radio_eth` +- `RAK_RAK13800_companion_radio_eth_static_diag` + +## What to Verify + +- The target name is the RAK13800 board-support name, not a generic RAK4631 label. +- The build still extends the RAK4631 PlatformIO environment. +- The static diagnostic target keeps: + - IP `10.245.94.47` + - Gateway `10.245.94.33` + - DNS `10.245.94.33` + - Subnet `255.255.255.224` + - TCP port `4403` + - `ETH_STATIC_ONLY=1` + - `ETH_DEBUG_LOGGING=1` +- The production target uses: + - DHCP first or DHCP with static fallback + - TCP port `4403` + - `ETH_DEBUG_LOGGING=0` + - `FORCE_CLIENT_REPEAT=0` + - `MAX_CONTACTS=128` unless RAM testing proves a higher value is safe + +## Compatibility Check + +- Keep `RAK_4631_companion_radio_eth_clean` as an alias to `RAK_RAK13800_companion_radio_eth` if older scripts still use it. +- Keep `RAK_4631_companion_radio_eth_static_diag` as an alias to `RAK_RAK13800_companion_radio_eth_static_diag` if older scripts still use it. diff --git a/build.sh b/build.sh index 313c4c47a0..5402797149 100755 --- a/build.sh +++ b/build.sh @@ -1,5 +1,8 @@ #!/usr/bin/env bash +# exit when any command fails +set -e + global_usage() { cat - <: Build the firmware for the given build target. build-firmwares: Build all firmwares for all targets. build-matching-firmwares : Build all firmwares for build targets containing the string given for . - build-companion-firmwares: Build all companion firmwares for all build targets. + build-companion-firmwares: Build all companion firmwares for all build targets, including RAK_RAK13800 board-support targets. build-repeater-firmwares: Build all repeater firmwares for all build targets. build-room-server-firmwares: Build all chat room server firmwares for all build targets. Examples: -Build firmware for the "RAK_4631_repeater" device target -$ sh build.sh build-firmware RAK_4631_repeater +Build firmware for the "RAK_RAK13800_companion_radio_eth" device target +$ sh build.sh build-firmware RAK_RAK13800_companion_radio_eth -Build all firmwares for device targets containing the string "RAK_4631" +Build all firmwares for device targets containing the string "RAK_RAK13800" $ sh build.sh build-matching-firmwares Build all companion firmwares @@ -39,11 +42,11 @@ Examples: Build without debug logging: $ export FIRMWARE_VERSION=v1.0.0 $ export DISABLE_DEBUG=1 -$ sh build.sh build-firmware RAK_4631_repeater +$ sh build.sh build-firmware RAK_RAK13800_companion_radio_eth Build with debug logging (default, uses flags from variant files): $ export FIRMWARE_VERSION=v1.0.0 -$ sh build.sh build-firmware RAK_4631_repeater +$ sh build.sh build-firmware RAK_RAK13800_companion_radio_eth_static_diag EOF } @@ -275,4 +278,11 @@ elif [[ $1 == "build-repeater-firmwares" ]]; then build_repeater_firmwares elif [[ $1 == "build-room-server-firmwares" ]]; then build_room_server_firmwares +elif [[ $1 == "get-companion-firmwares-to-build" ]]; then + get_pio_envs_ending_with_string "_companion_radio_usb" + get_pio_envs_ending_with_string "_companion_radio_ble" +elif [[ $1 == "get-repeater-firmwares-to-build" ]]; then + get_pio_envs_ending_with_string "_repeater" +elif [[ $1 == "get-room-server-firmwares-to-build" ]]; then + get_pio_envs_ending_with_string "_room_server" fi diff --git a/docs/cli_commands.md b/docs/cli_commands.md index 819b613337..5598dba550 100644 --- a/docs/cli_commands.md +++ b/docs/cli_commands.md @@ -29,12 +29,25 @@ This document provides an overview of CLI commands that can be sent to MeshCore **Usage:** - `reboot` +**Note:** No reply is sent. + +--- + +### Power-off the node +**Usage:** +- `poweroff`, or +- `shutdown` + +**Note:** No reply is sent. + --- ### Reset the clock and reboot **Usage:** - `clkreboot` +**Note:** No reply is sent. + --- ### Sync the clock with the remote device @@ -661,10 +674,21 @@ This document provides an overview of CLI commands that can be sent to MeshCore **Parameters:** - `value`: Maximum flood hop count (0-64) for a packet without a scope (no region set) -**Default:** `0xFF` - indicates it hasn't been set, will track flood.max until it is. +**Default:** `64` - (`0xFF` indicates it hasn't been set, will track flood.max until it is.) **Note:** An alternative to `region denyf *`, setting `flood.max.unscoped` to a lower value such as `3` would allow for local unscoped messages to propagate, while preventing noisy neighbors from flooding a local region. +--- + +#### Limit the number of hops for an advert flood message +**Usage:** +- `get flood.max.advert` +- `set flood.max.advert ` + +**Parameters:** +- `value`: Maximum flood hop count (0-64) for an advert packet + +**Default:** `8` --- diff --git a/docs/qr_codes.md b/docs/qr_codes.md index 364efa8acc..3516a76a49 100644 --- a/docs/qr_codes.md +++ b/docs/qr_codes.md @@ -12,8 +12,10 @@ meshcore://channel/add?name=Public&secret=8b3387e9c5cdea6ac9e5edbaa115cd72 **Parameters**: -- `name`: Channel name (URL-encoded if needed) +- `name`: Channel name (URL-encoded) - `secret`: 16-byte secret represented as 32 hex characters +- `region_scope`: Region Scope (optional, URL-encoded if provided) + - Supported by MeshCore App v1.47.0+ ## Add Contact diff --git a/variants/rak4631/platformio.ini b/variants/rak4631/platformio.ini index 31b507b4c2..3014f30ab5 100644 --- a/variants/rak4631/platformio.ini +++ b/variants/rak4631/platformio.ini @@ -228,6 +228,63 @@ lib_deps = ${rak4631.lib_deps} densaugeo/base64 @ ~1.4.0 +[env:RAK_RAK13800_companion_radio_eth] +extends = rak4631 +board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld +board_upload.maximum_size = 712704 +build_flags = + ${rak4631.build_flags} + -I examples/companion_radio/ui-new + -D PIN_USER_BTN=9 + -D PIN_USER_BTN_ANA=31 + -D DISPLAY_CLASS=SSD1306Display + -D MAX_CONTACTS=128 + -D MAX_GROUP_CHANNELS=40 + -D ETH_DEBUG_LOGGING=0 + -D FORCE_CLIENT_REPEAT=0 + -D ADVERT_NAME='"RAK4631 RAK13800 Eth"' +; -D MESH_PACKET_LOGGING=1 +; -D MESH_DEBUG=1 +build_src_filter = ${rak4631.build_src_filter} + + + +<../examples/companion_radio/*.cpp> + +<../examples/companion_radio/ui-new/*.cpp> +lib_deps = + ${rak4631.lib_deps} + densaugeo/base64 @ ~1.4.0 + +[env:RAK_RAK13800_companion_radio_eth_static_diag] +extends = rak4631 +board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld +board_upload.maximum_size = 712704 +build_flags = + ${rak4631.build_flags} + -I examples/companion_radio/ui-new + -D PIN_USER_BTN=9 + -D PIN_USER_BTN_ANA=31 + -D DISPLAY_CLASS=SSD1306Display + -D MAX_CONTACTS=128 + -D MAX_GROUP_CHANNELS=40 + -D ETH_STATIC_ONLY=1 + -D ETH_DEBUG_LOGGING=1 + -D FORCE_CLIENT_REPEAT=0 + -D ADVERT_NAME='"RAK4631 RAK13800 Eth Diag"' +; -D MESH_PACKET_LOGGING=1 +; -D MESH_DEBUG=1 +build_src_filter = ${rak4631.build_src_filter} + + + +<../examples/companion_radio/*.cpp> + +<../examples/companion_radio/ui-new/*.cpp> +lib_deps = + ${rak4631.lib_deps} + densaugeo/base64 @ ~1.4.0 + +[env:RAK_4631_companion_radio_eth_clean] +extends = RAK_RAK13800_companion_radio_eth + +[env:RAK_4631_companion_radio_eth_static_diag] +extends = RAK_RAK13800_companion_radio_eth_static_diag + [env:RAK_4631_terminal_chat] extends = rak4631 build_flags =