diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 6eba5cc..8db5e30 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -10,3 +10,21 @@
- [ ] All top level messages commented
- [ ] All enum members have unique descriptions
+
+
+### New Hardware Model Acceptance Policy
+
+Due to limited availability and ongoing support, new Hardware Models will only be accepted from [Meshtastic Backers and Partners](https://meshtastic.com/). The Meshtastic team reserves the right to make exceptions to this policy.
+
+#### Alternative for Community Contributors
+
+You are welcome to use one of the existing DIY hardware models in your PlatformIO environment and create a pull request in the firmware project. Please note the following conditions:
+
+- The device will **not** be officially supported by the core Meshtastic team.
+- The device will **not** appear in the [Web Flasher](https://flasher.meshtastic.org/) or Github release assets.
+- You will be responsible for ongoing maintenance and support.
+- Community-contributed / DIY hardware models are considered experimental and will likely have limited or no testing.
+
+#### Getting Official Support
+
+To have your hardware model officially supported and included in the Meshtastic ecosystem, consider becoming a Meshtastic Backer or Partner. Visit [meshtastic.com](https://meshtastic.com/) for more information about partnership opportunities.
diff --git a/.github/workflows/create_tag.yml b/.github/workflows/create_tag.yml
index 482ea79..a1e9768 100644
--- a/.github/workflows/create_tag.yml
+++ b/.github/workflows/create_tag.yml
@@ -50,7 +50,7 @@ jobs:
echo "NEW_VERSION=v$MAJOR.$MINOR.$PATCH" >> $GITHUB_OUTPUT
- name: Create release
- uses: ncipollo/release-action@v1.13.0
+ uses: ncipollo/release-action@v1
with:
name: Meshtastic Protobufs ${{ steps.version.outputs.NEW_VERSION }}
tag: ${{ steps.version.outputs.NEW_VERSION }}
@@ -58,14 +58,14 @@ jobs:
token: ${{ github.token }}
- name: Setup Buf
- uses: bufbuild/buf-setup-action@v1.26.1
+ uses: bufbuild/buf-action@v1.2.0
with:
github_token: ${{ github.token }}
+ token: ${{ secrets.BUF_TOKEN }}
+ setup_only: true
- name: Push to schema registry
- # uses: bufbuild/buf-push-action@v1
- # with:
- # buf_token: ${{ secrets.BUF_TOKEN }}
+ env:
+ BUF_TOKEN: ${{ secrets.BUF_TOKEN }}
run: |
- export BUF_TOKEN=${{ secrets.BUF_TOKEN }}
buf push --tag ${{ steps.version.outputs.NEW_VERSION }}
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index a54687d..6c61aed 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -1,30 +1,263 @@
-name: Push new version to schema registry
-
-permissions:
- contents: read
+name: Publish to JSR & NPM
on:
push:
tags:
- - "**"
+ - "v*"
+ workflow_dispatch:
+ inputs:
+ version:
+ description: "Version to publish (e.g. v1.2.3). Used when manually dispatching."
+ required: false
+ type: string
+ dry_run:
+ description: "Dry run mode - generate artifacts without publishing"
+ required: false
+ type: boolean
+ default: false
+
+permissions:
+ contents: write
+ id-token: write
jobs:
- push_to_registry:
- runs-on: ubuntu-latest
+ codegen:
+ runs-on: ubuntu-24.04
+ outputs:
+ version: ${{ steps.version.outputs.VERSION }}
+ tag: ${{ steps.version.outputs.TAG }}
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ - name: Determine version
+ id: version
+ run: |
+ set -euo pipefail
+ if [ "${{ github.ref_type }}" = "tag" ]; then
+ TAG="${{ github.ref_name }}"
+ elif [ -n "${{ inputs.version || '' }}" ]; then
+ TAG="${{ inputs.version }}"
+ else
+ echo "No tag ref and no 'version' input. Provide a tag (push a tag) or pass inputs.version." >&2
+ exit 1
+ fi
+ VERSION="${TAG#v}"
+ echo "VERSION=$VERSION" >> "$GITHUB_OUTPUT"
+ echo "TAG=$TAG" >> "$GITHUB_OUTPUT"
+ echo "Resolved VERSION=$VERSION, TAG=$TAG"
+
+ - name: Setup Buf
+ uses: bufbuild/buf-setup-action@main
+ with:
+ github_token: ${{ github.token }}
+
+ - name: Generate protobuf code
+ run: buf generate
+
+ - name: Move generated files to lib root
+ run: |
+ set -euo pipefail
+ src_dir="packages/ts/lib/meshtastic"
+ dest_dir="packages/ts/lib"
+
+ if [ ! -d "$src_dir" ]; then
+ echo "Expected source directory '$src_dir' does not exist. 'buf generate' may have failed or changed its output paths." >&2
+ exit 1
+ fi
+
+ if ! compgen -G "$src_dir"/*_pb.ts > /dev/null; then
+ echo "No '*_pb.ts' files found in '$src_dir'. 'buf generate' may have produced no TypeScript files or changed their naming." >&2
+ exit 1
+ fi
+
+ mv "$src_dir"/*_pb.ts "$dest_dir"/
+ - name: Show generated files
+ run: |
+ echo "=== packages/ts contents ==="
+ ls -la packages/ts/
+ echo "=== packages/ts/lib contents ==="
+ ls -la packages/ts/lib/ || echo "lib folder not found"
+
+ - name: Set package versions
+ run: |
+ set -euo pipefail
+ VERSION="${{ steps.version.outputs.VERSION }}"
+ for f in packages/ts/deno.json packages/ts/package.json; do
+ test -f "$f" || { echo "Missing $f" >&2; exit 1; }
+ sed -i "s/__PACKAGE_VERSION__/${VERSION}/g" "$f"
+ done
+
+ - name: Copy license & README
+ run: cp LICENSE README.md packages/ts/
+
+ - name: Upload TypeScript code
+ uses: actions/upload-artifact@v4
+ with:
+ name: ts_code
+ path: packages/ts
+
+ build-typescript:
+ runs-on: ubuntu-24.04
+ needs: codegen
+ steps:
+ - name: Download TypeScript code
+ uses: actions/download-artifact@v4
+ with:
+ name: ts_code
+
+ - name: Show downloaded files
+ run: |
+ echo "=== Working directory ==="
+ pwd
+ echo "=== Contents ==="
+ ls -la
+ echo "=== lib/ contents ==="
+ ls -la lib/ || echo "lib folder not found"
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: "22"
+
+ - name: Install dependencies
+ run: npm install
+
+ - name: Build with tsdown
+ run: npm run build
+
+ - name: Show build output
+ run: |
+ echo "=== Build output ==="
+ ls -la
+ ls -la dist/
+
+ - name: Upload built NPM package
+ uses: actions/upload-artifact@v4
+ with:
+ name: npm_package
+ path: |
+ dist/
+ package.json
+ LICENSE
+ README.md
+
+ - name: Upload JSR package
+ uses: actions/upload-artifact@v4
+ with:
+ name: jsr_package
+ path: |
+ lib/
+ mod.ts
+ deno.json
+ LICENSE
+ README.md
+
+ create-release-zips:
+ runs-on: ubuntu-24.04
+ needs: [codegen, build-typescript]
+ steps:
+ - name: Download NPM package
+ uses: actions/download-artifact@v4
+ with:
+ name: npm_package
+ path: npm_package
+
+ - name: Download JSR package
+ uses: actions/download-artifact@v4
+ with:
+ name: jsr_package
+ path: jsr_package
+
+ - name: Create zip archives
+ run: |
+ cd npm_package && zip -r ../meshtastic-protobufs-npm.zip . && cd ..
+ cd jsr_package && zip -r ../meshtastic-protobufs-jsr.zip . && cd ..
+
+ - name: Upload release zips
+ uses: actions/upload-artifact@v4
+ with:
+ name: release_zips
+ path: |
+ meshtastic-protobufs-npm.zip
+ meshtastic-protobufs-jsr.zip
+
+ upload-release-assets:
+ runs-on: ubuntu-24.04
+ needs: [codegen, create-release-zips]
+ if: ${{ !inputs.dry_run }}
+ steps:
+ - name: Download release zips
+ uses: actions/download-artifact@v4
+ with:
+ name: release_zips
+
+ - name: Upload assets to GitHub release
+ uses: softprops/action-gh-release@v2
+ with:
+ tag_name: ${{ needs.codegen.outputs.tag }}
+ files: |
+ meshtastic-protobufs-npm.zip
+ meshtastic-protobufs-jsr.zip
+
+ push-buf-registry:
+ runs-on: ubuntu-24.04
+ needs: codegen
+ if: ${{ !inputs.dry_run }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Buf
- uses: bufbuild/buf-setup-action@v1.26.1
+ uses: bufbuild/buf-setup-action@main
with:
github_token: ${{ github.token }}
- name: Push to schema registry
- # uses: bufbuild/buf-push-action@v1
- # with:
- # buf_token: ${{ secrets.BUF_TOKEN }}
- run: |
- export BUF_TOKEN=${{ secrets.BUF_TOKEN }}
- buf push --tag ${{ github.ref_name }}
+ env:
+ BUF_TOKEN: ${{ secrets.BUF_TOKEN }}
+ run: buf push --tag ${{ needs.codegen.outputs.tag }}
+
+ publish-npm:
+ runs-on: ubuntu-24.04
+ needs: [codegen, build-typescript]
+ if: ${{ !inputs.dry_run }}
+ steps:
+ - name: Download NPM package
+ uses: actions/download-artifact@v4
+ with:
+ name: npm_package
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: "22"
+ registry-url: "https://registry.npmjs.org"
+
+ - name: Publish to NPM
+ run: npm publish --access public
+ env:
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
+
+ publish-jsr:
+ runs-on: ubuntu-24.04
+ needs: [codegen, build-typescript]
+ if: ${{ !inputs.dry_run }}
+ permissions:
+ contents: read
+ id-token: write
+ steps:
+ - name: Download JSR package
+ uses: actions/download-artifact@v4
+ with:
+ name: jsr_package
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: "22"
+
+ - name: Publish to JSR
+ run: npx jsr publish
diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml
index 598c808..6df3b32 100644
--- a/.github/workflows/pull_request.yml
+++ b/.github/workflows/pull_request.yml
@@ -2,6 +2,7 @@ name: pull-request
permissions:
contents: read
+ pull-requests: write
on: pull_request
jobs:
@@ -12,16 +13,11 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4
- - name: Setup Buf
- uses: bufbuild/buf-setup-action@v1.26.1
+ - name: Buf PR Checks
+ uses: bufbuild/buf-action@v1.2.0
with:
github_token: ${{ github.token }}
-
- - name: Lint
- uses: bufbuild/buf-lint-action@v1.0.3
-
- - name: Push to schema registry
- uses: bufbuild/buf-push-action@v1.1.1
- with:
- buf_token: ${{ secrets.BUF_TOKEN }}
- draft: ${{ github.ref_name != 'master'}}
+ token: ${{ secrets.BUF_TOKEN }}
+ format: true
+ lint: true
+ breaking: true
diff --git a/.github/workflows/ci.yml b/.github/workflows/schema-registry.yml
similarity index 67%
rename from .github/workflows/ci.yml
rename to .github/workflows/schema-registry.yml
index 9322ba5..f38ad9f 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/schema-registry.yml
@@ -16,12 +16,9 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4
- - name: Setup Buf
- uses: bufbuild/buf-setup-action@v1.26.1
+ - name: Push to schema registry
+ uses: bufbuild/buf-action@v1.2.0
with:
github_token: ${{ github.token }}
-
- - name: Push to schema registry
- uses: bufbuild/buf-push-action@v1.1.1
- with:
- buf_token: ${{ secrets.BUF_TOKEN }}
+ token: ${{ secrets.BUF_TOKEN }}
+ push: true
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..dd68173
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+.DS_Store
+
+# Generated protobuf files
+packages/ts/lib/
+.bin/
diff --git a/.trunk/.gitignore b/.trunk/.gitignore
deleted file mode 100644
index 1e24652..0000000
--- a/.trunk/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-*out
-*logs
-*actions
-*notifications
-*tools
-plugins
-user_trunk.yaml
-user.yaml
diff --git a/.trunk/configs/.markdownlint.yaml b/.trunk/configs/.markdownlint.yaml
deleted file mode 100644
index fb94039..0000000
--- a/.trunk/configs/.markdownlint.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-# Autoformatter friendly markdownlint config (all formatting rules disabled)
-default: true
-blank_lines: false
-bullet: false
-html: false
-indentation: false
-line_length: false
-spaces: false
-url: false
-whitespace: false
diff --git a/.trunk/configs/.yamllint.yaml b/.trunk/configs/.yamllint.yaml
deleted file mode 100644
index 4d44466..0000000
--- a/.trunk/configs/.yamllint.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-rules:
- quoted-strings:
- required: only-when-needed
- extra-allowed: ["{|}"]
- empty-values:
- forbid-in-block-mappings: true
- forbid-in-flow-mappings: true
- key-duplicates: {}
- octal-values:
- forbid-implicit-octal: true
diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml
deleted file mode 100644
index acdfaad..0000000
--- a/.trunk/trunk.yaml
+++ /dev/null
@@ -1,33 +0,0 @@
-version: 0.1
-cli:
- version: 1.16.2
-plugins:
- sources:
- - id: trunk
- ref: v1.2.5
- uri: https://github.com/trunk-io/plugins
-lint:
- enabled:
- - checkov@2.4.9
- - trivy@0.45.1
- - trufflehog@3.57.0
- - yamllint@1.32.0
- - buf-lint@1.26.1
- - buf-breaking@1.26.1
- - actionlint@1.6.26
- - markdownlint@0.37.0
- - prettier@3.0.3
- - gitleaks@8.18.0
- - git-diff-check
-runtimes:
- enabled:
- - python@3.10.8
- - go@1.21.0
- - node@18.12.1
-actions:
- disabled:
- - trunk-announce
- - trunk-check-pre-push
- - trunk-fmt-pre-commit
- enabled:
- - trunk-upgrade-available
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index 56e433b..157b291 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -1,3 +1,3 @@
{
- "recommendations": ["trunk.io", "pbkit.vscode-pbkit", "bufbuild.vscode-buf"]
+ "recommendations": ["pbkit.vscode-pbkit", "bufbuild.vscode-buf"]
}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 3b48997..60415c3 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,4 +1,4 @@
{
"editor.formatOnSave": true,
- "editor.defaultFormatter": "trunk.io"
+ "editor.defaultFormatter": "pbkit.vscode-pbkit"
}
diff --git a/buf.gen.yaml b/buf.gen.yaml
new file mode 100644
index 0000000..652f41a
--- /dev/null
+++ b/buf.gen.yaml
@@ -0,0 +1,5 @@
+version: v2
+plugins:
+ - remote: buf.build/bufbuild/es:v2.1.0
+ out: packages/ts/lib
+ opt: target=ts,import_extension=.ts
diff --git a/buf.yaml b/buf.yaml
index 642e538..2a93588 100644
--- a/buf.yaml
+++ b/buf.yaml
@@ -1,14 +1,23 @@
-version: v1
-name: buf.build/meshtastic/protobufs
-deps: []
-build:
- excludes: []
-breaking:
- use:
- - FILE
-lint:
- ignore_only:
- PACKAGE_DEFINED:
- - nanopb.proto
- use:
- - MINIMAL
+version: v2
+modules:
+ - path: .
+ name: buf.build/meshtastic/protobufs
+ excludes:
+ - .trunk/
+ - meshtastic/device_only/
+ lint:
+ use:
+ - MINIMAL
+ except:
+ - PACKAGE_NO_IMPORT_CYCLE
+ ignore_only:
+ PACKAGE_DEFINED:
+ - nanopb.proto
+ disallow_comment_ignores: true
+ breaking:
+ use:
+ - FILE
+ except:
+ - EXTENSION_NO_DELETE
+ - FIELD_SAME_DEFAULT
+
diff --git a/meshtastic/admin.options b/meshtastic/admin.options
index 1d582e2..6574db5 100644
--- a/meshtastic/admin.options
+++ b/meshtastic/admin.options
@@ -1,5 +1,14 @@
*AdminMessage.payload_variant anonymous_oneof:true
+*AdminMessage.session_passkey max_size:8
+
+*AdminMessage.OTAEvent.ota_hash max_size:32
+
+*AdminMessage.InputEvent.event_code int_size:8
+*AdminMessage.InputEvent.kb_char int_size:8
+*AdminMessage.InputEvent.touch_x int_size:16
+*AdminMessage.InputEvent.touch_y int_size:16
+
*AdminMessage.set_canned_message_module_messages max_size:201
*AdminMessage.get_canned_message_module_messages_response max_size:201
*AdminMessage.delete_file_request max_size:201
@@ -8,5 +17,5 @@
*AdminMessage.get_ringtone_response max_size:231
*HamParameters.call_sign max_size:8
-*HamParameters.short_name max_size:6
-*NodeRemoteHardwarePinsResponse.node_remote_hardware_pins max_count:16
\ No newline at end of file
+*HamParameters.short_name max_size:5
+*NodeRemoteHardwarePinsResponse.node_remote_hardware_pins max_count:16
diff --git a/meshtastic/admin.proto b/meshtastic/admin.proto
index cd6de55..ac29cc8 100644
--- a/meshtastic/admin.proto
+++ b/meshtastic/admin.proto
@@ -2,17 +2,18 @@ syntax = "proto3";
package meshtastic;
+/* trunk-ignore(buf-lint/COMPILE) */
import "meshtastic/channel.proto";
import "meshtastic/config.proto";
import "meshtastic/connection_status.proto";
-import "meshtastic/deviceonly.proto";
+import "meshtastic/device_ui.proto";
import "meshtastic/mesh.proto";
import "meshtastic/module_config.proto";
option csharp_namespace = "Meshtastic.Protobufs";
option go_package = "github.com/meshtastic/go/generated";
option java_outer_classname = "AdminProtos";
-option java_package = "com.geeksville.mesh";
+option java_package = "org.meshtastic.proto";
option swift_prefix = "";
/*
@@ -21,6 +22,13 @@ option swift_prefix = "";
* (Prior to 1.2 these operations were done via special ToRadio operations)
*/
message AdminMessage {
+ /*
+ * The node generates this key and sends it with any get_x_response packets.
+ * The client MUST include the same key with any set_x commands. Key expires after 300 seconds.
+ * Prevents replay attacks for admin messages.
+ */
+ bytes session_passkey = 101;
+
/*
* TODO: REPLACE
*/
@@ -59,6 +67,21 @@ message AdminMessage {
* TODO: REPLACE
*/
BLUETOOTH_CONFIG = 6;
+
+ /*
+ * TODO: REPLACE
+ */
+ SECURITY_CONFIG = 7;
+
+ /*
+ * Session key config
+ */
+ SESSIONKEY_CONFIG = 8;
+
+ /*
+ * device-ui config
+ */
+ DEVICEUI_CONFIG = 9;
}
/*
@@ -129,6 +152,72 @@ message AdminMessage {
* TODO: REPLACE
*/
PAXCOUNTER_CONFIG = 12;
+
+ /*
+ * TODO: REPLACE
+ */
+ STATUSMESSAGE_CONFIG = 13;
+
+ /*
+ * Traffic management module config
+ */
+ TRAFFICMANAGEMENT_CONFIG = 14;
+
+ /*
+ * TAK module config
+ */
+ TAK_CONFIG = 15;
+ }
+
+ enum BackupLocation {
+ /*
+ * Backup to the internal flash
+ */
+ FLASH = 0;
+
+ /*
+ * Backup to the SD card
+ */
+ SD = 1;
+ }
+
+ /*
+ * Input event message to be sent to the node.
+ */
+ message InputEvent {
+ /*
+ * The input event code
+ */
+ uint32 event_code = 1;
+ /*
+ * Keyboard character code
+ */
+ uint32 kb_char = 2;
+ /*
+ * The touch X coordinate
+ */
+ uint32 touch_x = 3;
+ /*
+ * The touch Y coordinate
+ */
+ uint32 touch_y = 4;
+ }
+
+ /*
+ * User is requesting an over the air update.
+ * Node will reboot into the OTA loader
+ */
+ message OTAEvent {
+ /*
+ * Tell the node to reboot into OTA mode for firmware update via BLE or WiFi (ESP32 only for now)
+ */
+ OTAMode reboot_ota_mode = 1;
+
+ /*
+ * A 32 byte hash of the OTA firmware.
+ * Used to verify the integrity of the firmware before applying an update.
+ */
+ bytes ota_hash = 2;
}
/*
@@ -242,6 +331,32 @@ message AdminMessage {
*/
string delete_file_request = 22;
+ /*
+ * Set zero and offset for scale chips
+ */
+ uint32 set_scale = 23;
+
+ /*
+ * Backup the node's preferences
+ */
+ BackupLocation backup_preferences = 24;
+
+ /*
+ * Restore the node's preferences
+ */
+ BackupLocation restore_preferences = 25;
+
+ /*
+ * Remove backups of the node's preferences
+ */
+ BackupLocation remove_backup_preferences = 26;
+
+ /*
+ * Send an input event to the node.
+ * This is used to trigger physical input events like button presses, touch events, etc.
+ */
+ InputEvent send_input_event = 27;
+
/*
* Set the owner for this node
*/
@@ -280,7 +395,7 @@ message AdminMessage {
* Remove the node by the specified node-num from the NodeDB on the device
*/
uint32 remove_by_nodenum = 38;
-
+
/*
* Set specified node-num to be favorited on the NodeDB on the device
*/
@@ -291,6 +406,52 @@ message AdminMessage {
*/
uint32 remove_favorite_node = 40;
+ /*
+ * Set fixed position data on the node and then set the position.fixed_position = true
+ */
+ Position set_fixed_position = 41;
+
+ /*
+ * Clear fixed position coordinates and then set position.fixed_position = false
+ */
+ bool remove_fixed_position = 42;
+
+ /*
+ * Set time only on the node
+ * Convenience method to set the time on the node (as Net quality) without any other position data
+ */
+ fixed32 set_time_only = 43;
+
+ /*
+ * Tell the node to send the stored ui data.
+ */
+ bool get_ui_config_request = 44;
+
+ /*
+ * Reply stored device ui data.
+ */
+ DeviceUIConfig get_ui_config_response = 45;
+
+ /*
+ * Tell the node to store UI data persistently.
+ */
+ DeviceUIConfig store_ui_config = 46;
+
+ /*
+ * Set specified node-num to be ignored on the NodeDB on the device
+ */
+ uint32 set_ignored_node = 47;
+
+ /*
+ * Set specified node-num to be un-ignored on the NodeDB on the device
+ */
+ uint32 remove_ignored_node = 48;
+
+ /*
+ * Set specified node-num to be muted
+ */
+ uint32 toggle_muted_node = 49;
+
/*
* Begins an edit transaction for config, module config, owner, and channel settings changes
* This will delay the standard *implicit* save to the file system and subsequent reboot behavior until committed (commit_edit_settings)
@@ -302,11 +463,27 @@ message AdminMessage {
*/
bool commit_edit_settings = 65;
+ /*
+ * Add a contact (User) to the nodedb
+ */
+ SharedContact add_contact = 66;
+
+ /*
+ * Initiate or respond to a key verification request
+ */
+ KeyVerificationAdmin key_verification = 67;
+
+ /*
+ * Tell the node to factory reset config everything; all device state and configuration will be returned to factory defaults and BLE bonds will be cleared.
+ */
+ int32 factory_reset_device = 94;
+
/*
* Tell the node to reboot into the OTA Firmware in this many seconds (or <0 to cancel reboot)
* Only Implemented for ESP32 Devices. This needs to be issued to send a new main firmware via bluetooth.
+ * Deprecated in favor of reboot_ota_mode in 2.7.17
*/
- int32 reboot_ota_seconds = 95;
+ int32 reboot_ota_seconds = 95 [deprecated = true];
/*
* This message is only supported for the simulator Portduino build.
@@ -325,17 +502,48 @@ message AdminMessage {
int32 shutdown_seconds = 98;
/*
- * Tell the node to factory reset, all device settings will be returned to factory defaults.
+ * Tell the node to factory reset config; all device state and configuration will be returned to factory defaults; BLE bonds will be preserved.
*/
- int32 factory_reset = 99;
+ int32 factory_reset_config = 99;
/*
* Tell the node to reset the nodedb.
+ * When true, favorites are preserved through reset.
*/
- int32 nodedb_reset = 100;
+ bool nodedb_reset = 100;
+
+ /*
+ * Tell the node to reset into the OTA Loader
+ */
+ OTAEvent ota_request = 102;
+
+ /*
+ * Parameters and sensor configuration
+ */
+ SensorConfig sensor_config = 103;
}
}
+/*
+ * Firmware update mode for OTA updates
+ */
+enum OTAMode {
+ /*
+ * Do not reboot into OTA mode
+ */
+ NO_REBOOT_OTA = 0;
+
+ /*
+ * Reboot into OTA mode for BLE firmware update
+ */
+ OTA_BLE = 1;
+
+ /*
+ * Reboot into OTA mode for WiFi firmware update
+ */
+ OTA_WIFI = 2;
+}
+
/*
* Parameters for setting up Meshtastic for ameteur radio usage
*/
@@ -372,3 +580,183 @@ message NodeRemoteHardwarePinsResponse {
*/
repeated NodeRemoteHardwarePin node_remote_hardware_pins = 1;
}
+
+message SharedContact {
+ /*
+ * The node number of the contact
+ */
+ uint32 node_num = 1;
+
+ /*
+ * The User of the contact
+ */
+ User user = 2;
+
+ /*
+ * Add this contact to the blocked / ignored list
+ */
+ bool should_ignore = 3;
+
+ /*
+ * Set the IS_KEY_MANUALLY_VERIFIED bit
+ */
+ bool manually_verified = 4;
+}
+
+/*
+ * This message is used by a client to initiate or complete a key verification
+ */
+message KeyVerificationAdmin {
+ /*
+ * Three stages of this request.
+ */
+ enum MessageType {
+ /*
+ * This is the first stage, where a client initiates
+ */
+ INITIATE_VERIFICATION = 0;
+
+ /*
+ * After the nonce has been returned over the mesh, the client prompts for the security number
+ * And uses this message to provide it to the node.
+ */
+ PROVIDE_SECURITY_NUMBER = 1;
+
+ /*
+ * Once the user has compared the verification message, this message notifies the node.
+ */
+ DO_VERIFY = 2;
+
+ /*
+ * This is the cancel path, can be taken at any point
+ */
+ DO_NOT_VERIFY = 3;
+ }
+
+ MessageType message_type = 1;
+
+ /*
+ * The nodenum we're requesting
+ */
+ uint32 remote_nodenum = 2;
+
+ /*
+ * The nonce is used to track the connection
+ */
+ uint64 nonce = 3;
+
+ /*
+ * The 4 digit code generated by the remote node, and communicated outside the mesh
+ */
+ optional uint32 security_number = 4;
+}
+
+message SensorConfig {
+ /*
+ * SCD4X CO2 Sensor configuration
+ */
+ SCD4X_config scd4x_config = 1;
+
+ /*
+ * SEN5X PM Sensor configuration
+ */
+ SEN5X_config sen5x_config = 2;
+
+ /*
+ * SCD30 CO2 Sensor configuration
+ */
+ SCD30_config scd30_config = 3;
+
+ /*
+ * SHTXX temperature and relative humidity sensor configuration
+ */
+ SHTXX_config shtxx_config = 4;
+}
+
+message SCD4X_config {
+ /*
+ * Set Automatic self-calibration enabled
+ */
+ optional bool set_asc = 1;
+
+ /*
+ * Recalibration target CO2 concentration in ppm (FRC or ASC)
+ */
+ optional uint32 set_target_co2_conc = 2;
+
+ /*
+ * Reference temperature in degC
+ */
+ optional float set_temperature = 3;
+
+ /*
+ * Altitude of sensor in meters above sea level. 0 - 3000m (overrides ambient pressure)
+ */
+ optional uint32 set_altitude = 4;
+
+ /*
+ * Sensor ambient pressure in Pa. 70000 - 120000 Pa (overrides altitude)
+ */
+ optional uint32 set_ambient_pressure = 5;
+
+ /*
+ * Perform a factory reset of the sensor
+ */
+ optional bool factory_reset = 6;
+
+ /*
+ * Power mode for sensor (true for low power, false for normal)
+ */
+ optional bool set_power_mode = 7;
+}
+
+message SEN5X_config {
+ /*
+ * Reference temperature in degC
+ */
+ optional float set_temperature = 1;
+
+ /*
+ * One-shot mode (true for low power - one-shot mode, false for normal - continuous mode)
+ */
+ optional bool set_one_shot_mode = 2;
+}
+
+message SCD30_config {
+ /*
+ * Set Automatic self-calibration enabled
+ */
+ optional bool set_asc = 1;
+
+ /*
+ * Recalibration target CO2 concentration in ppm (FRC or ASC)
+ */
+ optional uint32 set_target_co2_conc = 2;
+
+ /*
+ * Reference temperature in degC
+ */
+ optional float set_temperature = 3;
+
+ /*
+ * Altitude of sensor in meters above sea level. 0 - 3000m (overrides ambient pressure)
+ */
+ optional uint32 set_altitude = 4;
+
+ /*
+ * Power mode for sensor (true for low power, false for normal)
+ */
+ optional uint32 set_measurement_interval = 5;
+
+ /*
+ * Perform a factory reset of the sensor
+ */
+ optional bool soft_reset = 6;
+}
+
+message SHTXX_config {
+ /*
+ * Accuracy mode (0 = low, 1 = medium, 2 = high)
+ */
+ optional uint32 set_accuracy = 1;
+}
diff --git a/meshtastic/apponly.proto b/meshtastic/apponly.proto
index 100833f..2612ed6 100644
--- a/meshtastic/apponly.proto
+++ b/meshtastic/apponly.proto
@@ -8,7 +8,7 @@ import "meshtastic/config.proto";
option csharp_namespace = "Meshtastic.Protobufs";
option go_package = "github.com/meshtastic/go/generated";
option java_outer_classname = "AppOnlyProtos";
-option java_package = "com.geeksville.mesh";
+option java_package = "org.meshtastic.proto";
option swift_prefix = "";
/*
diff --git a/meshtastic/atak.options b/meshtastic/atak.options
index c341400..29ec3e1 100644
--- a/meshtastic/atak.options
+++ b/meshtastic/atak.options
@@ -3,4 +3,108 @@
*Status.battery int_size:8
*PLI.course int_size:16
*GeoChat.message max_size:200
-*GeoChat.to max_size:120
\ No newline at end of file
+*GeoChat.to max_size:120
+*GeoChat.to_callsign max_size:120
+*TAKPacket.detail max_size:220
+*TAKPacketV2.cot_type_str max_size:32
+*TAKPacketV2.callsign max_size:120
+*TAKPacketV2.uid max_size:48
+*TAKPacketV2.device_callsign max_size:120
+*TAKPacketV2.tak_version max_size:64
+*TAKPacketV2.tak_device max_size:32
+*TAKPacketV2.tak_platform max_size:32
+*TAKPacketV2.tak_os max_size:16
+*TAKPacketV2.endpoint max_size:32
+*TAKPacketV2.phone max_size:20
+*TAKPacketV2.raw_detail max_size:220
+*TAKPacketV2.stale_seconds int_size:16
+*TAKPacketV2.battery int_size:8
+*TAKPacketV2.course int_size:16
+*AircraftTrack.icao max_size:8
+*AircraftTrack.registration max_size:16
+*AircraftTrack.flight max_size:16
+*AircraftTrack.aircraft_type max_size:8
+*AircraftTrack.squawk int_size:16
+*AircraftTrack.category max_size:4
+*AircraftTrack.cot_host_id max_size:64
+
+# --- Typed geometry payloads (v2 protocol extension) ---
+#
+# CotGeoPoint: sint32 deltas from the enclosing event's latitude_i/longitude_i.
+# For nearby vertices (telestrations, small rectangles) the varint+zigzag
+# encoding is 2-3 bytes per field, cutting telestration vertex data in half
+# versus sfixed32. int_size:32 keeps the C type a plain int32.
+# Named with a `Cot` prefix to avoid a collision with `meshtastic.GeoPoint`
+# in device_ui.proto, which is an unrelated zoom/latitude/longitude type.
+*CotGeoPoint.lat_delta_i int_size:32
+*CotGeoPoint.lon_delta_i int_size:32
+#
+# DrawnShape pool sizing. `kind` and `style` are varint enums (no int_size
+# needed). stroke_color / fill_color are Team enum, also varint. stroke_argb
+# / fill_argb are fixed32 (always 4 bytes on the wire). Vertex pool is 32
+# entries x ~12B each ~= 384B worst case. Telestrations beyond 32 vertices
+# MUST be pre-truncated by the sender with `truncated = true`.
+*DrawnShape.vertices max_count:32
+*DrawnShape.major_cm int_size:32
+*DrawnShape.minor_cm int_size:32
+*DrawnShape.angle_deg int_size:16
+*DrawnShape.stroke_weight_x10 int_size:16
+*DrawnShape.bullseye_distance_dm int_size:32
+*DrawnShape.bullseye_bearing_ref int_size:8
+*DrawnShape.bullseye_flags int_size:8
+*DrawnShape.bullseye_uid_ref max_size:48
+
+# Marker pool sizing. Strings bounded tight to keep fixed pool small on
+# ESP32 nanopb. parent_uid matches existing TAKPacketV2.uid cap (48).
+# iconset fits "f7f71666-8b28-4b57-9fbb-e38e61d33b79/Google/hiker.png"
+# (~52 chars) with slack.
+*Marker.parent_uid max_size:48
+*Marker.parent_type max_size:24
+*Marker.parent_callsign max_size:24
+*Marker.iconset max_size:80
+
+# RangeAndBearing pool sizing.
+*RangeAndBearing.anchor_uid max_size:48
+*RangeAndBearing.range_cm int_size:32
+*RangeAndBearing.bearing_cdeg int_size:16
+*RangeAndBearing.stroke_weight_x10 int_size:16
+
+# Route pool sizing. 16 links x ~24B each ~= 384B worst case. prefix is
+# ATAK's short waypoint name prefix ("CP", "RP", etc.) — 8 chars is plenty.
+*Route.links max_count:16
+*Route.prefix max_size:8
+*Route.stroke_weight_x10 int_size:16
+*Route.Link.uid max_size:48
+*Route.Link.callsign max_size:16
+*Route.Link.link_type int_size:8
+
+# GeoChat receipt extension. receipt_for_uid matches TAKPacketV2.uid caps.
+*GeoChat.receipt_for_uid max_size:48
+
+# CasevacReport pool sizing. All numeric fields are small (0..255 for
+# patient counts, 1 byte for flags bitfields); strings are short.
+*CasevacReport.equipment_flags int_size:8
+*CasevacReport.terrain_flags int_size:8
+*CasevacReport.litter_patients int_size:8
+*CasevacReport.ambulatory_patients int_size:8
+*CasevacReport.us_military int_size:8
+*CasevacReport.us_civilian int_size:8
+*CasevacReport.non_us_military int_size:8
+*CasevacReport.non_us_civilian int_size:8
+*CasevacReport.epw int_size:8
+*CasevacReport.child int_size:8
+*CasevacReport.zone_marker max_size:16
+*CasevacReport.frequency max_size:16
+
+# EmergencyAlert pool sizing. UIDs match TAKPacketV2.uid caps (48).
+*EmergencyAlert.authoring_uid max_size:48
+*EmergencyAlert.cancel_reference_uid max_size:48
+
+# TaskRequest pool sizing. All four strings are capped tight so the
+# worst-case wire size stays under the LoRa MTU with headroom. task_type
+# is a short category tag; target_uid/assignee_uid match TAKPacketV2.uid
+# conventions; note is the one user-entered field.
+*TaskRequest.task_type max_size:12
+*TaskRequest.target_uid max_size:32
+*TaskRequest.assignee_uid max_size:32
+*TaskRequest.note max_size:48
\ No newline at end of file
diff --git a/meshtastic/atak.proto b/meshtastic/atak.proto
index c44479f..873e0b6 100644
--- a/meshtastic/atak.proto
+++ b/meshtastic/atak.proto
@@ -1,17 +1,18 @@
syntax = "proto3";
+/* trunk-ignore(buf-lint/PACKAGE_DIRECTORY_MATCH) */
package meshtastic;
option csharp_namespace = "Meshtastic.Protobufs";
option go_package = "github.com/meshtastic/go/generated";
option java_outer_classname = "ATAKProtos";
-option java_package = "com.geeksville.mesh";
+option java_package = "org.meshtastic.proto";
option swift_prefix = "";
+
/*
- * Packets for the official ATAK Plugin
+ * Packets for the official ATAK Plugin
*/
-message TAKPacket
-{
+message TAKPacket {
/*
* Are the payloads strings compressed for LoRA transport?
*/
@@ -40,6 +41,12 @@ message TAKPacket
* ATAK GeoChat message
*/
GeoChat chat = 6;
+
+ /*
+ * Generic CoT detail XML
+ * May be compressed / truncated by the sender (EUD)
+ */
+ bytes detail = 7;
}
}
@@ -48,7 +55,21 @@ message TAKPacket
*/
message GeoChat {
/*
- * The text message
+ * Receipt discriminator. Set alongside cot_type_id = b-t-f-d (delivered)
+ * or b-t-f-r (read). ReceiptType_None is the default for a normal chat
+ * message (cot_type_id = b-t-f).
+ *
+ * Receivers can detect a receipt by checking receipt_type != ReceiptType_None
+ * without re-parsing the envelope cot_type_id.
+ */
+ enum ReceiptType {
+ ReceiptType_None = 0; // normal chat message
+ ReceiptType_Delivered = 1; // b-t-f-d delivered receipt
+ ReceiptType_Read = 2; // b-t-f-r read receipt
+ }
+
+ /*
+ * The text message. Empty for receipts.
*/
string message = 1;
@@ -56,6 +77,25 @@ message GeoChat {
* Uid recipient of the message
*/
optional string to = 2;
+
+ /*
+ * Callsign of the recipient for the message
+ */
+ optional string to_callsign = 3;
+
+ /*
+ * UID of the chat message this event is acknowledging. Empty for a
+ * normal chat message; set for delivered / read receipts. Paired with
+ * receipt_type so receivers can match the ack back to the original
+ * outbound GeoChat by its event uid.
+ */
+ string receipt_for_uid = 4;
+
+ /*
+ * Receipt kind discriminator. See ReceiptType doc. Default ReceiptType_None
+ * means this is a regular chat message, not a receipt.
+ */
+ ReceiptType receipt_type = 5;
}
/*
@@ -189,6 +229,7 @@ message Status {
*/
uint32 battery = 1;
}
+
/*
* ATAK Contact
*
@@ -247,5 +288,1730 @@ message PLI {
/*
* Course in degrees
*/
- uint32 course = 5;
+ uint32 course = 5;
+}
+
+/*
+ * CoT how field values.
+ * Represents how the coordinates were generated.
+ */
+enum CotHow {
+ /*
+ * Unspecified
+ */
+ CotHow_Unspecified = 0;
+ /*
+ * Human entered
+ */
+ CotHow_h_e = 1;
+ /*
+ * Machine generated
+ */
+ CotHow_m_g = 2;
+ /*
+ * Human GPS/INS derived
+ */
+ CotHow_h_g_i_g_o = 3;
+ /*
+ * Machine relayed (imported from another system/gateway)
+ */
+ CotHow_m_r = 4;
+ /*
+ * Machine fused (corroborated from multiple sources)
+ */
+ CotHow_m_f = 5;
+ /*
+ * Machine predicted
+ */
+ CotHow_m_p = 6;
+ /*
+ * Machine simulated
+ */
+ CotHow_m_s = 7;
+}
+
+/*
+ * Well-known CoT event types.
+ * When the type is known, use the enum value for efficient encoding.
+ * For unknown types, set cot_type_id to CotType_Other and populate cot_type_str.
+ */
+enum CotType {
+ /*
+ * Unknown or unmapped type, use cot_type_str
+ */
+ CotType_Other = 0;
+ /*
+ * a-f-G-U-C: Friendly ground unit combat
+ */
+ CotType_a_f_G_U_C = 1;
+ /*
+ * a-f-G-U-C-I: Friendly ground unit combat infantry
+ */
+ CotType_a_f_G_U_C_I = 2;
+ /*
+ * a-n-A-C-F: Neutral aircraft civilian fixed-wing
+ */
+ CotType_a_n_A_C_F = 3;
+ /*
+ * a-n-A-C-H: Neutral aircraft civilian helicopter
+ */
+ CotType_a_n_A_C_H = 4;
+ /*
+ * a-n-A-C: Neutral aircraft civilian
+ */
+ CotType_a_n_A_C = 5;
+ /*
+ * a-f-A-M-H: Friendly aircraft military helicopter
+ */
+ CotType_a_f_A_M_H = 6;
+ /*
+ * a-f-A-M: Friendly aircraft military
+ */
+ CotType_a_f_A_M = 7;
+ /*
+ * a-f-A-M-F-F: Friendly aircraft military fixed-wing fighter
+ */
+ CotType_a_f_A_M_F_F = 8;
+ /*
+ * a-f-A-M-H-A: Friendly aircraft military helicopter attack
+ */
+ CotType_a_f_A_M_H_A = 9;
+ /*
+ * a-f-A-M-H-U-M: Friendly aircraft military helicopter utility medium
+ */
+ CotType_a_f_A_M_H_U_M = 10;
+ /*
+ * a-h-A-M-F-F: Hostile aircraft military fixed-wing fighter
+ */
+ CotType_a_h_A_M_F_F = 11;
+ /*
+ * a-h-A-M-H-A: Hostile aircraft military helicopter attack
+ */
+ CotType_a_h_A_M_H_A = 12;
+ /*
+ * a-u-A-C: Unknown aircraft civilian
+ */
+ CotType_a_u_A_C = 13;
+ /*
+ * t-x-d-d: Tasking delete/disconnect
+ */
+ CotType_t_x_d_d = 14;
+ /*
+ * a-f-G-E-S-E: Friendly ground equipment sensor
+ */
+ CotType_a_f_G_E_S_E = 15;
+ /*
+ * a-f-G-E-V-C: Friendly ground equipment vehicle
+ */
+ CotType_a_f_G_E_V_C = 16;
+ /*
+ * a-f-S: Friendly sea
+ */
+ CotType_a_f_S = 17;
+ /*
+ * a-f-A-M-F: Friendly aircraft military fixed-wing
+ */
+ CotType_a_f_A_M_F = 18;
+ /*
+ * a-f-A-M-F-C-H: Friendly aircraft military fixed-wing cargo heavy
+ */
+ CotType_a_f_A_M_F_C_H = 19;
+ /*
+ * a-f-A-M-F-U-L: Friendly aircraft military fixed-wing utility light
+ */
+ CotType_a_f_A_M_F_U_L = 20;
+ /*
+ * a-f-A-M-F-L: Friendly aircraft military fixed-wing liaison
+ */
+ CotType_a_f_A_M_F_L = 21;
+ /*
+ * a-f-A-M-F-P: Friendly aircraft military fixed-wing patrol
+ */
+ CotType_a_f_A_M_F_P = 22;
+ /*
+ * a-f-A-C-H: Friendly aircraft civilian helicopter
+ */
+ CotType_a_f_A_C_H = 23;
+ /*
+ * a-n-A-M-F-Q: Neutral aircraft military fixed-wing drone
+ */
+ CotType_a_n_A_M_F_Q = 24;
+
+ // --- Chat / messaging ---
+
+ /*
+ * b-t-f: GeoChat message
+ */
+ CotType_b_t_f = 25;
+
+ // --- CASEVAC / MEDEVAC ---
+
+ /*
+ * b-r-f-h-c: CASEVAC/MEDEVAC report
+ */
+ CotType_b_r_f_h_c = 26;
+
+ // --- Alerts ---
+
+ /*
+ * b-a-o-pan: Ring the bell / alert all
+ */
+ CotType_b_a_o_pan = 27;
+ /*
+ * b-a-o-opn: Troops in contact
+ */
+ CotType_b_a_o_opn = 28;
+ /*
+ * b-a-o-can: Cancel alert
+ */
+ CotType_b_a_o_can = 29;
+ /*
+ * b-a-o-tbl: 911 alert
+ */
+ CotType_b_a_o_tbl = 30;
+ /*
+ * b-a-g: Geofence breach alert
+ */
+ CotType_b_a_g = 31;
+
+ // --- Generic ground atoms (simplified affiliation types) ---
+
+ /*
+ * a-f-G: Friendly ground (generic)
+ */
+ CotType_a_f_G = 32;
+ /*
+ * a-f-G-U: Friendly ground unit (generic)
+ */
+ CotType_a_f_G_U = 33;
+ /*
+ * a-h-G: Hostile ground (generic)
+ */
+ CotType_a_h_G = 34;
+ /*
+ * a-u-G: Unknown ground (generic)
+ */
+ CotType_a_u_G = 35;
+ /*
+ * a-n-G: Neutral ground (generic)
+ */
+ CotType_a_n_G = 36;
+
+ // --- Routes and waypoints ---
+
+ /*
+ * b-m-r: Route
+ */
+ CotType_b_m_r = 37;
+ /*
+ * b-m-p-w: Route waypoint
+ */
+ CotType_b_m_p_w = 38;
+ /*
+ * b-m-p-s-p-i: Self-position marker
+ */
+ CotType_b_m_p_s_p_i = 39;
+
+ // --- Drawing / tactical graphics ---
+
+ /*
+ * u-d-f: Freeform shape (line/polygon)
+ */
+ CotType_u_d_f = 40;
+ /*
+ * u-d-r: Rectangle
+ */
+ CotType_u_d_r = 41;
+ /*
+ * u-d-c-c: Circle
+ */
+ CotType_u_d_c_c = 42;
+ /*
+ * u-rb-a: Range/bearing line
+ */
+ CotType_u_rb_a = 43;
+
+ // --- Additional hostile/unknown aircraft ---
+
+ /*
+ * a-h-A: Hostile aircraft (generic)
+ */
+ CotType_a_h_A = 44;
+ /*
+ * a-u-A: Unknown aircraft (generic)
+ */
+ CotType_a_u_A = 45;
+ /*
+ * a-f-A-M-H-Q: Friendly aircraft military helicopter observation
+ */
+ CotType_a_f_A_M_H_Q = 46;
+
+ // Friendly aircraft civilian
+
+ /*
+ * a-f-A-C-F: Friendly aircraft civilian fixed-wing
+ */
+ CotType_a_f_A_C_F = 47;
+ /*
+ * a-f-A-C: Friendly aircraft civilian (generic)
+ */
+ CotType_a_f_A_C = 48;
+ /*
+ * a-f-A-C-L: Friendly aircraft civilian lighter-than-air
+ */
+ CotType_a_f_A_C_L = 49;
+ /*
+ * a-f-A: Friendly aircraft (generic)
+ */
+ CotType_a_f_A = 50;
+
+ // Friendly aircraft military helicopter variants
+
+ /*
+ * a-f-A-M-H-C: Friendly aircraft military helicopter cargo
+ */
+ CotType_a_f_A_M_H_C = 51;
+
+ // Neutral aircraft military
+
+ /*
+ * a-n-A-M-F-F: Neutral aircraft military fixed-wing fighter
+ */
+ CotType_a_n_A_M_F_F = 52;
+
+ // Unknown aircraft civilian
+
+ /*
+ * a-u-A-C-F: Unknown aircraft civilian fixed-wing
+ */
+ CotType_a_u_A_C_F = 53;
+
+ // Friendly ground unit subtypes
+
+ /*
+ * a-f-G-U-C-F-T-A: Friendly ground unit combat forces theater aviation
+ */
+ CotType_a_f_G_U_C_F_T_A = 54;
+ /*
+ * a-f-G-U-C-V-S: Friendly ground unit combat vehicle support
+ */
+ CotType_a_f_G_U_C_V_S = 55;
+ /*
+ * a-f-G-U-C-R-X: Friendly ground unit combat reconnaissance exploitation
+ */
+ CotType_a_f_G_U_C_R_X = 56;
+ /*
+ * a-f-G-U-C-I-Z: Friendly ground unit combat infantry mechanized
+ */
+ CotType_a_f_G_U_C_I_Z = 57;
+ /*
+ * a-f-G-U-C-E-C-W: Friendly ground unit combat engineer construction wheeled
+ */
+ CotType_a_f_G_U_C_E_C_W = 58;
+ /*
+ * a-f-G-U-C-I-L: Friendly ground unit combat infantry light
+ */
+ CotType_a_f_G_U_C_I_L = 59;
+ /*
+ * a-f-G-U-C-R-O: Friendly ground unit combat reconnaissance other
+ */
+ CotType_a_f_G_U_C_R_O = 60;
+ /*
+ * a-f-G-U-C-R-V: Friendly ground unit combat reconnaissance cavalry
+ */
+ CotType_a_f_G_U_C_R_V = 61;
+ /*
+ * a-f-G-U-H: Friendly ground unit headquarters
+ */
+ CotType_a_f_G_U_H = 62;
+ /*
+ * a-f-G-U-U-M-S-E: Friendly ground unit support medical surgical evacuation
+ */
+ CotType_a_f_G_U_U_M_S_E = 63;
+ /*
+ * a-f-G-U-S-M-C: Friendly ground unit support maintenance collection
+ */
+ CotType_a_f_G_U_S_M_C = 64;
+
+ // Friendly ground equipment
+
+ /*
+ * a-f-G-E-S: Friendly ground equipment sensor (generic)
+ */
+ CotType_a_f_G_E_S = 65;
+ /*
+ * a-f-G-E: Friendly ground equipment (generic)
+ */
+ CotType_a_f_G_E = 66;
+ /*
+ * a-f-G-E-V-C-U: Friendly ground equipment vehicle utility
+ */
+ CotType_a_f_G_E_V_C_U = 67;
+ /*
+ * a-f-G-E-V-C-ps: Friendly ground equipment vehicle public safety
+ */
+ CotType_a_f_G_E_V_C_ps = 68;
+
+ // Unknown ground
+
+ /*
+ * a-u-G-E-V: Unknown ground equipment vehicle
+ */
+ CotType_a_u_G_E_V = 69;
+
+ // Sea
+
+ /*
+ * a-f-S-N-N-R: Friendly sea surface non-naval rescue
+ */
+ CotType_a_f_S_N_N_R = 70;
+
+ // Friendly force (non-domain-specific)
+
+ /*
+ * a-f-F-B: Friendly force boundary
+ */
+ CotType_a_f_F_B = 71;
+
+ // Bits / data messages
+
+ /*
+ * b-m-p-s-p-loc: Self-position location marker
+ */
+ CotType_b_m_p_s_p_loc = 72;
+ /*
+ * b-i-v: Imagery/video
+ */
+ CotType_b_i_v = 73;
+ /*
+ * b-f-t-r: File transfer request
+ */
+ CotType_b_f_t_r = 74;
+ /*
+ * b-f-t-a: File transfer acknowledgment
+ */
+ CotType_b_f_t_a = 75;
+
+ // --- Additional drawing / tactical graphics ---
+
+ /*
+ * u-d-f-m: Freehand telestration / annotation. Anchor at event point,
+ * geometry carried via DrawnShape.vertices. May be truncated to
+ * MAX_VERTICES by the sender.
+ */
+ CotType_u_d_f_m = 76;
+ /*
+ * u-d-p: Closed polygon. Geometry carried via DrawnShape.vertices,
+ * implicitly closed (receiver duplicates first vertex as needed).
+ */
+ CotType_u_d_p = 77;
+
+ // --- Additional markers ---
+
+ /*
+ * b-m-p-s-m: Spot map marker (colored dot at a point of interest).
+ */
+ CotType_b_m_p_s_m = 78;
+ /*
+ * b-m-p-c: Checkpoint (intermediate route control point).
+ */
+ CotType_b_m_p_c = 79;
+
+ // --- Ranging tools ---
+
+ /*
+ * u-r-b-c-c: Ranging circle (range rings centered on the event point).
+ */
+ CotType_u_r_b_c_c = 80;
+ /*
+ * u-r-b-bullseye: Bullseye with configurable range rings and bearing
+ * reference (magnetic / true / grid).
+ */
+ CotType_u_r_b_bullseye = 81;
+
+ // ======================================================================
+ // Expanded coverage from the ATAK-CIV quick-drop pallet (values 82-124).
+ // ======================================================================
+ //
+ // All of these types existed as cot_type_str strings; promoting them to
+ // enum values turns a ~10-byte string into a 1-byte varint on the wire
+ // for every event that uses them. Grouped below by pallet section.
+
+ // --- PLI self-reporting (1) ------------------------------------------
+ /*
+ * a-f-G-E-V-A: Friendly armored vehicle, user-selectable self PLI.
+ */
+ CotType_a_f_G_E_V_A = 82;
+
+ // --- 2525 quick-drop: basic affiliation gaps -------------------------
+ /*
+ * a-n-A: Neutral aircraft (friendly/hostile/unknown already present).
+ */
+ CotType_a_n_A = 83;
+
+ // --- 2525 quick-drop: artillery (4) ----------------------------------
+ CotType_a_u_G_U_C_F = 84;
+ CotType_a_n_G_U_C_F = 85;
+ CotType_a_h_G_U_C_F = 86;
+ CotType_a_f_G_U_C_F = 87;
+
+ // --- 2525 quick-drop: building (4) -----------------------------------
+ CotType_a_u_G_I = 88;
+ CotType_a_n_G_I = 89;
+ CotType_a_h_G_I = 90;
+ CotType_a_f_G_I = 91;
+
+ // --- 2525 quick-drop: mine (4) ---------------------------------------
+ CotType_a_u_G_E_X_M = 92;
+ CotType_a_n_G_E_X_M = 93;
+ CotType_a_h_G_E_X_M = 94;
+ CotType_a_f_G_E_X_M = 95;
+
+ // --- 2525 quick-drop: ship (3; a-f-S already at 17) ------------------
+ CotType_a_u_S = 96;
+ CotType_a_n_S = 97;
+ CotType_a_h_S = 98;
+
+ // --- 2525 quick-drop: sniper (4) -------------------------------------
+ CotType_a_u_G_U_C_I_d = 99;
+ CotType_a_n_G_U_C_I_d = 100;
+ CotType_a_h_G_U_C_I_d = 101;
+ CotType_a_f_G_U_C_I_d = 102;
+
+ // --- 2525 quick-drop: tank (4) ---------------------------------------
+ CotType_a_u_G_E_V_A_T = 103;
+ CotType_a_n_G_E_V_A_T = 104;
+ CotType_a_h_G_E_V_A_T = 105;
+ CotType_a_f_G_E_V_A_T = 106;
+
+ // --- 2525 quick-drop: troops (3; a-f-G-U-C-I already at 2) -----------
+ CotType_a_u_G_U_C_I = 107;
+ CotType_a_n_G_U_C_I = 108;
+ CotType_a_h_G_U_C_I = 109;
+
+ // --- 2525 quick-drop: generic vehicle (3; a-u-G-E-V already at 69) ---
+ CotType_a_n_G_E_V = 110;
+ CotType_a_h_G_E_V = 111;
+ CotType_a_f_G_E_V = 112;
+
+ // --- Mission-specific points (4) -------------------------------------
+ /*
+ * b-m-p-w-GOTO: Go To / bloodhound navigation target.
+ */
+ CotType_b_m_p_w_GOTO = 113;
+ /*
+ * b-m-p-c-ip: Initial point (mission planning).
+ */
+ CotType_b_m_p_c_ip = 114;
+ /*
+ * b-m-p-c-cp: Contact point (mission planning).
+ */
+ CotType_b_m_p_c_cp = 115;
+ /*
+ * b-m-p-s-p-op: Observation post.
+ */
+ CotType_b_m_p_s_p_op = 116;
+
+ // --- Vehicle drawings (2) --------------------------------------------
+ /*
+ * u-d-v: 2D vehicle outline drawn on the map.
+ */
+ CotType_u_d_v = 117;
+ /*
+ * u-d-v-m: 3D vehicle model reference.
+ */
+ CotType_u_d_v_m = 118;
+
+ // --- Drawing shapes (1) ----------------------------------------------
+ /*
+ * u-d-c-e: Non-circular ellipse (circle with distinct major/minor axes).
+ */
+ CotType_u_d_c_e = 119;
+
+ // --- Image / media marker (1) ----------------------------------------
+ /*
+ * b-i-x-i: Quick Pic geotagged image marker. The image itself does not
+ * ride on LoRa; this event references the image via iconset metadata.
+ */
+ CotType_b_i_x_i = 120;
+
+ // --- GeoChat receipts (2) --------------------------------------------
+ /*
+ * b-t-f-d: GeoChat delivered receipt. Carried on the existing `chat`
+ * payload_variant via GeoChat.receipt_for_uid + receipt_type.
+ */
+ CotType_b_t_f_d = 121;
+ /*
+ * b-t-f-r: GeoChat read receipt. Same wire slot as b-t-f-d.
+ */
+ CotType_b_t_f_r = 122;
+
+ // --- Custom emergency (1) --------------------------------------------
+ /*
+ * b-a-o-c: Custom / generic emergency beacon.
+ */
+ CotType_b_a_o_c = 123;
+
+ // --- Tasking (1) -----------------------------------------------------
+ /*
+ * t-s: Task / engage request. Structured payload carried via the new
+ * TaskRequest typed variant.
+ */
+ CotType_t_s = 124;
+}
+
+/*
+ * Geopoint and altitude source
+ */
+enum GeoPointSource {
+ /*
+ * Unspecified
+ */
+ GeoPointSource_Unspecified = 0;
+ /*
+ * GPS derived
+ */
+ GeoPointSource_GPS = 1;
+ /*
+ * User entered
+ */
+ GeoPointSource_USER = 2;
+ /*
+ * Network/external
+ */
+ GeoPointSource_NETWORK = 3;
+}
+
+/*
+ * Aircraft track information from ADS-B or military air tracking.
+ * Covers the majority of observed real-world CoT traffic.
+ */
+message AircraftTrack {
+ /*
+ * ICAO hex identifier (e.g. "AD237C")
+ */
+ string icao = 1;
+ /*
+ * Aircraft registration (e.g. "N946AK")
+ */
+ string registration = 2;
+ /*
+ * Flight number/callsign (e.g. "ASA864")
+ */
+ string flight = 3;
+ /*
+ * ICAO aircraft type designator (e.g. "B39M")
+ */
+ string aircraft_type = 4;
+ /*
+ * Transponder squawk code (0-7777 octal)
+ */
+ uint32 squawk = 5;
+ /*
+ * ADS-B emitter category (e.g. "A3")
+ */
+ string category = 6;
+ /*
+ * Received signal strength * 10 (e.g. -194 for -19.4 dBm)
+ */
+ sint32 rssi_x10 = 7;
+ /*
+ * Whether receiver has GPS fix
+ */
+ bool gps = 8;
+ /*
+ * CoT host ID for source attribution
+ */
+ string cot_host_id = 9;
+}
+
+/*
+ * Compact geographic vertex used by repeated vertex lists in TAK geometry
+ * payloads. Named with a `Cot` prefix to avoid a namespace collision with
+ * `meshtastic.GeoPoint` in `device_ui.proto`, which is an unrelated zoom/
+ * latitude/longitude type used by the on-device map UI.
+ *
+ * Encoded as a signed DELTA from TAKPacketV2.latitude_i / longitude_i (the
+ * enclosing event's anchor point). The absolute coordinate is recovered by
+ * the receiver as `event.latitude_i + vertex.lat_delta_i` (and likewise for
+ * longitude).
+ *
+ * Why deltas: a 32-vertex telestration with vertices clustered within a few
+ * hundred meters of the anchor has per-vertex deltas in the ±10^4 range.
+ * Under sint32+zigzag those encode as 2 bytes each (tag+varint), versus the
+ * 4 bytes that sfixed32 would always require. At 32 vertices that is ~128
+ * bytes of savings — the difference between fitting under the LoRa MTU or
+ * not. Absolute coordinates (values ~10^9) would cost sint32 varint 5 bytes
+ * per field, which is why TAKPacketV2's top-level latitude_i / longitude_i
+ * stay sfixed32 — only small values win with sint32.
+ */
+message CotGeoPoint {
+ /*
+ * Latitude delta from TAKPacketV2.latitude_i, in 1e-7 degree units.
+ * Add to the enclosing event's latitude_i to recover the absolute latitude.
+ */
+ sint32 lat_delta_i = 1;
+ /*
+ * Longitude delta from TAKPacketV2.longitude_i, in 1e-7 degree units.
+ */
+ sint32 lon_delta_i = 2;
+}
+
+/*
+ * User-drawn tactical graphic: circle, rectangle, polygon, polyline, freehand
+ * telestration, ranging circle, or bullseye.
+ *
+ * Covers CoT types u-d-c-c, u-d-r, u-d-f, u-d-f-m, u-d-p, u-r-b-c-c,
+ * u-r-b-bullseye. The shape's anchor position is carried on
+ * TAKPacketV2.latitude_i/longitude_i; polyline/polygon vertices are in the
+ * `vertices` repeated field as `CotGeoPoint` deltas from that anchor.
+ *
+ * Colors use the Team enum as a 14-color palette (see color encoding below)
+ * with a fixed32 exact-ARGB fallback for custom user-picked colors that
+ * don't map to a palette entry.
+ */
+message DrawnShape {
+ /*
+ * Shape kind discriminator. Drives receiver rendering and also controls
+ * which optional fields below are meaningful.
+ */
+ enum Kind {
+ /*
+ * Unspecified (do not use on the wire)
+ */
+ Kind_Unspecified = 0;
+ /*
+ * u-d-c-c: User-drawn circle (uses major/minor/angle, anchor = event point)
+ */
+ Kind_Circle = 1;
+ /*
+ * u-d-r: User-drawn rectangle (uses vertices = 4 corners)
+ */
+ Kind_Rectangle = 2;
+ /*
+ * u-d-f: User-drawn polyline (uses vertices, not closed)
+ */
+ Kind_Freeform = 3;
+ /*
+ * u-d-f-m: Freehand telestration / annotation (uses vertices, may be truncated)
+ */
+ Kind_Telestration = 4;
+ /*
+ * u-d-p: Closed polygon (uses vertices, implicitly closed)
+ */
+ Kind_Polygon = 5;
+ /*
+ * u-r-b-c-c: Ranging circle (major/minor/angle, stroke + optional fill)
+ */
+ Kind_RangingCircle = 6;
+ /*
+ * u-r-b-bullseye: Bullseye ring with range rings and bearing reference
+ */
+ Kind_Bullseye = 7;
+ /*
+ * u-d-c-e: Ellipse with distinct major/minor axes (same storage as
+ * Kind_Circle — uses major_cm/minor_cm/angle_deg — but receivers
+ * render it as a non-circular ellipse rather than a round circle).
+ */
+ Kind_Ellipse = 8;
+ /*
+ * u-d-v: 2D vehicle outline drawn on the map. Vertices carry the
+ * outline polygon; receivers draw it as a filled polygon.
+ */
+ Kind_Vehicle2D = 9;
+ /*
+ * u-d-v-m: 3D vehicle model reference. Same vertex polygon as
+ * Kind_Vehicle2D; receivers that support 3D rendering extrude it.
+ */
+ Kind_Vehicle3D = 10;
+ }
+ /*
+ * Explicit stroke/fill/both discriminator.
+ *
+ * ATAK's source XML distinguishes "stroke-only polyline" from "closed shape
+ * with both stroke and fill" by the presence of the element.
+ * Both states can hash to all-zero color fields, so we carry the signal
+ * explicitly. Parser sets this from (sawStrokeColor, sawFillColor) at the
+ * end of parse; builder uses it to decide which of /
+ * to emit in the reconstructed XML.
+ */
+ enum StyleMode {
+ /*
+ * Unspecified — receiver infers from which color fields are non-zero.
+ */
+ StyleMode_Unspecified = 0;
+ /*
+ * Stroke only. No in the source XML. Used for polylines,
+ * ranging lines, bullseye rings.
+ */
+ StyleMode_StrokeOnly = 1;
+ /*
+ * Fill only. No in the source XML. Rare but valid in
+ * ATAK (solid region with no outline).
+ */
+ StyleMode_FillOnly = 2;
+ /*
+ * Both stroke and fill present. Closed shapes: circle, rectangle,
+ * polygon, ranging circle.
+ */
+ StyleMode_StrokeAndFill = 3;
+ }
+ /*
+ * Shape kind (circle, rectangle, freeform, etc.)
+ */
+ Kind kind = 1;
+ /*
+ * Explicit stroke/fill/both discriminator. See StyleMode doc.
+ */
+ StyleMode style = 2;
+ /*
+ * Ellipse major radius in centimeters. 0 for non-ellipse kinds.
+ */
+ uint32 major_cm = 3;
+ /*
+ * Ellipse minor radius in centimeters. 0 for non-ellipse kinds.
+ */
+ uint32 minor_cm = 4;
+ /*
+ * Ellipse rotation angle in degrees. Valid values are 0..360 inclusive;
+ * 0 and 360 are equivalent rotations. In proto3, an unset uint32 reads
+ * as 0, so senders should emit 0 when the angle is unspecified.
+ */
+ uint32 angle_deg = 5;
+ /*
+ * Stroke color as a named palette entry from the Team enum. If
+ * Unspecifed_Color, the exact ARGB is carried in stroke_argb.
+ * Valid only when style is StrokeOnly or StrokeAndFill.
+ */
+ Team stroke_color = 6;
+ /*
+ * Stroke color as an exact 32-bit ARGB bit pattern. Always populated
+ * on the wire; readers MUST use this value when stroke_color ==
+ * Unspecifed_Color and MAY use it to recover the exact original bytes
+ * even when a palette entry is set.
+ */
+ fixed32 stroke_argb = 7;
+ /*
+ * Stroke weight in tenths of a unit (e.g. 30 = 3.0). Typical ATAK
+ * range 10..60.
+ */
+ uint32 stroke_weight_x10 = 8;
+ /*
+ * Fill color as a named palette entry. See stroke_color docs.
+ * Valid only when style is FillOnly or StrokeAndFill.
+ */
+ Team fill_color = 9;
+ /*
+ * Fill color exact ARGB fallback. See stroke_argb docs.
+ */
+ fixed32 fill_argb = 10;
+ /*
+ * Whether labels are rendered on this shape.
+ */
+ bool labels_on = 11;
+ /*
+ * Vertex list for polyline/polygon/rectangle shapes. Capped at 32 by
+ * the nanopb pool; senders MUST truncate longer inputs and set
+ * `truncated = true`.
+ */
+ repeated CotGeoPoint vertices = 12;
+ /*
+ * True if the sender truncated `vertices` to fit the pool.
+ */
+ bool truncated = 13;
+ // --- Bullseye-only fields. All ignored unless kind == Kind_Bullseye. ---
+ /*
+ * Bullseye distance in meters * 10 (e.g. 3285 = 328.5 m). 0 = unset.
+ */
+ uint32 bullseye_distance_dm = 14;
+ /*
+ * Bullseye bearing reference: 0 unset, 1 Magnetic, 2 True, 3 Grid.
+ */
+ uint32 bullseye_bearing_ref = 15;
+ /*
+ * Bullseye attribute bit flags:
+ * bit 0: rangeRingVisible
+ * bit 1: hasRangeRings
+ * bit 2: edgeToCenter
+ * bit 3: mils
+ */
+ uint32 bullseye_flags = 16;
+ /*
+ * Bullseye reference UID (anchor marker). Empty = anchor is self.
+ */
+ string bullseye_uid_ref = 17;
+}
+
+/*
+ * Fixed point of interest: spot marker, waypoint, checkpoint, 2525 symbol,
+ * or custom icon.
+ *
+ * Covers CoT types b-m-p-s-m, b-m-p-w, b-m-p-c, b-m-p-s-p-i, b-m-p-s-p-loc,
+ * plus a-u-G / a-f-G / a-h-G / a-n-G with iconset paths. The marker position
+ * is carried on TAKPacketV2.latitude_i/longitude_i; fields below carry only
+ * the marker-specific metadata.
+ */
+message Marker {
+ /*
+ * Marker kind. Used to pick sensible receiver defaults when the CoT type
+ * alone is ambiguous (e.g. a-u-G could be a 2525 symbol or a custom icon
+ * depending on the iconset path).
+ */
+ enum Kind {
+ /*
+ * Unspecified — fall back to TAKPacketV2.cot_type_id
+ */
+ Kind_Unspecified = 0;
+ /*
+ * b-m-p-s-m: Spot map marker
+ */
+ Kind_Spot = 1;
+ /*
+ * b-m-p-w: Route waypoint
+ */
+ Kind_Waypoint = 2;
+ /*
+ * b-m-p-c: Checkpoint
+ */
+ Kind_Checkpoint = 3;
+ /*
+ * b-m-p-s-p-i / b-m-p-s-p-loc: Self-position marker
+ */
+ Kind_SelfPosition = 4;
+ /*
+ * 2525B/C military symbol (iconsetpath = COT_MAPPING_2525B/...)
+ */
+ Kind_Symbol2525 = 5;
+ /*
+ * COT_MAPPING_SPOTMAP icon (e.g. colored dot)
+ */
+ Kind_SpotMap = 6;
+ /*
+ * Custom icon set (UUID/GroupName/filename.png)
+ */
+ Kind_CustomIcon = 7;
+ /*
+ * b-m-p-w-GOTO: Go To / bloodhound navigation waypoint.
+ */
+ Kind_GoToPoint = 8;
+ /*
+ * b-m-p-c-ip: Initial point (mission planning control point).
+ */
+ Kind_InitialPoint = 9;
+ /*
+ * b-m-p-c-cp: Contact point (mission planning control point).
+ */
+ Kind_ContactPoint = 10;
+ /*
+ * b-m-p-s-p-op: Observation post.
+ */
+ Kind_ObservationPost = 11;
+ /*
+ * b-i-x-i: Quick Pic geotagged image marker. iconset carries the
+ * image reference (local filename or remote URL); the image itself
+ * does not ride on the LoRa wire.
+ */
+ Kind_ImageMarker = 12;
+ }
+ /*
+ * Marker kind
+ */
+ Kind kind = 1;
+ /*
+ * Marker color as a named palette entry. If Unspecifed_Color, the exact
+ * ARGB is in color_argb.
+ */
+ Team color = 2;
+ /*
+ * Marker color exact ARGB bit pattern. Always populated on the wire.
+ */
+ fixed32 color_argb = 3;
+ /*
+ * Status readiness flag (ATAK ).
+ */
+ bool readiness = 4;
+ /*
+ * Parent link UID (ATAK ). Empty = no parent.
+ * For spot/waypoint markers this is typically the producing TAK user's UID.
+ */
+ string parent_uid = 5;
+ /*
+ * Parent CoT type (e.g. "a-f-G-U-C"). Usually the parent TAK user's type.
+ */
+ string parent_type = 6;
+ /*
+ * Parent callsign (e.g. "HOPE").
+ */
+ string parent_callsign = 7;
+ /*
+ * Iconset path stored verbatim. ATAK emits three flavors:
+ * Kind_Symbol2525 -> "COT_MAPPING_2525B//"
+ * Kind_SpotMap -> "COT_MAPPING_SPOTMAP//"
+ * Kind_CustomIcon -> "//.png"
+ * Stored end-to-end without prefix stripping; the ~19 bytes saved by
+ * stripping well-known prefixes are not worth the builder-side bug
+ * surface, and the dict compresses the repetition effectively.
+ */
+ string iconset = 8;
+}
+
+/*
+ * Range and bearing measurement line from the event anchor to a target point.
+ *
+ * Covers CoT type u-rb-a. The anchor position is on
+ * TAKPacketV2.latitude_i/longitude_i; the target endpoint is carried as a
+ * CotGeoPoint — same delta-from-anchor encoding used by DrawnShape.vertices
+ * so a self-anchored RAB (common case) encodes in zero bytes.
+ */
+message RangeAndBearing {
+ /*
+ * Target/anchor endpoint (delta-encoded from TAKPacketV2.latitude_i/longitude_i).
+ */
+ CotGeoPoint anchor = 1;
+ /*
+ * Anchor UID (from ). Empty = free-standing.
+ */
+ string anchor_uid = 2;
+ /*
+ * Range in centimeters (value * 100). Range 0..4294 km.
+ */
+ uint32 range_cm = 3;
+ /*
+ * Bearing in degrees * 100 (0..36000).
+ */
+ uint32 bearing_cdeg = 4;
+ /*
+ * Stroke color as a Team palette entry. See DrawnShape.stroke_color doc.
+ */
+ Team stroke_color = 5;
+ /*
+ * Stroke color exact ARGB fallback.
+ */
+ fixed32 stroke_argb = 6;
+ /*
+ * Stroke weight * 10 (e.g. 30 = 3.0).
+ */
+ uint32 stroke_weight_x10 = 7;
+}
+
+/*
+ * Named route consisting of ordered waypoints and control points.
+ *
+ * Covers CoT type b-m-r. The first waypoint's position is on
+ * TAKPacketV2.latitude_i/longitude_i; subsequent waypoints and checkpoints
+ * are in `links`. Link count is capped at 16 by the nanopb pool; senders
+ * MUST truncate longer routes and set `truncated = true`.
+ */
+message Route {
+ /*
+ * Travel method for the route.
+ */
+ enum Method {
+ /*
+ * Unspecified / unknown
+ */
+ Method_Unspecified = 0;
+ /*
+ * Driving / vehicle
+ */
+ Method_Driving = 1;
+ /*
+ * Walking / foot
+ */
+ Method_Walking = 2;
+ /*
+ * Flying
+ */
+ Method_Flying = 3;
+ /*
+ * Swimming (individual)
+ */
+ Method_Swimming = 4;
+ /*
+ * Watercraft (boat)
+ */
+ Method_Watercraft = 5;
+ }
+ /*
+ * Route direction (infil = ingress, exfil = egress).
+ */
+ enum Direction {
+ /*
+ * Unspecified
+ */
+ Direction_Unspecified = 0;
+ /*
+ * Infiltration (ingress)
+ */
+ Direction_Infil = 1;
+ /*
+ * Exfiltration (egress)
+ */
+ Direction_Exfil = 2;
+ }
+ /*
+ * Route waypoint or control point. Each link corresponds to one ATAK
+ * entry inside the b-m-r event.
+ */
+ message Link {
+ /*
+ * Waypoint position (delta-encoded from TAKPacketV2.latitude_i/longitude_i).
+ */
+ CotGeoPoint point = 1;
+ /*
+ * Optional UID (empty = receiver derives).
+ */
+ string uid = 2;
+ /*
+ * Optional display callsign (e.g. "CP1"). Empty for unnamed control points.
+ */
+ string callsign = 3;
+ /*
+ * Link role: 0 = waypoint (b-m-p-w), 1 = checkpoint (b-m-p-c).
+ */
+ uint32 link_type = 4;
+ }
+ /*
+ * Travel method
+ */
+ Method method = 1;
+ /*
+ * Direction (infil/exfil)
+ */
+ Direction direction = 2;
+ /*
+ * Waypoint name prefix (e.g. "CP").
+ */
+ string prefix = 3;
+ /*
+ * Stroke weight * 10 (e.g. 30 = 3.0). 0 = default.
+ */
+ uint32 stroke_weight_x10 = 4;
+ /*
+ * Ordered list of route control points. Capped at 16.
+ */
+ repeated Link links = 5;
+ /*
+ * True if the sender truncated `links` to fit the pool.
+ */
+ bool truncated = 6;
+}
+
+/*
+ * 9-line MEDEVAC request (CoT type b-r-f-h-c).
+ *
+ * Mirrors the ATAK MedLine tool's <_medevac_> detail element. Every field
+ * is optional (proto3 default); senders omit lines they don't have. The
+ * envelope (TAKPacketV2.uid, cot_type_id=b-r-f-h-c, latitude_i/longitude_i,
+ * altitude, callsign) carries Line 1 (location) and Line 2 (callsign).
+ *
+ * All numeric fields are tight varints so a complete 9-line request fits
+ * in well under 100 bytes of proto on the wire.
+ */
+message CasevacReport {
+ /*
+ * Line 3: precedence / urgency.
+ */
+ enum Precedence {
+ Precedence_Unspecified = 0;
+ Precedence_Urgent = 1; // A - immediate, life-threatening
+ Precedence_UrgentSurgical = 2; // B - needs surgery
+ Precedence_Priority = 3; // C - within 4 hours
+ Precedence_Routine = 4; // D - within 24 hours
+ Precedence_Convenience = 5; // E - convenience
+ }
+ /*
+ * Line 7: HLZ marking method.
+ */
+ enum HlzMarking {
+ HlzMarking_Unspecified = 0;
+ HlzMarking_Panels = 1;
+ HlzMarking_PyroSignal = 2;
+ HlzMarking_Smoke = 3;
+ HlzMarking_None = 4;
+ HlzMarking_Other = 5;
+ }
+ /*
+ * Line 6: security situation at the pickup zone.
+ */
+ enum Security {
+ Security_Unspecified = 0;
+ Security_NoEnemy = 1; // N - no enemy activity
+ Security_PossibleEnemy = 2; // P - possible enemy
+ Security_EnemyInArea = 3; // E - enemy, approach with caution
+ Security_EnemyInArmedContact = 4; // X - armed escort required
+ }
+
+ /*
+ * Line 3: precedence / urgency.
+ */
+ Precedence precedence = 1;
+ /*
+ * Line 4: special equipment required, as a bitfield.
+ * bit 0: none
+ * bit 1: hoist
+ * bit 2: extraction equipment
+ * bit 3: ventilator
+ * bit 4: blood
+ */
+ uint32 equipment_flags = 2;
+ /*
+ * Line 5: number of litter (stretcher-bound) patients.
+ */
+ uint32 litter_patients = 3;
+ /*
+ * Line 5: number of ambulatory (walking-wounded) patients.
+ */
+ uint32 ambulatory_patients = 4;
+ /*
+ * Line 6: security situation at the PZ.
+ */
+ Security security = 5;
+ /*
+ * Line 7: HLZ marking method.
+ */
+ HlzMarking hlz_marking = 6;
+ /*
+ * Line 7 supplementary: short free-text describing the zone marker
+ * (e.g. "Green smoke", "VS-17 panel west"). Capped tight in options.
+ */
+ string zone_marker = 7;
+ // --- Line 8: patient nationality counts ---
+ uint32 us_military = 8;
+ uint32 us_civilian = 9;
+ uint32 non_us_military = 10;
+ uint32 non_us_civilian = 11;
+ uint32 epw = 12; // enemy prisoner of war
+ uint32 child = 13;
+ /*
+ * Line 9: terrain and obstacles at the PZ, as a bitfield.
+ * bit 0: slope
+ * bit 1: rough
+ * bit 2: loose
+ * bit 3: trees
+ * bit 4: wires
+ * bit 5: other
+ */
+ uint32 terrain_flags = 14;
+ /*
+ * Line 2: radio frequency / callsign metadata (e.g. "38.90 Mhz" or
+ * "Victor 6"). Capped tight in options.
+ */
+ string frequency = 15;
+
+ // --- v2.x medline extensions (tags 16–33) --------------------------------
+ //
+ // Fields 16+ cost a 2-byte tag instead of 1 byte, but they're usually
+ // sparse so the on-wire delta is modest when most stay unset. A fully
+ // populated CASEVAC with 13 free-text fields + 2 ZMIST entries can run
+ // 200-400 bytes compressed, i.e. potentially over the 237 B LoRa MTU.
+ // Callers that hit the MTU on the `compressWithRemarksFallback` path
+ // SHOULD strip the tier-2 situational fields (tags 28-32 + terrain_other_detail)
+ // before dropping the packet entirely. See README "CASEVAC tier-2 stripping".
+
+ /*
+ * Short title / MEDEVAC identifier (e.g. "EAGLE.15.181230"). Usually the
+ * same as the envelope callsign but ATAK sometimes carries a distinct
+ * ops-number here.
+ */
+ string title = 16;
+ /*
+ * Primary medline free-text — the single most clinically important line
+ * on a MEDLINE form (e.g. "2 urgent litter patients, smoke on approach").
+ * MUST be preserved under MTU pressure as long as any casevac is sent.
+ */
+ string medline_remarks = 17;
+
+ /*
+ * Line 3 (newer ATAK format): patient counts by precedence level.
+ * Coexists with the enum-style `precedence` field (tag 1) — older ATAK
+ * emits a single enum, newer ATAK emits these counts, and both can be
+ * set simultaneously. Senders populate whichever style(s) the source
+ * XML had; receivers prefer counts when non-zero.
+ */
+ uint32 urgent_count = 18;
+ uint32 urgent_surgical_count = 19;
+ uint32 priority_count = 20;
+ uint32 routine_count = 21;
+ uint32 convenience_count = 22;
+
+ /*
+ * Line 4 supplementary: free-text description of non-standard equipment
+ * (e.g. "Blood warmer"). Pairs with the `equipment_flags` bitfield.
+ */
+ string equipment_detail = 23;
+ /*
+ * Line 1 override: MGRS grid when distinct from the event anchor point
+ * (e.g. "34T CQ 12345 67890"). Event lat/lon/hae still carries the
+ * numeric location; this field preserves the exact MGRS string the
+ * medic entered.
+ */
+ string zone_protected_coord = 24;
+ /*
+ * Line 9 supplementary: slope direction (e.g. "N", "NE", "SSW") when
+ * `terrain_flags` bit 0 (slope) is set.
+ */
+ string terrain_slope_dir = 25;
+ /*
+ * Line 9 supplementary: free-text description of "other" terrain hazards
+ * (e.g. "Loose debris on west edge") when `terrain_flags` bit 5 (other)
+ * is set. Tier-2 strippable under MTU pressure.
+ */
+ string terrain_other_detail = 26;
+ /*
+ * Line 7 supplementary: how the zone is being marked right now
+ * (e.g. "Orange smoke", "VS-17 panel"). Complements the structured
+ * `hlz_marking` enum with a specific human-readable description.
+ */
+ string marked_by = 27;
+
+ // --- Tier-2 situational awareness (stripped first under MTU pressure) ---
+ // These fields are free-text context that helps the receiver plan the
+ // approach but aren't strictly required to evacuate the patient.
+
+ /*
+ * Nearby obstacles on the approach (e.g. "Power lines north of HLZ").
+ */
+ string obstacles = 28;
+ /*
+ * Wind direction and speed (e.g. "270 at 12 kts").
+ */
+ string winds_are_from = 29;
+ /*
+ * Friendly forces posture near the pickup zone
+ * (e.g. "Squad east of HLZ").
+ */
+ string friendlies = 30;
+ /*
+ * Known or suspected enemy positions near the pickup zone
+ * (e.g. "Possible enemy on south ridge").
+ */
+ string enemy = 31;
+ /*
+ * Free-text description of the HLZ itself
+ * (e.g. "Primary HLZ is soccer field").
+ */
+ string hlz_remarks = 32;
+
+ /*
+ * Per-patient clinical records. Each entry is one patient's ZMIST card
+ * (Zap number / Mechanism / Injuries / Signs / Treatment). Repeatable —
+ * a mass-casualty event can carry 1-6 entries in practice, limited by
+ * the 237 B LoRa MTU.
+ */
+ repeated ZMistEntry zmist = 33;
+}
+
+/*
+ * Per-patient clinical summary record — one entry per patient in a CASEVAC.
+ * Maps directly to ATAK's child element inside .
+ * All fields are optional free-text; senders populate what they have.
+ */
+message ZMistEntry {
+ /*
+ * Patient identifier / sequence label (e.g. "ZMIST-1", "ZMIST-2").
+ */
+ string title = 1;
+ /*
+ * Zap number — unique patient tracking ID (often a terse code like
+ * "Gunshot" or a serial).
+ */
+ string z = 2;
+ /*
+ * Mechanism of injury (e.g. "Penetrating trauma", "Blast injury").
+ */
+ string m = 3;
+ /*
+ * Injuries observed (e.g. "Left thigh", "Concussion").
+ */
+ string i = 4;
+ /*
+ * Signs / vital stats (e.g. "Stable", "Priority", "BP 110/70").
+ */
+ string s = 5;
+ /*
+ * Treatment given (e.g. "Tourniquet 1810Z", "O2 administered").
+ */
+ string t = 6;
+}
+
+/*
+ * Emergency alert / 911 beacon (CoT types b-a-o-tbl, b-a-o-pan, b-a-o-opn,
+ * b-a-o-can, b-a-o-c, b-a-g).
+ *
+ * Small, high-priority structured record. The CoT type string is still set
+ * on cot_type_id so receivers that ignore payload_variant can still display
+ * the alert from the enum alone; the typed fields let modern receivers show
+ * the authoring unit and handle cancel-referencing without XML parsing.
+ */
+message EmergencyAlert {
+ enum Type {
+ Type_Unspecified = 0;
+ Type_Alert911 = 1; // b-a-o-tbl
+ Type_RingTheBell = 2; // b-a-o-pan
+ Type_InContact = 3; // b-a-o-opn
+ Type_GeoFenceBreached = 4; // b-a-g
+ Type_Custom = 5; // b-a-o-c
+ Type_Cancel = 6; // b-a-o-can
+ }
+ /*
+ * Alert discriminator.
+ */
+ Type type = 1;
+ /*
+ * UID of the unit that raised the alert. Often the same as
+ * TAKPacketV2.uid but can be a parent device uid when a tracker raises
+ * an alert on behalf of a dismount.
+ */
+ string authoring_uid = 2;
+ /*
+ * For Type_Cancel: the uid of the alert being cancelled. Empty for
+ * non-cancel alert types.
+ */
+ string cancel_reference_uid = 3;
+}
+
+/*
+ * Task / engage request (CoT type t-s).
+ *
+ * Mirrors ATAK's TaskCotReceiver / CotTaskBuilder workflow. The envelope
+ * carries the task's originating uid (implicit requester), position, and
+ * creation time; the fields below carry structured metadata the raw-detail
+ * fallback currently loses.
+ *
+ * Fields are deliberately lean — this variant is closer to the MTU ceiling
+ * than the others, so every string is capped in options.
+ */
+message TaskRequest {
+ enum Priority {
+ Priority_Unspecified = 0;
+ Priority_Low = 1;
+ Priority_Normal = 2;
+ Priority_High = 3;
+ Priority_Critical = 4;
+ }
+ enum Status {
+ Status_Unspecified = 0;
+ Status_Pending = 1; // assigned, not yet acknowledged
+ Status_Acknowledged = 2; // assignee has seen it
+ Status_InProgress = 3; // assignee is working it
+ Status_Completed = 4; // task done
+ Status_Cancelled = 5; // cancelled before completion
+ }
+
+ /*
+ * Short tag for the task category (e.g. "engage", "observe", "recon",
+ * "rescue"). Free text on the wire so ATAK-specific task taxonomies
+ * don't need proto coordination; capped tight in options.
+ */
+ string task_type = 1;
+ /*
+ * UID of the target / map item being tasked.
+ */
+ string target_uid = 2;
+ /*
+ * UID of the assigned unit. Empty = unassigned / broadcast task.
+ */
+ string assignee_uid = 3;
+ Priority priority = 4;
+ Status status = 5;
+ /*
+ * Optional short note (reason, constraints, grid reference). Capped
+ * tight in options to keep the worst-case under the LoRa MTU.
+ */
+ string note = 6;
+}
+
+/*
+ * Weather annotation from CoT detail element.
+ *
+ * Attaches to any TAKPacketV2 regardless of payload_variant — an Aircraft,
+ * PLI, or Marker can all carry observed conditions at the emitting station.
+ * ATAK-CIV ships an XSD for but no dedicated handler, so the
+ * element round-trips through the generic detail pipeline; this message
+ * promotes it to a first-class structured field.
+ *
+ * Target wire cost: ~6-8 bytes compressed with a fully populated instance.
+ *
+ * Named `TAKEnvironment` (not just `Environment`) because the bare name
+ * collides with `SwiftUI.Environment` — every SwiftUI view in a consuming
+ * iOS app uses the `@Environment` property wrapper, and importing the
+ * generated proto module would make `Environment` ambiguous in every one
+ * of those files. The `TAK` prefix matches the convention used by the
+ * outer `TAKPacketV2` wrapper and is unambiguous across all target
+ * languages (Swift, Kotlin, Python, TypeScript, C#).
+ */
+message TAKEnvironment {
+ /*
+ * Temperature in deci-degrees Celsius. 225 = 22.5°C.
+ * Range covers -50°C to +50°C (-500 to +500) which spans every realistic
+ * outdoor TAK deployment. sint32 because negative temps are common in
+ * cold-weather ops.
+ */
+ sint32 temperature_c_x10 = 1;
+ /*
+ * Wind direction in whole degrees, 0-359. "Direction FROM" per
+ * meteorological convention (matches CoT / ATAK).
+ */
+ uint32 wind_direction_deg = 2;
+ /*
+ * Wind speed in cm/s. Matches the unit of TAKPacketV2.speed for
+ * consistency. 1200 = 12.00 m/s = ~27 mph.
+ */
+ uint32 wind_speed_cm_s = 3;
+}
+
+/*
+ * Sensor field-of-view cone from CoT detail element.
+ *
+ * Encodes the 8 geometry attributes that ATAK-CIV's SensorDetailHandler
+ * reads from the wire; drops the 9 visual-styling attributes that are
+ * receiver-side render hints (fovAlpha, fovRed/Green/Blue, strokeColor,
+ * strokeWeight, displayMagneticReference, hideFov, fovLabels, rangeLines).
+ * The receiving ATAK client restores those from its own defaults, same as
+ * every other CoT carried over Meshtastic today.
+ *
+ * Attaches to any TAKPacketV2 — a PLI with a sensor on the operator's head,
+ * an Aircraft with a FLIR turret, a Marker dropped on a UAV.
+ * Target wire cost: ~7-14 bytes compressed (dominated by model string).
+ */
+message SensorFov {
+ /*
+ * Coarse sensor category, inferred from `model` on parse when the source
+ * XML doesn't label it. Receivers that render differently per sensor
+ * class (thermal overlay vs daylight cone) use this.
+ */
+ enum SensorType {
+ SensorType_Unspecified = 0;
+ SensorType_Camera = 1; // daylight / general optical
+ SensorType_Thermal = 2; // FLIR, thermal imager
+ SensorType_Laser = 3; // rangefinder, LRF, designator
+ SensorType_Nvg = 4; // night vision goggles
+ SensorType_Rf = 5; // radio/radar direction-finding
+ SensorType_Other = 6;
+ }
+
+ SensorType type = 1;
+ /*
+ * Azimuth in whole degrees, 0-359. "Pointing direction" of the cone axis,
+ * measured clockwise from true north. Whole degrees match ATAK-CIV's
+ * SensorDetailHandler default (270°) and save varint bytes over centi-deg.
+ */
+ uint32 azimuth_deg = 2;
+ /*
+ * Maximum range of the cone in meters.
+ * Optional — if unset, receivers should use the ATAK-CIV default of 100m.
+ */
+ optional uint32 range_m = 3;
+ /*
+ * Horizontal field of view in whole degrees (cone's angular width).
+ * ATAK-CIV default is 45°.
+ */
+ uint32 fov_horizontal_deg = 4;
+ /*
+ * Vertical field of view in whole degrees. ATAK-CIV default is 45°.
+ * Optional — a value of 0 means "not set / use horizontal FOV".
+ */
+ uint32 fov_vertical_deg = 5;
+ /*
+ * Elevation angle in whole degrees. Positive = up, negative = down.
+ * Range -90 to +90. sint32 for varint efficiency on small negatives.
+ */
+ sint32 elevation_deg = 6;
+ /*
+ * Roll (camera tilt) in whole degrees, -180 to +180.
+ * Optional — use 0 if the sensor doesn't track roll.
+ */
+ sint32 roll_deg = 7;
+ /*
+ * Free-form device model identifier, e.g. "FLIR-Boson-640", "SEEK".
+ * Optional — empty string means "unknown model" (ATAK-CIV default).
+ */
+ string model = 8;
+}
+
+/*
+ * ATAK v2 packet with expanded CoT field support and zstd dictionary compression.
+ * Sent on ATAK_PLUGIN_V2 port. The wire payload is:
+ * [1 byte flags][zstd-compressed TAKPacketV2 protobuf]
+ * Flags byte: bits 0-5 = dictionary ID, bits 6-7 = reserved.
+ */
+message TAKPacketV2 {
+ /*
+ * Well-known CoT event type enum.
+ * Use CotType_Other with cot_type_str for unknown types.
+ */
+ CotType cot_type_id = 1;
+ /*
+ * How the coordinates were generated
+ */
+ CotHow how = 2;
+ /*
+ * Callsign
+ */
+ string callsign = 3;
+ /*
+ * Team color assignment
+ */
+ Team team = 4;
+ /*
+ * Role of the group member
+ */
+ MemberRole role = 5;
+ /*
+ * Latitude, multiply by 1e-7 to get degrees in floating point
+ */
+ sfixed32 latitude_i = 6;
+ /*
+ * Longitude, multiply by 1e-7 to get degrees in floating point
+ */
+ sfixed32 longitude_i = 7;
+ /*
+ * Altitude in meters (HAE)
+ */
+ sint32 altitude = 8;
+ /*
+ * Speed in cm/s
+ */
+ uint32 speed = 9;
+ /*
+ * Course in degrees * 100 (0-36000)
+ */
+ uint32 course = 10;
+ /*
+ * Battery level 0-100
+ */
+ uint32 battery = 11;
+ /*
+ * Geopoint source
+ */
+ GeoPointSource geo_src = 12;
+ /*
+ * Altitude source
+ */
+ GeoPointSource alt_src = 13;
+ /*
+ * Device UID (UUID string or device ID like "ANDROID-xxxx")
+ */
+ string uid = 14;
+ /*
+ * Device callsign
+ */
+ string device_callsign = 15;
+ /*
+ * Stale time as seconds offset from event time
+ */
+ uint32 stale_seconds = 16;
+ /*
+ * TAK client version string
+ */
+ string tak_version = 17;
+ /*
+ * TAK device model
+ */
+ string tak_device = 18;
+ /*
+ * TAK platform (ATAK-CIV, WebTAK, etc.)
+ */
+ string tak_platform = 19;
+ /*
+ * TAK OS version
+ */
+ string tak_os = 20;
+ /*
+ * Connection endpoint
+ */
+ string endpoint = 21;
+ /*
+ * Phone number
+ */
+ string phone = 22;
+ /*
+ * CoT event type string, only populated when cot_type_id is CotType_Other
+ */
+ string cot_type_str = 23;
+ /*
+ * Optional remarks / free-text annotation from the element.
+ * Populated for non-GeoChat payload types (shapes, markers, routes, etc.)
+ * when the original CoT event carried non-empty remarks text.
+ * GeoChat messages carry their text in GeoChat.message instead.
+ * Empty string (proto3 default) means no remarks were present.
+ */
+ string remarks = 24;
+
+ // --- Sensor / environment annotations ----------------------------------
+ //
+ // Both fields are OPTIONAL and attach to any payload_variant. They
+ // describe observed conditions at the emitting station — a PLI with
+ // environment data, an Aircraft with a sensor cone, a Marker with both.
+ // Absent by default; presence is signaled by the message being non-null.
+
+ /*
+ * Observed weather conditions (temperature, wind). From .
+ * Type is `TAKEnvironment`, not `Environment`, to avoid colliding with
+ * SwiftUI's `@Environment` property wrapper in iOS consumers.
+ */
+ optional TAKEnvironment environment = 25;
+ /*
+ * Sensor field-of-view cone (camera, FLIR, laser, etc.). From .
+ */
+ optional SensorFov sensor_fov = 26;
+
+ reserved 27, 28, 29;
+ // Tags 27, 28, 29 reserved for future top-level annotations before the
+ // payload_variant oneof resumes at 30.
+
+ /*
+ * The payload of the packet
+ */
+ oneof payload_variant {
+ /*
+ * Position report (true = PLI, no extra fields beyond the common ones above)
+ */
+ bool pli = 30;
+ /*
+ * ATAK GeoChat message
+ */
+ GeoChat chat = 31;
+ /*
+ * Aircraft track data (ADS-B, military air)
+ */
+ AircraftTrack aircraft = 32;
+ /*
+ * Generic CoT detail XML for unmapped types. Kept as a fallback for CoT
+ * types not yet promoted to a typed variant; drawings, markers, ranging
+ * tools, and routes have dedicated variants below and should not land here.
+ */
+ bytes raw_detail = 33;
+ /*
+ * User-drawn tactical graphic: circle, rectangle, polygon, polyline,
+ * telestration, ranging circle, or bullseye. See DrawnShape.
+ */
+ DrawnShape shape = 34;
+ /*
+ * Fixed point of interest: spot marker, waypoint, checkpoint, 2525
+ * symbol, or custom icon. See Marker.
+ */
+ Marker marker = 35;
+ /*
+ * Range and bearing measurement line. See RangeAndBearing.
+ */
+ RangeAndBearing rab = 36;
+ /*
+ * Named route with ordered waypoints and control points. See Route.
+ */
+ Route route = 37;
+ /*
+ * 9-line MEDEVAC request. See CasevacReport.
+ */
+ CasevacReport casevac = 38;
+ /*
+ * Emergency beacon / 911 alert. See EmergencyAlert.
+ */
+ EmergencyAlert emergency = 39;
+ /*
+ * Task / engage request. See TaskRequest.
+ */
+ TaskRequest task = 40;
+ }
}
diff --git a/meshtastic/cannedmessages.proto b/meshtastic/cannedmessages.proto
index baa5134..59f3dcc 100644
--- a/meshtastic/cannedmessages.proto
+++ b/meshtastic/cannedmessages.proto
@@ -5,7 +5,7 @@ package meshtastic;
option csharp_namespace = "Meshtastic.Protobufs";
option go_package = "github.com/meshtastic/go/generated";
option java_outer_classname = "CannedMessageConfigProtos";
-option java_package = "com.geeksville.mesh";
+option java_package = "org.meshtastic.proto";
option swift_prefix = "";
/*
diff --git a/meshtastic/channel.proto b/meshtastic/channel.proto
index 2b10aaf..f49895a 100644
--- a/meshtastic/channel.proto
+++ b/meshtastic/channel.proto
@@ -1,11 +1,12 @@
syntax = "proto3";
+/* trunk-ignore(buf-lint/PACKAGE_DIRECTORY_MATCH) */
package meshtastic;
option csharp_namespace = "Meshtastic.Protobufs";
option go_package = "github.com/meshtastic/go/generated";
option java_outer_classname = "ChannelProtos";
-option java_package = "com.geeksville.mesh";
+option java_package = "org.meshtastic.proto";
option swift_prefix = "";
/*
@@ -85,17 +86,23 @@ message ChannelSettings {
/*
* Per-channel module settings.
*/
- ModuleSettings module_settings = 7;
+ ModuleSettings module_settings = 7;
}
/*
* This message is specifically for modules to store per-channel configuration data.
*/
message ModuleSettings {
-/*
- * Bits of precision for the location sent in position packets.
- */
+ /*
+ * Bits of precision for the location sent in position packets.
+ */
uint32 position_precision = 1;
+
+ /*
+ * Controls whether or not the client / device should mute the current channel
+ * Useful for noisy public channels you don't necessarily want to disable
+ */
+ bool is_muted = 2;
}
/*
diff --git a/meshtastic/clientonly.options b/meshtastic/clientonly.options
index bc98b39..c47944a 100644
--- a/meshtastic/clientonly.options
+++ b/meshtastic/clientonly.options
@@ -1,2 +1,4 @@
*DeviceProfile.long_name max_size:40
-*DeviceProfile.short_name max_size:5
\ No newline at end of file
+*DeviceProfile.short_name max_size:5
+*DeviceProfile.ringtone max_size:231
+*DeviceProfile.canned_messages max_size:201
\ No newline at end of file
diff --git a/meshtastic/clientonly.proto b/meshtastic/clientonly.proto
index b1a27b1..c80f428 100644
--- a/meshtastic/clientonly.proto
+++ b/meshtastic/clientonly.proto
@@ -3,11 +3,12 @@ syntax = "proto3";
package meshtastic;
import "meshtastic/localonly.proto";
+import "meshtastic/mesh.proto";
option csharp_namespace = "Meshtastic.Protobufs";
option go_package = "github.com/meshtastic/go/generated";
option java_outer_classname = "ClientOnlyProtos";
-option java_package = "com.geeksville.mesh";
+option java_package = "org.meshtastic.proto";
option swift_prefix = "";
/*
@@ -39,4 +40,19 @@ message DeviceProfile {
* The ModuleConfig of the node
*/
optional LocalModuleConfig module_config = 5;
+
+ /*
+ * Fixed position data
+ */
+ optional Position fixed_position = 6;
+
+ /*
+ * Ringtone for ExternalNotification
+ */
+ optional string ringtone = 7;
+
+ /*
+ * Predefined messages for CannedMessage
+ */
+ optional string canned_messages = 8;
}
diff --git a/meshtastic/config.options b/meshtastic/config.options
index 4490f08..3f6d81c 100644
--- a/meshtastic/config.options
+++ b/meshtastic/config.options
@@ -1,3 +1,8 @@
+# longest current is 45 chars, plan with a bit of buffer
+*DeviceConfig.tzdef max_size:65
+*DeviceConfig.buzzer_mode int_size:8
+
+
*NetworkConfig.wifi_ssid max_size:33
*NetworkConfig.wifi_psk max_size:65
*NetworkConfig.ntp_server max_size:33
@@ -12,3 +17,8 @@
*LoRaConfig.channel_num int_size:16
*PowerConfig.device_battery_ina_address int_size:8
+
+*SecurityConfig.public_key max_size:32
+*SecurityConfig.private_key max_size:32
+*SecurityConfig.admin_key max_size:32
+*SecurityConfig.admin_key max_count:3
diff --git a/meshtastic/config.proto b/meshtastic/config.proto
index 7ebbe45..33eaa58 100644
--- a/meshtastic/config.proto
+++ b/meshtastic/config.proto
@@ -2,10 +2,12 @@ syntax = "proto3";
package meshtastic;
+import "meshtastic/device_ui.proto";
+
option csharp_namespace = "Meshtastic.Protobufs";
option go_package = "github.com/meshtastic/go/generated";
option java_outer_classname = "ConfigProtos";
-option java_package = "com.geeksville.mesh";
+option java_package = "org.meshtastic.proto";
option swift_prefix = "";
message Config {
@@ -37,20 +39,23 @@ message Config {
/*
* Description: Combination of both ROUTER and CLIENT. Not for mobile devices.
+ * Deprecated in v2.3.15 because improper usage is impacting public meshes: Use ROUTER or CLIENT instead.
*/
- ROUTER_CLIENT = 3;
+
+ ROUTER_CLIENT = 3 [deprecated = true];
/*
* Description: Infrastructure node for extending network coverage by relaying messages with minimal overhead. Not visible in Nodes list.
* Technical Details: Mesh packets will simply be rebroadcasted over this node. Nodes configured with this role will not originate NodeInfo, Position, Telemetry
* or any other packet type. They will simply rebroadcast any mesh packets on the same frequency, channel num, spread factor, and coding rate.
+ * Deprecated in v2.7.11 because it creates "holes" in the mesh rebroadcast chain.
*/
- REPEATER = 4;
+ REPEATER = 4 [deprecated = true];
/*
* Description: Broadcasts GPS position packets as priority.
* Technical Details: Position Mesh packets will be prioritized higher and sent more frequently by default.
- * When used in conjunction with power.is_power_saving = true, nodes will wake up,
+ * When used in conjunction with power.is_power_saving = true, nodes will wake up,
* send position, and then sleep for position.position_broadcast_secs seconds.
*/
TRACKER = 5;
@@ -58,7 +63,7 @@ message Config {
/*
* Description: Broadcasts telemetry packets as priority.
* Technical Details: Telemetry Mesh packets will be prioritized higher and sent more frequently by default.
- * When used in conjunction with power.is_power_saving = true, nodes will wake up,
+ * When used in conjunction with power.is_power_saving = true, nodes will wake up,
* send environment telemetry, and then sleep for telemetry.environment_update_interval seconds.
*/
SENSOR = 6;
@@ -76,18 +81,18 @@ message Config {
* Technical Details: Used for nodes that "only speak when spoken to"
* Turns all of the routine broadcasts but allows for ad-hoc communication
* Still rebroadcasts, but with local only rebroadcast mode (known meshes only)
- * Can be used for clandestine operation or to dramatically reduce airtime / power consumption
+ * Can be used for clandestine operation or to dramatically reduce airtime / power consumption
*/
CLIENT_HIDDEN = 8;
/*
* Description: Broadcasts location as message to default channel regularly for to assist with device recovery.
- * Technical Details: Used to automatically send a text message to the mesh
+ * Technical Details: Used to automatically send a text message to the mesh
* with the current position of the device on a frequent interval:
* "I'm lost! Position: lat / long"
*/
LOST_AND_FOUND = 9;
-
+
/*
* Description: Enables automatic TAK PLI broadcasts and reduces routine broadcasts.
* Technical Details: Turns off many of the routine broadcasts to favor ATAK CoT packet stream
@@ -95,6 +100,23 @@ message Config {
* Uses position module configuration to determine TAK PLI broadcast interval.
*/
TAK_TRACKER = 10;
+
+ /*
+ * Description: Will always rebroadcast packets, but will do so after all other modes.
+ * Technical Details: Used for router nodes that are intended to provide additional coverage
+ * in areas not already covered by other routers, or to bridge around problematic terrain,
+ * but should not be given priority over other routers in order to avoid unnecessaraily
+ * consuming hops.
+ */
+ ROUTER_LATE = 11;
+
+ /*
+ * Description: Treats packets from or to favorited nodes as ROUTER_LATE, and all other packets as CLIENT.
+ * Technical Details: Used for stronger attic/roof nodes to distribute messages more widely
+ * from weaker, indoor, or less-well-positioned nodes. Recommended for users with multiple nodes
+ * where one CLIENT_BASE acts as a more powerful base station, such as an attic/roof node.
+ */
+ CLIENT_BASE = 12;
}
/*
@@ -118,12 +140,60 @@ message Config {
* Only rebroadcasts message on the nodes local primary / secondary channels.
*/
LOCAL_ONLY = 2;
-
+
/*
* Ignores observed messages from foreign meshes like LOCAL_ONLY,
* but takes it step further by also ignoring messages from nodenums not in the node's known list (NodeDB)
*/
KNOWN_ONLY = 3;
+
+ /*
+ * Only permitted for SENSOR, TRACKER and TAK_TRACKER roles, this will inhibit all rebroadcasts, not unlike CLIENT_MUTE role.
+ */
+ NONE = 4;
+
+ /*
+ * Ignores packets from non-standard portnums such as: TAK, RangeTest, PaxCounter, etc.
+ * Only rebroadcasts packets with standard portnums: NodeInfo, Text, Position, Telemetry, and Routing.
+ */
+ CORE_PORTNUMS_ONLY = 5;
+ }
+
+ /*
+ * Defines buzzer behavior for audio feedback
+ */
+ enum BuzzerMode {
+ /*
+ * Default behavior.
+ * Buzzer is enabled for all audio feedback including button presses and alerts.
+ */
+ ALL_ENABLED = 0;
+
+ /*
+ * Disabled.
+ * All buzzer audio feedback is disabled.
+ */
+ DISABLED = 1;
+
+ /*
+ * Notifications Only.
+ * Buzzer is enabled only for notifications and alerts, but not for button presses.
+ * External notification config determines the specifics of the notification behavior.
+ */
+ NOTIFICATIONS_ONLY = 2;
+
+ /*
+ * Non-notification system buzzer tones only.
+ * Buzzer is enabled only for non-notification tones such as button presses, startup, shutdown, but not for alerts.
+ */
+ SYSTEM_ONLY = 3;
+
+ /*
+ * Direct Message notifications only.
+ * Buzzer is enabled only for direct messages and alerts, but not for button presses.
+ * External notification config determines the specifics of the notification behavior.
+ */
+ DIRECT_MSG_ONLY = 4;
}
/*
@@ -133,14 +203,9 @@ message Config {
/*
* Disabling this will disable the SerialConsole by not initilizing the StreamAPI
+ * Moved to SecurityConfig
*/
- bool serial_enabled = 2;
-
- /*
- * By default we turn off logging as soon as an API client connects (to keep shared serial link quiet).
- * Set this to true to leave the debug log outputting even when API is active.
- */
- bool debug_log_enabled = 3;
+ bool serial_enabled = 2 [deprecated = true];
/*
* For boards without a hard wired button, this is the pin number that will be used
@@ -173,13 +238,30 @@ message Config {
/*
* If true, device is considered to be "managed" by a mesh administrator
* Clients should then limit available configuration and administrative options inside the user interface
+ * Moved to SecurityConfig
*/
- bool is_managed = 9;
+ bool is_managed = 9 [deprecated = true];
/*
* Disables the triple-press of user button to enable or disable GPS
*/
bool disable_triple_click = 10;
+
+ /*
+ * POSIX Timezone definition string from https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv.
+ */
+ string tzdef = 11;
+
+ /*
+ * If true, disable the default blinking LED (LED_PIN) behavior on the device
+ */
+ bool led_heartbeat_disabled = 12;
+
+ /*
+ * Controls buzzer behavior for audio feedback
+ * Defaults to ENABLED
+ */
+ BuzzerMode buzzer_mode = 13;
}
/*
@@ -257,18 +339,18 @@ message Config {
enum GpsMode {
/*
- * GPS is present but disabled
- */
+ * GPS is present but disabled
+ */
DISABLED = 0;
/*
- * GPS is present and enabled
- */
+ * GPS is present and enabled
+ */
ENABLED = 1;
/*
- * GPS is not present on the device
- */
+ * GPS is not present on the device
+ */
NOT_PRESENT = 2;
}
@@ -293,7 +375,7 @@ message Config {
/*
* Is GPS enabled for this node?
*/
- bool gps_enabled = 4[deprecated = true];
+ bool gps_enabled = 4 [deprecated = true];
/*
* How often should we try to get GPS position (in seconds)
@@ -305,7 +387,7 @@ message Config {
/*
* Deprecated in favor of using smart / regular broadcast intervals as implicit attempt time
*/
- uint32 gps_attempt_time = 6 [deprecated = true];
+ uint32 gps_attempt_time = 6 [deprecated = true];
/*
* Bit field of boolean configuration options for POSITION messages
@@ -350,30 +432,28 @@ message Config {
*/
message PowerConfig {
/*
- * If set, we are powered from a low-current source (i.e. solar), so even if it looks like we have power flowing in
- * we should try to minimize power consumption as much as possible.
- * YOU DO NOT NEED TO SET THIS IF YOU'VE set is_router (it is implied in that case).
- * Advanced Option
+ * Description: Will sleep everything as much as possible, for the tracker and sensor role this will also include the lora radio.
+ * Don't use this setting if you want to use your device with the phone apps or are using a device without a user button.
+ * Technical Details: Works for ESP32 devices and NRF52 devices in the Sensor or Tracker roles
*/
bool is_power_saving = 1;
/*
- * If non-zero, the device will fully power off this many seconds after external power is removed.
+ * Description: If non-zero, the device will fully power off this many seconds after external power is removed.
*/
uint32 on_battery_shutdown_after_secs = 2;
/*
* Ratio of voltage divider for battery pin eg. 3.20 (R1=100k, R2=220k)
* Overrides the ADC_MULTIPLIER defined in variant for battery voltage calculation.
- * Should be set to floating point value between 2 and 4
- * Fixes issues on Heltec v2
+ * https://meshtastic.org/docs/configuration/radio/power/#adc-multiplier-override
+ * Should be set to floating point value between 2 and 6
*/
float adc_multiplier_override = 3;
/*
- * Wait Bluetooth Seconds
- * The number of seconds for to wait before turning off BLE in No Bluetooth states
- * 0 for default of 1 minute
+ * Description: The number of seconds for to wait before turning off BLE in No Bluetooth states
+ * Technical Details: ESP32 Only 0 for default of 1 minute
*/
uint32 wait_bluetooth_secs = 4;
@@ -386,17 +466,14 @@ message Config {
uint32 sds_secs = 6;
/*
- * Light Sleep Seconds
- * In light sleep the CPU is suspended, LoRa radio is on, BLE is off an GPS is on
- * ESP32 Only
- * 0 for default of 300
+ * Description: In light sleep the CPU is suspended, LoRa radio is on, BLE is off an GPS is on
+ * Technical Details: ESP32 Only 0 for default of 300
*/
uint32 ls_secs = 7;
/*
- * Minimum Wake Seconds
- * While in light sleep when we receive packets on the LoRa radio we will wake and handle them and stay awake in no BLE mode for this value
- * 0 for default of 10 seconds
+ * Description: While in light sleep when we receive packets on the LoRa radio we will wake and handle them and stay awake in no BLE mode for this value
+ * Technical Details: ESP32 Only 0 for default of 10 seconds
*/
uint32 min_wake_secs = 8;
@@ -404,6 +481,12 @@ message Config {
* I2C address of INA_2XX to use for reading device battery voltage
*/
uint32 device_battery_ina_address = 9;
+
+ /*
+ * If non-zero, we want powermon log outputs. With the particular (bitfield) sources enabled.
+ * Note: we picked an ID of 32 so that lower more efficient IDs can be used for more frequently used options.
+ */
+ uint64 powermon_enables = 32;
}
/*
@@ -461,7 +544,7 @@ message Config {
string wifi_psk = 4;
/*
- * NTP server to use if WiFi is conneced, defaults to `0.pool.ntp.org`
+ * NTP server to use if WiFi is conneced, defaults to `meshtastic.pool.ntp.org`
*/
string ntp_server = 5;
@@ -484,6 +567,31 @@ message Config {
* rsyslog Server and Port
*/
string rsyslog_server = 9;
+
+ /*
+ * Flags for enabling/disabling network protocols
+ */
+ uint32 enabled_protocols = 10;
+
+ /*
+ * Enable/Disable ipv6 support
+ */
+ bool ipv6_enabled = 11;
+
+ /*
+ * Available flags auxiliary network protocols
+ */
+ enum ProtocolFlags {
+ /*
+ * Do not broadcast packets over any network protocol
+ */
+ NO_BROADCAST = 0x0000;
+
+ /*
+ * Enable broadcasting packets via UDP over the local network
+ */
+ UDP_BROADCAST = 0x0001;
+ }
}
/*
@@ -491,45 +599,10 @@ message Config {
*/
message DisplayConfig {
/*
- * How the GPS coordinates are displayed on the OLED screen.
+ * Deprecated in 2.7.4: Unused
*/
- enum GpsCoordinateFormat {
- /*
- * GPS coordinates are displayed in the normal decimal degrees format:
- * DD.DDDDDD DDD.DDDDDD
- */
- DEC = 0;
-
- /*
- * GPS coordinates are displayed in the degrees minutes seconds format:
- * DD°MM'SS"C DDD°MM'SS"C, where C is the compass point representing the locations quadrant
- */
- DMS = 1;
-
- /*
- * Universal Transverse Mercator format:
- * ZZB EEEEEE NNNNNNN, where Z is zone, B is band, E is easting, N is northing
- */
- UTM = 2;
-
- /*
- * Military Grid Reference System format:
- * ZZB CD EEEEE NNNNN, where Z is zone, B is band, C is the east 100k square, D is the north 100k square,
- * E is easting, N is northing
- */
- MGRS = 3;
-
- /*
- * Open Location Code (aka Plus Codes).
- */
- OLC = 4;
-
- /*
- * Ordnance Survey Grid Reference (the National Grid System of the UK).
- * Format: AB EEEEE NNNNN, where A is the east 100k square, B is the north 100k square,
- * E is the easting, N is the northing
- */
- OSGR = 5;
+ enum DeprecatedGpsCoordinateFormat {
+ UNUSED = 0;
}
/*
@@ -552,24 +625,29 @@ message Config {
*/
enum OledType {
/*
- * Default / Auto
+ * Default / Autodetect
*/
OLED_AUTO = 0;
/*
- * Default / Auto
+ * Default / Autodetect
*/
OLED_SSD1306 = 1;
/*
- * Default / Auto
+ * Default / Autodetect
*/
OLED_SH1106 = 2;
/*
- * Can not be auto detected but set by proto. Used for 128x128 screens
+ * Can not be auto detected but set by proto. Used for 128x64 screens
*/
OLED_SH1107 = 3;
+
+ /*
+ * Can not be auto detected but set by proto. Used for 128x128 screens
+ */
+ OLED_SH1107_128_128 = 4;
}
/*
@@ -579,9 +657,10 @@ message Config {
uint32 screen_on_secs = 1;
/*
+ * Deprecated in 2.7.4: Unused
* How the GPS coordinates are formatted on the OLED screen.
*/
- GpsCoordinateFormat gps_format = 2;
+ DeprecatedGpsCoordinateFormat gps_format = 2 [deprecated = true];
/*
* Automatically toggles to the next page on the screen like a carousel, based the specified interval in seconds.
@@ -593,7 +672,7 @@ message Config {
* If this is set, the displayed compass will always point north. if unset, the old behaviour
* (top of display is heading direction) is used.
*/
- bool compass_north_top = 4;
+ bool compass_north_top = 4 [deprecated = true];
/*
* Flip screen vertically, for cases that mount the screen upside down
@@ -645,6 +724,70 @@ message Config {
* Should we wake the screen up on accelerometer detected motion or tap
*/
bool wake_on_tap_or_motion = 10;
+
+ enum CompassOrientation {
+ /*
+ * The compass and the display are in the same orientation.
+ */
+ DEGREES_0 = 0;
+
+ /*
+ * Rotate the compass by 90 degrees.
+ */
+ DEGREES_90 = 1;
+
+ /*
+ * Rotate the compass by 180 degrees.
+ */
+ DEGREES_180 = 2;
+
+ /*
+ * Rotate the compass by 270 degrees.
+ */
+ DEGREES_270 = 3;
+
+ /*
+ * Don't rotate the compass, but invert the result.
+ */
+ DEGREES_0_INVERTED = 4;
+
+ /*
+ * Rotate the compass by 90 degrees and invert.
+ */
+ DEGREES_90_INVERTED = 5;
+
+ /*
+ * Rotate the compass by 180 degrees and invert.
+ */
+ DEGREES_180_INVERTED = 6;
+
+ /*
+ * Rotate the compass by 270 degrees and invert.
+ */
+ DEGREES_270_INVERTED = 7;
+ }
+
+ /*
+ * Indicates how to rotate or invert the compass output to accurate display on the display.
+ */
+ CompassOrientation compass_orientation = 11;
+
+ /*
+ * If false (default), the device will display the time in 24-hour format on screen.
+ * If true, the device will display the time in 12-hour format on screen.
+ */
+ bool use_12h_clock = 12;
+
+ /*
+ * If false (default), the device will use short names for various display screens.
+ * If true, node names will show in long format
+ */
+ bool use_long_node_name = 13;
+
+ /*
+ * If true, the device will display message bubbles on screen.
+ */
+ bool enable_message_bubbles = 14;
}
/*
@@ -746,6 +889,46 @@ message Config {
* Singapore 923mhz
*/
SG_923 = 18;
+
+ /*
+ * Philippines 433mhz
+ */
+ PH_433 = 19;
+
+ /*
+ * Philippines 868mhz
+ */
+ PH_868 = 20;
+
+ /*
+ * Philippines 915mhz
+ */
+ PH_915 = 21;
+
+ /*
+ * Australia / New Zealand 433MHz
+ */
+ ANZ_433 = 22;
+
+ /*
+ * Kazakhstan 433MHz
+ */
+ KZ_433 = 23;
+
+ /*
+ * Kazakhstan 863MHz
+ */
+ KZ_863 = 24;
+
+ /*
+ * Nepal 865MHz
+ */
+ NP_865 = 25;
+
+ /*
+ * Brazil 902MHz
+ */
+ BR_902 = 26;
}
/*
@@ -760,13 +943,15 @@ message Config {
/*
* Long Range - Slow
+ * Deprecated in 2.7: Unpopular slow preset.
*/
- LONG_SLOW = 1;
+ LONG_SLOW = 1 [deprecated = true];
/*
* Very Long Range - Slow
+ * Deprecated in 2.5: Works only with txco and is unusably slow
*/
- VERY_LONG_SLOW = 2;
+ VERY_LONG_SLOW = 2 [deprecated = true];
/*
* Medium Range - Slow
@@ -792,6 +977,36 @@ message Config {
* Long Range - Moderately Fast
*/
LONG_MODERATE = 7;
+
+ /*
+ * Short Range - Turbo
+ * This is the fastest preset and the only one with 500kHz bandwidth.
+ * It is not legal to use in all regions due to this wider bandwidth.
+ */
+ SHORT_TURBO = 8;
+
+ /*
+ * Long Range - Turbo
+ * This preset performs similarly to LongFast, but with 500Khz bandwidth.
+ */
+ LONG_TURBO = 9;
+ }
+
+ enum FEM_LNA_Mode {
+ /*
+ * FEM_LNA is present but disabled
+ */
+ DISABLED = 0;
+
+ /*
+ * FEM_LNA is present and enabled
+ */
+ ENABLED = 1;
+
+ /*
+ * FEM_LNA is not present on the device
+ */
+ NOT_PRESENT = 2;
}
/*
@@ -893,6 +1108,11 @@ message Config {
*/
float override_frequency = 14;
+ /*
+ * If true, disable the build-in PA FAN using pin define in RF95_FAN_EN.
+ */
+ bool pa_fan_disabled = 15;
+
/*
* For testing it is useful sometimes to force a node to never listen to
* particular other nodes (simulating radio out of range). All nodenums listed
@@ -904,6 +1124,15 @@ message Config {
* If true, the device will not process any packets received via LoRa that passed via MQTT anywhere on the path towards it.
*/
bool ignore_mqtt = 104;
+
+ /*
+ * Sets the ok_to_mqtt bit on outgoing packets
+ */
+ bool config_ok_to_mqtt = 105;
+ /*
+ * Set where LORA FEM is enabled, disabled, or not present
+ */
+ FEM_LNA_Mode fem_lna_mode = 106;
}
message BluetoothConfig {
@@ -940,6 +1169,52 @@ message Config {
uint32 fixed_pin = 3;
}
+ message SecurityConfig {
+ /*
+ * The public key of the user's device.
+ * Sent out to other nodes on the mesh to allow them to compute a shared secret key.
+ */
+ bytes public_key = 1;
+
+ /*
+ * The private key of the device.
+ * Used to create a shared key with a remote device.
+ */
+ bytes private_key = 2;
+
+ /*
+ * The public key authorized to send admin messages to this node.
+ */
+ repeated bytes admin_key = 3;
+
+ /*
+ * If true, device is considered to be "managed" by a mesh administrator via admin messages
+ * Device is managed by a mesh administrator.
+ */
+ bool is_managed = 4;
+
+ /*
+ * Serial Console over the Stream API."
+ */
+ bool serial_enabled = 5;
+
+ /*
+ * By default we turn off logging as soon as an API client connects (to keep shared serial link quiet).
+ * Output live debug logging over serial or bluetooth is set to true.
+ */
+ bool debug_log_api_enabled = 6;
+
+ /*
+ * Allow incoming device control over the insecure legacy admin channel.
+ */
+ bool admin_channel_enabled = 8;
+ }
+
+ /*
+ * Blank config request, strictly for getting the session key
+ */
+ message SessionkeyConfig {}
+
/*
* Payload Variant
*/
@@ -951,5 +1226,8 @@ message Config {
DisplayConfig display = 5;
LoRaConfig lora = 6;
BluetoothConfig bluetooth = 7;
+ SecurityConfig security = 8;
+ SessionkeyConfig sessionkey = 9;
+ DeviceUIConfig device_ui = 10;
}
}
diff --git a/meshtastic/connection_status.proto b/meshtastic/connection_status.proto
index 7551596..641e916 100644
--- a/meshtastic/connection_status.proto
+++ b/meshtastic/connection_status.proto
@@ -5,7 +5,7 @@ package meshtastic;
option csharp_namespace = "Meshtastic.Protobufs";
option go_package = "github.com/meshtastic/go/generated";
option java_outer_classname = "ConnStatusProtos";
-option java_package = "com.geeksville.mesh";
+option java_package = "org.meshtastic.proto";
option swift_prefix = "";
message DeviceConnectionStatus {
diff --git a/meshtastic/device_ui.options b/meshtastic/device_ui.options
new file mode 100644
index 0000000..a8fab46
--- /dev/null
+++ b/meshtastic/device_ui.options
@@ -0,0 +1,12 @@
+*DeviceUIConfig.screen_brightness int_size:8
+*DeviceUIConfig.screen_timeout int_size:16
+*DeviceUIConfig.ring_tone_id int_size:8
+*DeviceUIConfig.calibration_data max_size:16
+*DeviceUIConfig.compass_mode int_size:8
+*DeviceUIConfig.gps_format int_size:8
+*NodeFilter.node_name max_size:16
+*NodeFilter.hops_away int_size:8
+*NodeFilter.channel int_size:8
+*NodeHighlight.node_name max_size:16
+*GeoPoint.zoom int_size:8
+*Map.style max_size:20
diff --git a/meshtastic/device_ui.proto b/meshtastic/device_ui.proto
new file mode 100644
index 0000000..28d2910
--- /dev/null
+++ b/meshtastic/device_ui.proto
@@ -0,0 +1,389 @@
+syntax = "proto3";
+
+package meshtastic;
+
+option csharp_namespace = "Meshtastic.Protobufs";
+option go_package = "github.com/meshtastic/go/generated";
+option java_outer_classname = "DeviceUIProtos";
+option java_package = "org.meshtastic.proto";
+option swift_prefix = "";
+
+/*
+ * Protobuf structures for device-ui persistency
+ */
+
+message DeviceUIConfig {
+ /*
+ * A version integer used to invalidate saved files when we make incompatible changes.
+ */
+ uint32 version = 1;
+
+ /*
+ * TFT display brightness 1..255
+ */
+ uint32 screen_brightness = 2;
+
+ /*
+ * Screen timeout 0..900
+ */
+ uint32 screen_timeout = 3;
+
+ /*
+ * Screen/Settings lock enabled
+ */
+ bool screen_lock = 4;
+ bool settings_lock = 5;
+ uint32 pin_code = 6;
+
+ /*
+ * Color theme
+ */
+ Theme theme = 7;
+
+ /*
+ * Audible message, banner and ring tone
+ */
+ bool alert_enabled = 8;
+ bool banner_enabled = 9;
+ uint32 ring_tone_id = 10;
+
+ /*
+ * Localization
+ */
+ Language language = 11;
+
+ /*
+ * Node list filter
+ */
+ NodeFilter node_filter = 12;
+
+ /*
+ * Node list highlightening
+ */
+ NodeHighlight node_highlight = 13;
+
+ /*
+ * 8 integers for screen calibration data
+ */
+ bytes calibration_data = 14;
+
+ /*
+ * Map related data
+ */
+ Map map_data = 15;
+
+ /*
+ * Compass mode
+ */
+ CompassMode compass_mode = 16;
+
+ /*
+ * RGB color for BaseUI
+ * 0xRRGGBB format, e.g. 0xFF0000 for red
+ */
+ uint32 screen_rgb_color = 17;
+
+ /*
+ * Clockface analog style
+ * true for analog clockface, false for digital clockface
+ */
+ bool is_clockface_analog = 18;
+
+ /*
+ * How the GPS coordinates are formatted on the OLED screen.
+ */
+ GpsCoordinateFormat gps_format = 19;
+
+ /*
+ * How the GPS coordinates are displayed on the OLED screen.
+ */
+ enum GpsCoordinateFormat {
+ /*
+ * GPS coordinates are displayed in the normal decimal degrees format:
+ * DD.DDDDDD DDD.DDDDDD
+ */
+ DEC = 0;
+
+ /*
+ * GPS coordinates are displayed in the degrees minutes seconds format:
+ * DD°MM'SS"C DDD°MM'SS"C, where C is the compass point representing the locations quadrant
+ */
+ DMS = 1;
+
+ /*
+ * Universal Transverse Mercator format:
+ * ZZB EEEEEE NNNNNNN, where Z is zone, B is band, E is easting, N is northing
+ */
+ UTM = 2;
+
+ /*
+ * Military Grid Reference System format:
+ * ZZB CD EEEEE NNNNN, where Z is zone, B is band, C is the east 100k square, D is the north 100k square,
+ * E is easting, N is northing
+ */
+ MGRS = 3;
+
+ /*
+ * Open Location Code (aka Plus Codes).
+ */
+ OLC = 4;
+
+ /*
+ * Ordnance Survey Grid Reference (the National Grid System of the UK).
+ * Format: AB EEEEE NNNNN, where A is the east 100k square, B is the north 100k square,
+ * E is the easting, N is the northing
+ */
+ OSGR = 5;
+
+ /*
+ * Maidenhead Locator System
+ * Described here: https://en.wikipedia.org/wiki/Maidenhead_Locator_System
+ */
+ MLS = 6;
+ }
+}
+
+message NodeFilter {
+ /*
+ * Filter unknown nodes
+ */
+ bool unknown_switch = 1;
+
+ /*
+ * Filter offline nodes
+ */
+ bool offline_switch = 2;
+
+ /*
+ * Filter nodes w/o public key
+ */
+ bool public_key_switch = 3;
+
+ /*
+ * Filter based on hops away
+ */
+ int32 hops_away = 4;
+
+ /*
+ * Filter nodes w/o position
+ */
+ bool position_switch = 5;
+
+ /*
+ * Filter nodes by matching name string
+ */
+ string node_name = 6;
+
+ /*
+ * Filter based on channel
+ */
+ int32 channel = 7;
+}
+
+message NodeHighlight {
+ /*
+ * Hightlight nodes w/ active chat
+ */
+ bool chat_switch = 1;
+
+ /*
+ * Highlight nodes w/ position
+ */
+ bool position_switch = 2;
+
+ /*
+ * Highlight nodes w/ telemetry data
+ */
+ bool telemetry_switch = 3;
+
+ /*
+ * Highlight nodes w/ iaq data
+ */
+ bool iaq_switch = 4;
+
+ /*
+ * Highlight nodes by matching name string
+ */
+ string node_name = 5;
+}
+
+message GeoPoint {
+ /*
+ * Zoom level
+ */
+ int32 zoom = 1;
+
+ /*
+ * Coordinate: latitude
+ */
+ int32 latitude = 2;
+
+ /*
+ * Coordinate: longitude
+ */
+ int32 longitude = 3;
+}
+
+message Map {
+ /*
+ * Home coordinates
+ */
+ GeoPoint home = 1;
+
+ /*
+ * Map tile style
+ */
+ string style = 2;
+
+ /*
+ * Map scroll follows GPS
+ */
+ bool follow_gps = 3;
+}
+
+enum CompassMode {
+ /*
+ * Compass with dynamic ring and heading
+ */
+ DYNAMIC = 0;
+
+ /*
+ * Compass with fixed ring and heading
+ */
+ FIXED_RING = 1;
+
+ /*
+ * Compass with heading and freeze option
+ */
+ FREEZE_HEADING = 2;
+}
+
+enum Theme {
+ /*
+ * Dark
+ */
+ DARK = 0;
+ /*
+ * Light
+ */
+ LIGHT = 1;
+ /*
+ * Red
+ */
+ RED = 2;
+}
+
+/*
+ * Localization
+ */
+enum Language {
+ /*
+ * English
+ */
+ ENGLISH = 0;
+
+ /*
+ * French
+ */
+ FRENCH = 1;
+
+ /*
+ * German
+ */
+ GERMAN = 2;
+
+ /*
+ * Italian
+ */
+ ITALIAN = 3;
+
+ /*
+ * Portuguese
+ */
+ PORTUGUESE = 4;
+
+ /*
+ * Spanish
+ */
+ SPANISH = 5;
+
+ /*
+ * Swedish
+ */
+ SWEDISH = 6;
+
+ /*
+ * Finnish
+ */
+ FINNISH = 7;
+
+ /*
+ * Polish
+ */
+ POLISH = 8;
+
+ /*
+ * Turkish
+ */
+ TURKISH = 9;
+
+ /*
+ * Serbian
+ */
+ SERBIAN = 10;
+
+ /*
+ * Russian
+ */
+ RUSSIAN = 11;
+
+ /*
+ * Dutch
+ */
+ DUTCH = 12;
+
+ /*
+ * Greek
+ */
+ GREEK = 13;
+
+ /*
+ * Norwegian
+ */
+ NORWEGIAN = 14;
+
+ /*
+ * Slovenian
+ */
+ SLOVENIAN = 15;
+
+ /*
+ * Ukrainian
+ */
+ UKRAINIAN = 16;
+
+ /*
+ * Bulgarian
+ */
+ BULGARIAN = 17;
+
+ /*
+ * Czech
+ */
+ CZECH = 18;
+
+ /*
+ * Danish
+ */
+ DANISH = 19;
+
+ /*
+ * Simplified Chinese (experimental)
+ */
+ SIMPLIFIED_CHINESE = 30;
+
+ /*
+ * Traditional Chinese (experimental)
+ */
+ TRADITIONAL_CHINESE = 31;
+}
diff --git a/meshtastic/deviceonly.options b/meshtastic/deviceonly.options
index e9477a0..d6aae0c 100644
--- a/meshtastic/deviceonly.options
+++ b/meshtastic/deviceonly.options
@@ -6,11 +6,13 @@
*ChannelFile.channels max_count:8
-*OEMStore.oem_text max_size:40
-*OEMStore.oem_icon_bits max_size:2048
-*OEMStore.oem_aes_key max_size:32
-
*DeviceState.node_remote_hardware_pins max_count:12
*NodeInfoLite.channel int_size:8
*NodeInfoLite.hops_away int_size:8
+*NodeInfoLite.next_hop int_size:8
+
+*UserLite.long_name max_size:40
+*UserLite.short_name max_size:5
+*UserLite.public_key max_size:32 # public key
+*UserLite.macaddr max_size:6 fixed_length:true
\ No newline at end of file
diff --git a/meshtastic/deviceonly.proto b/meshtastic/deviceonly.proto
index f5345c9..b7c377a 100644
--- a/meshtastic/deviceonly.proto
+++ b/meshtastic/deviceonly.proto
@@ -2,20 +2,177 @@ syntax = "proto3";
package meshtastic;
+/* trunk-ignore(buf-lint/COMPILE) */
import "meshtastic/channel.proto";
+import "meshtastic/config.proto";
import "meshtastic/localonly.proto";
import "meshtastic/mesh.proto";
import "meshtastic/telemetry.proto";
-import "meshtastic/module_config.proto";
import "nanopb.proto";
option csharp_namespace = "Meshtastic.Protobufs";
option go_package = "github.com/meshtastic/go/generated";
option java_outer_classname = "DeviceOnly";
-option java_package = "com.geeksville.mesh";
+option java_package = "org.meshtastic.proto";
option swift_prefix = "";
option (nanopb_fileopt).include = "";
+/*
+ * Position with static location information only for NodeDBLite
+ */
+message PositionLite {
+ /*
+ * The new preferred location encoding, multiply by 1e-7 to get degrees
+ * in floating point
+ */
+ sfixed32 latitude_i = 1;
+
+ /*
+ * TODO: REPLACE
+ */
+ sfixed32 longitude_i = 2;
+
+ /*
+ * In meters above MSL (but see issue #359)
+ */
+ int32 altitude = 3;
+
+ /*
+ * This is usually not sent over the mesh (to save space), but it is sent
+ * from the phone so that the local device can set its RTC If it is sent over
+ * the mesh (because there are devices on the mesh without GPS), it will only
+ * be sent by devices which has a hardware GPS clock.
+ * seconds since 1970
+ */
+ fixed32 time = 4;
+
+ /*
+ * TODO: REPLACE
+ */
+ Position.LocSource location_source = 5;
+}
+
+message UserLite {
+ /*
+ * This is the addr of the radio.
+ */
+ bytes macaddr = 1 [deprecated = true];
+
+ /*
+ * A full name for this user, i.e. "Kevin Hester"
+ */
+ string long_name = 2;
+
+ /*
+ * A VERY short name, ideally two characters.
+ * Suitable for a tiny OLED screen
+ */
+ string short_name = 3;
+
+ /*
+ * TBEAM, HELTEC, etc...
+ * Starting in 1.2.11 moved to hw_model enum in the NodeInfo object.
+ * Apps will still need the string here for older builds
+ * (so OTA update can find the right image), but if the enum is available it will be used instead.
+ */
+ HardwareModel hw_model = 4;
+
+ /*
+ * In some regions Ham radio operators have different bandwidth limitations than others.
+ * If this user is a licensed operator, set this flag.
+ * Also, "long_name" should be their licence number.
+ */
+ bool is_licensed = 5;
+
+ /*
+ * Indicates that the user's role in the mesh
+ */
+ Config.DeviceConfig.Role role = 6;
+
+ /*
+ * The public key of the user's device.
+ * This is sent out to other nodes on the mesh to allow them to compute a shared secret key.
+ */
+ bytes public_key = 7;
+
+ /*
+ * Whether or not the node can be messaged
+ */
+ optional bool is_unmessagable = 9;
+}
+
+message NodeInfoLite {
+ /*
+ * The node number
+ */
+ uint32 num = 1;
+
+ /*
+ * The user info for this node
+ */
+ UserLite user = 2;
+
+ /*
+ * This position data. Note: before 1.2.14 we would also store the last time we've heard from this node in position.time, that is no longer true.
+ * Position.time now indicates the last time we received a POSITION from that node.
+ */
+ PositionLite position = 3;
+
+ /*
+ * Returns the Signal-to-noise ratio (SNR) of the last received message,
+ * as measured by the receiver. Return SNR of the last received message in dB
+ */
+ float snr = 4;
+
+ /*
+ * Set to indicate the last time we received a packet from this node
+ */
+ fixed32 last_heard = 5;
+ /*
+ * The latest device metrics for the node.
+ */
+ DeviceMetrics device_metrics = 6;
+
+ /*
+ * local channel index we heard that node on. Only populated if its not the default channel.
+ */
+ uint32 channel = 7;
+
+ /*
+ * True if we witnessed the node over MQTT instead of LoRA transport
+ */
+ bool via_mqtt = 8;
+
+ /*
+ * Number of hops away from us this node is (0 if direct neighbor)
+ */
+ optional uint32 hops_away = 9;
+
+ /*
+ * True if node is in our favorites list
+ * Persists between NodeDB internal clean ups
+ */
+ bool is_favorite = 10;
+
+ /*
+ * True if node is in our ignored list
+ * Persists between NodeDB internal clean ups
+ */
+ bool is_ignored = 11;
+
+ /*
+ * Last byte of the node number of the node that should be used as the next hop to reach this node.
+ */
+ uint32 next_hop = 12;
+
+ /*
+ * Bitfield for storing booleans.
+ * LSB 0 is_key_manually_verified
+ * LSB 1 is_muted
+ */
+ uint32 bitfield = 13;
+}
+
/*
* This message is never sent over the wire, but it is used for serializing DB
* state to flash in the device code
@@ -61,9 +218,10 @@ message DeviceState {
bool no_save = 9 [deprecated = true];
/*
- * Some GPS receivers seem to have bogus settings from the factory, so we always do one factory reset.
+ * Previously used to manage GPS factory resets.
+ * Deprecated in 2.5.23
*/
- bool did_gps_reset = 11;
+ bool did_gps_reset = 11 [deprecated = true];
/*
* We keep the last received waypoint stored in the device flash,
@@ -76,100 +234,20 @@ message DeviceState {
* The mesh's nodes with their available gpio pins for RemoteHardware module
*/
repeated NodeRemoteHardwarePin node_remote_hardware_pins = 13;
+}
+
+message NodeDatabase {
+ /*
+ * A version integer used to invalidate old save files when we make
+ * incompatible changes This integer is set at build time and is private to
+ * NodeDB.cpp in the device code.
+ */
+ uint32 version = 1;
/*
* New lite version of NodeDB to decrease memory footprint
*/
- repeated NodeInfoLite node_db_lite = 14 [(nanopb).callback_datatype="std::vector"];
-}
-
-message NodeInfoLite {
- /*
- * The node number
- */
- uint32 num = 1;
-
- /*
- * The user info for this node
- */
- User user = 2;
-
- /*
- * This position data. Note: before 1.2.14 we would also store the last time we've heard from this node in position.time, that is no longer true.
- * Position.time now indicates the last time we received a POSITION from that node.
- */
- PositionLite position = 3;
-
- /*
- * Returns the Signal-to-noise ratio (SNR) of the last received message,
- * as measured by the receiver. Return SNR of the last received message in dB
- */
- float snr = 4;
-
- /*
- * Set to indicate the last time we received a packet from this node
- */
- fixed32 last_heard = 5;
- /*
- * The latest device metrics for the node.
- */
- DeviceMetrics device_metrics = 6;
-
- /*
- * local channel index we heard that node on. Only populated if its not the default channel.
- */
- uint32 channel = 7;
-
- /*
- * True if we witnessed the node over MQTT instead of LoRA transport
- */
- bool via_mqtt = 8;
-
- /*
- * Number of hops away from us this node is (0 if adjacent)
- */
- uint32 hops_away = 9;
-
- /*
- * True if node is in our favorites list
- * Persists between NodeDB internal clean ups
- */
- bool is_favorite = 10;
-}
-
-/*
- * Position with static location information only for NodeDBLite
- */
-message PositionLite {
- /*
- * The new preferred location encoding, multiply by 1e-7 to get degrees
- * in floating point
- */
- sfixed32 latitude_i = 1;
-
- /*
- * TODO: REPLACE
- */
- sfixed32 longitude_i = 2;
-
- /*
- * In meters above MSL (but see issue #359)
- */
- int32 altitude = 3;
-
- /*
- * This is usually not sent over the mesh (to save space), but it is sent
- * from the phone so that the local device can set its RTC If it is sent over
- * the mesh (because there are devices on the mesh without GPS), it will only
- * be sent by devices which has a hardware GPS clock.
- * seconds since 1970
- */
- fixed32 time = 4;
-
- /*
- * TODO: REPLACE
- */
- Position.LocSource location_source = 5;
+ repeated NodeInfoLite nodes = 2 [(nanopb).callback_datatype = "std::vector"];
}
/*
@@ -190,82 +268,36 @@ message ChannelFile {
}
/*
- * TODO: REPLACE
+ * The on-disk backup of the node's preferences
*/
-enum ScreenFonts {
+message BackupPreferences {
/*
- * TODO: REPLACE
+ * The version of the backup
*/
- FONT_SMALL = 0;
+ uint32 version = 1;
/*
- * TODO: REPLACE
+ * The timestamp of the backup (if node has time)
*/
- FONT_MEDIUM = 1;
+ fixed32 timestamp = 2;
/*
- * TODO: REPLACE
+ * The node's configuration
*/
- FONT_LARGE = 2;
-}
-
-/*
- * This can be used for customizing the firmware distribution. If populated,
- * show a secondary bootup screen with custom logo and text for 2.5 seconds.
- */
-message OEMStore {
- /*
- * The Logo width in Px
- */
- uint32 oem_icon_width = 1;
-
- /*
- * The Logo height in Px
- */
- uint32 oem_icon_height = 2;
-
- /*
- * The Logo in XBM bytechar format
- */
- bytes oem_icon_bits = 3;
-
- /*
- * Use this font for the OEM text.
- */
- ScreenFonts oem_font = 4;
-
- /*
- * Use this font for the OEM text.
- */
- string oem_text = 5;
-
- /*
- * The default device encryption key, 16 or 32 byte
- */
- bytes oem_aes_key = 6;
-
- /*
- * A Preset LocalConfig to apply during factory reset
- */
- LocalConfig oem_local_config = 7;
-
- /*
- * A Preset LocalModuleConfig to apply during factory reset
- */
- LocalModuleConfig oem_local_module_config = 8;
-}
-
-/*
- * RemoteHardwarePins associated with a node
- */
-message NodeRemoteHardwarePin {
- /*
- * The node_num exposing the available gpio pin
- */
- uint32 node_num = 1;
-
- /*
- * The the available gpio pin for usage with RemoteHardware module
- */
- RemoteHardwarePin pin = 2;
+ LocalConfig config = 3;
+
+ /*
+ * The node's module configuration
+ */
+ LocalModuleConfig module_config = 4;
+
+ /*
+ * The node's channels
+ */
+ ChannelFile channels = 5;
+
+ /*
+ * The node's user (owner) information
+ */
+ User owner = 6;
}
diff --git a/meshtastic/interdevice.options b/meshtastic/interdevice.options
new file mode 100644
index 0000000..97df282
--- /dev/null
+++ b/meshtastic/interdevice.options
@@ -0,0 +1 @@
+*InterdeviceMessage.nmea max_size:1024
diff --git a/meshtastic/interdevice.proto b/meshtastic/interdevice.proto
new file mode 100644
index 0000000..f646368
--- /dev/null
+++ b/meshtastic/interdevice.proto
@@ -0,0 +1,44 @@
+syntax = "proto3";
+
+package meshtastic;
+
+option csharp_namespace = "Meshtastic.Protobufs";
+option go_package = "github.com/meshtastic/go/generated";
+option java_outer_classname = "InterdeviceProtos";
+option java_package = "org.meshtastic.proto";
+option swift_prefix = "";
+
+// encapsulate up to 1k of NMEA string data
+
+enum MessageType {
+ ACK = 0;
+ COLLECT_INTERVAL = 160; // in ms
+ BEEP_ON = 161; // duration ms
+ BEEP_OFF = 162; // cancel prematurely
+ SHUTDOWN = 163;
+ POWER_ON = 164;
+ SCD41_TEMP = 176;
+ SCD41_HUMIDITY = 177;
+ SCD41_CO2 = 178;
+ AHT20_TEMP = 179;
+ AHT20_HUMIDITY = 180;
+ TVOC_INDEX = 181;
+}
+
+message SensorData {
+ // The message type
+ MessageType type = 1;
+ // The sensor data, either as a float or an uint32
+ oneof data {
+ float float_value = 2;
+ uint32 uint32_value = 3;
+ }
+}
+
+message InterdeviceMessage {
+ // The message data
+ oneof data {
+ string nmea = 1;
+ SensorData sensor = 2;
+ }
+}
diff --git a/meshtastic/localonly.proto b/meshtastic/localonly.proto
index 9297dff..2a6c7ca 100644
--- a/meshtastic/localonly.proto
+++ b/meshtastic/localonly.proto
@@ -8,7 +8,7 @@ import "meshtastic/module_config.proto";
option csharp_namespace = "Meshtastic.Protobufs";
option go_package = "github.com/meshtastic/go/generated";
option java_outer_classname = "LocalOnlyProtos";
-option java_package = "com.geeksville.mesh";
+option java_package = "org.meshtastic.proto";
option swift_prefix = "";
/*
@@ -58,6 +58,11 @@ message LocalConfig {
* NodeDB.cpp in the device code.
*/
uint32 version = 8;
+
+ /*
+ * The part of the config that is specific to Security settings
+ */
+ Config.SecurityConfig security = 9;
}
message LocalModuleConfig {
@@ -114,7 +119,7 @@ message LocalModuleConfig {
/*
* The part of the config that is specific to the Ambient Lighting module
*/
- ModuleConfig.AmbientLightingConfig ambient_lighting = 12;
+ ModuleConfig.AmbientLightingConfig ambient_lighting = 12;
/*
* The part of the config that is specific to the Detection Sensor module
@@ -126,10 +131,25 @@ message LocalModuleConfig {
*/
ModuleConfig.PaxcounterConfig paxcounter = 14;
+ /*
+ * StatusMessage Config
+ */
+ ModuleConfig.StatusMessageConfig statusmessage = 15;
+
+ /*
+ * The part of the config that is specific to the Traffic Management module
+ */
+ ModuleConfig.TrafficManagementConfig traffic_management = 16;
+
+ /*
+ * TAK Config
+ */
+ ModuleConfig.TAKConfig tak = 17;
+
/*
* A version integer used to invalidate old save files when we make
* incompatible changes This integer is set at build time and is private to
* NodeDB.cpp in the device code.
*/
uint32 version = 8;
-}
\ No newline at end of file
+}
diff --git a/meshtastic/mesh.options b/meshtastic/mesh.options
index aedfe99..2341e6c 100644
--- a/meshtastic/mesh.options
+++ b/meshtastic/mesh.options
@@ -3,25 +3,37 @@
*macaddr max_size:6 fixed_length:true # macaddrs
*id max_size:16 # node id strings
+*public_key max_size:32 # public key
*User.long_name max_size:40
*User.short_name max_size:5
*RouteDiscovery.route max_count:8
+*RouteDiscovery.snr_towards max_count:8
+*RouteDiscovery.snr_towards int_size:8
+*RouteDiscovery.route_back max_count:8
+*RouteDiscovery.snr_back max_count:8
+*RouteDiscovery.snr_back int_size:8
# note: this payload length is ONLY the bytes that are sent inside of the Data protobuf (excluding protobuf overhead). The 16 byte header is
# outside of this envelope
-*Data.payload max_size:237
+*Data.payload max_size:233
+*Data.bitfield int_size:8
*NodeInfo.channel int_size:8
*NodeInfo.hops_away int_size:8
# Big enough for 1.2.28.568032c-d
*MyNodeInfo.firmware_version max_size:18
+*MyNodeInfo.device_id max_size:16
+*MyNodeInfo.pio_env max_size:40
*MyNodeInfo.air_period_tx max_count:8
*MyNodeInfo.air_period_rx max_count:8
+*MyNodeInfo.firmware_edition int_size:8
+*MyNodeInfo.nodedb_count int_size:16
+
# Note: the actual limit (because of header bytes) on the size of encrypted payloads is 251 bytes, but I use 256
# here because we might need to fill with zeros for padding to encryption block size (16 bytes per block)
*MeshPacket.encrypted max_size:256
@@ -29,6 +41,8 @@
*MeshPacket.hop_limit int_size:8
*MeshPacket.hop_start int_size:8
*MeshPacket.channel int_size:8
+*MeshPacket.next_hop int_size:8
+*MeshPacket.relay_node int_size:8
*QueueStatus.res int_size:8
*QueueStatus.free int_size:8
@@ -40,14 +54,35 @@
*Routing.variant anonymous_oneof:true
-*LogRecord.message max_size:64
-*LogRecord.source max_size:8
+*LogRecord.message max_size:384
+*LogRecord.source max_size:32
+
+*FileInfo.file_name max_size:228
+
+*ClientNotification.message max_size:400
+
+*KeyVerificationNumberInform.remote_longname max_size:40
+*KeyVerificationNumberRequest.remote_longname max_size:40
+*KeyVerificationFinal.remote_longname max_size:40
+*KeyVerificationFinal.verification_characters max_size:10
+
+*KeyVerification.hash1 max_size:32
+*KeyVerification.hash2 max_size:32
+
+*StoreForwardPlusPlus.message_hash max_size:32
+*StoreForwardPlusPlus.commit_hash max_size:32
+*StoreForwardPlusPlus.root_hash max_size:32
+*StoreForwardPlusPlus.message max_size:240
+
+*RemoteShell.payload max_size:200
+
+*StatusMessage.status max_size:80
# MyMessage.name max_size:40
# or fixed_length or fixed_count, or max_count
#This value may want to be a few bytes smaller to compensate for the parent fields.
-*Compressed.data max_size:237
+*Compressed.data max_size:233
*Waypoint.name max_size:30
*Waypoint.description max_size:100
@@ -59,3 +94,7 @@
*MqttClientProxyMessage.topic max_size:60
*MqttClientProxyMessage.data max_size:435
*MqttClientProxyMessage.text max_size:435
+
+*ChunkedPayload.chunk_count int_size:16
+*ChunkedPayload.chunk_index int_size:16
+*ChunkedPayload.payload_chunk max_size:228
diff --git a/meshtastic/mesh.proto b/meshtastic/mesh.proto
index 60a3906..fb585b9 100644
--- a/meshtastic/mesh.proto
+++ b/meshtastic/mesh.proto
@@ -4,6 +4,7 @@ package meshtastic;
import "meshtastic/channel.proto";
import "meshtastic/config.proto";
+import "meshtastic/device_ui.proto";
import "meshtastic/module_config.proto";
import "meshtastic/portnums.proto";
import "meshtastic/telemetry.proto";
@@ -12,28 +13,28 @@ import "meshtastic/xmodem.proto";
option csharp_namespace = "Meshtastic.Protobufs";
option go_package = "github.com/meshtastic/go/generated";
option java_outer_classname = "MeshProtos";
-option java_package = "com.geeksville.mesh";
+option java_package = "org.meshtastic.proto";
option swift_prefix = "";
/*
- * a gps position
+ * A GPS Position
*/
message Position {
/*
* The new preferred location encoding, multiply by 1e-7 to get degrees
* in floating point
*/
- sfixed32 latitude_i = 1;
+ optional sfixed32 latitude_i = 1;
/*
* TODO: REPLACE
*/
- sfixed32 longitude_i = 2;
+ optional sfixed32 longitude_i = 2;
/*
* In meters above MSL (but see issue #359)
*/
- int32 altitude = 3;
+ optional int32 altitude = 3;
/*
* This is usually not sent over the mesh (to save space), but it is sent
@@ -122,12 +123,12 @@ message Position {
/*
* HAE altitude in meters - can be used instead of MSL altitude
*/
- sint32 altitude_hae = 9;
+ optional sint32 altitude_hae = 9;
/*
* Geoidal separation in meters
*/
- sint32 altitude_geoidal_separation = 10;
+ optional sint32 altitude_geoidal_separation = 10;
/*
* Horizontal, Vertical and Position Dilution of Precision, in 1/100 units
@@ -163,12 +164,12 @@ message Position {
* - "yaw" indicates a relative rotation about the vertical axis
* TODO: REMOVE/INTEGRATE
*/
- uint32 ground_speed = 15;
+ optional uint32 ground_speed = 15;
/*
* TODO: REPLACE
*/
- uint32 ground_track = 16;
+ optional uint32 ground_track = 16;
/*
* GPS fix quality (from NMEA GxGGA statement or similar)
@@ -319,6 +320,31 @@ enum HardwareModel {
*/
LORA_TYPE = 19;
+ /*
+ * wiphone https://www.wiphone.io/
+ */
+ WIPHONE = 20;
+
+ /*
+ * WIO Tracker WM1110 family from Seeed Studio. Includes wio-1110-tracker and wio-1110-sdk
+ */
+ WIO_WM1110 = 21;
+
+ /*
+ * RAK2560 Solar base station based on RAK4630
+ */
+ RAK2560 = 22;
+
+ /*
+ * Heltec HRU-3601: https://heltec.org/project/hru-3601/
+ */
+ HELTEC_HRU_3601 = 23;
+
+ /*
+ * Heltec Wireless Bridge
+ */
+ HELTEC_WIRELESS_BRIDGE = 24;
+
/*
* B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station
*/
@@ -340,8 +366,8 @@ enum HardwareModel {
SENSELORA_S3 = 28;
/*
- * Canary Radio Company - CanaryOne: https://canaryradio.io/products/canaryone
- */
+ * Canary Radio Company - CanaryOne: https://canaryradio.io/products/canaryone
+ */
CANARYONE = 29;
/*
@@ -362,9 +388,9 @@ enum HardwareModel {
LORA_RELAY_V1 = 32;
/*
- * TODO: REPLACE
+ * T-Echo Plus device from LilyGo
*/
- NRF52840DK = 33;
+ T_ECHO_PLUS = 33;
/*
* TODO: REPLACE
@@ -407,7 +433,7 @@ enum HardwareModel {
DR_DEV = 41;
/*
- * M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, Paper) https://m5stack.com/
+ * M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, CoreS3, Paper) https://m5stack.com/
*/
M5STACK = 42;
@@ -456,13 +482,13 @@ enum HardwareModel {
* LilyGo T-Watch S3 with ESP32-S3 CPU and IPS display
*/
T_WATCH_S3 = 51;
-
+
/*
* Bobricius Picomputer with ESP32-S3 CPU, Keyboard and IPS display
*/
PICOMPUTER_S3 = 52;
-
- /*
+
+ /*
* Heltec HT-CT62 with ESP32-C3 CPU and SX1262 LoRa
*/
HELTEC_HT62 = 53;
@@ -481,7 +507,7 @@ enum HardwareModel {
* CircuitMess Chatter 2 LLCC68 Lora Module and ESP32 Wroom
* Lora module can be swapped out for a Heltec RA-62 which is "almost" pin compatible
* with one cut and one jumper Meshtastic works
- */
+ */
CHATTER_2 = 56;
/*
@@ -498,7 +524,370 @@ enum HardwareModel {
* Older "V1.0" Variant
*/
HELTEC_WIRELESS_TRACKER_V1_0 = 58;
-
+
+ /*
+ * unPhone with ESP32-S3, TFT touchscreen, LSM6DS3TR-C accelerometer and gyroscope
+ */
+ UNPHONE = 59;
+
+ /*
+ * Teledatics TD-LORAC NRF52840 based M.2 LoRA module
+ * Compatible with the TD-WRLS development board
+ */
+ TD_LORAC = 60;
+
+ /*
+ * CDEBYTE EoRa-S3 board using their own MM modules, clone of LILYGO T3S3
+ */
+ CDEBYTE_EORA_S3 = 61;
+
+ /*
+ * TWC_MESH_V4
+ * Adafruit NRF52840 feather express with SX1262, SSD1306 OLED and NEO6M GPS
+ */
+ TWC_MESH_V4 = 62;
+
+ /*
+ * NRF52_PROMICRO_DIY
+ * Promicro NRF52840 with SX1262/LLCC68, SSD1306 OLED and NEO6M GPS
+ */
+ NRF52_PROMICRO_DIY = 63;
+
+ /*
+ * RadioMaster 900 Bandit Nano, https://www.radiomasterrc.com/products/bandit-nano-expresslrs-rf-module
+ * ESP32-D0WDQ6 With SX1276/SKY66122, SSD1306 OLED and No GPS
+ */
+ RADIOMASTER_900_BANDIT_NANO = 64;
+
+ /*
+ * Heltec Capsule Sensor V3 with ESP32-S3 CPU, Portable LoRa device that can replace GNSS modules or sensors
+ */
+ HELTEC_CAPSULE_SENSOR_V3 = 65;
+
+ /*
+ * Heltec Vision Master T190 with ESP32-S3 CPU, and a 1.90 inch TFT display
+ */
+ HELTEC_VISION_MASTER_T190 = 66;
+
+ /*
+ * Heltec Vision Master E213 with ESP32-S3 CPU, and a 2.13 inch E-Ink display
+ */
+ HELTEC_VISION_MASTER_E213 = 67;
+
+ /*
+ * Heltec Vision Master E290 with ESP32-S3 CPU, and a 2.9 inch E-Ink display
+ */
+ HELTEC_VISION_MASTER_E290 = 68;
+
+ /*
+ * Heltec Mesh Node T114 board with nRF52840 CPU, and a 1.14 inch TFT display, Ultimate low-power design,
+ * specifically adapted for the Meshtatic project
+ */
+ HELTEC_MESH_NODE_T114 = 69;
+
+ /*
+ * Sensecap Indicator from Seeed Studio. ESP32-S3 device with TFT and RP2040 coprocessor
+ */
+ SENSECAP_INDICATOR = 70;
+
+ /*
+ * Seeed studio T1000-E tracker card. NRF52840 w/ LR1110 radio, GPS, button, buzzer, and sensors.
+ */
+ TRACKER_T1000_E = 71;
+
+ /*
+ * RAK3172 STM32WLE5 Module (https://store.rakwireless.com/products/wisduo-lpwan-module-rak3172)
+ */
+ RAK3172 = 72;
+
+ /*
+ * Seeed Studio Wio-E5 (either mini or Dev kit) using STM32WL chip.
+ */
+ WIO_E5 = 73;
+
+ /*
+ * RadioMaster 900 Bandit, https://www.radiomasterrc.com/products/bandit-expresslrs-rf-module
+ * SSD1306 OLED and No GPS
+ */
+ RADIOMASTER_900_BANDIT = 74;
+
+ /*
+ * Minewsemi ME25LS01 (ME25LE01_V1.0). NRF52840 w/ LR1110 radio, buttons and leds and pins.
+ */
+ ME25LS01_4Y10TD = 75;
+
+ /*
+ * RP2040_FEATHER_RFM95
+ * Adafruit Feather RP2040 with RFM95 LoRa Radio RFM95 with SX1272, SSD1306 OLED
+ * https://www.adafruit.com/product/5714
+ * https://www.adafruit.com/product/326
+ * https://www.adafruit.com/product/938
+ * ^^^ short A0 to switch to I2C address 0x3C
+ *
+ */
+ RP2040_FEATHER_RFM95 = 76;
+
+ /* M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, CoreS3, Paper) https://m5stack.com/ */
+ M5STACK_COREBASIC = 77;
+ M5STACK_CORE2 = 78;
+
+ /* Pico2 with Waveshare Hat, same as Pico */
+ RPI_PICO2 = 79;
+
+ /* M5 esp32 based MCU modules with enclosure, TFT and LORA Shields. All Variants (Basic, Core, Fire, Core2, CoreS3, Paper) https://m5stack.com/ */
+ M5STACK_CORES3 = 80;
+
+ /* Seeed XIAO S3 DK*/
+ SEEED_XIAO_S3 = 81;
+
+ /*
+ * Nordic nRF52840+Semtech SX1262 LoRa BLE Combo Module. nRF52840+SX1262 MS24SF1
+ */
+ MS24SF1 = 82;
+
+ /*
+ * Lilygo TLora-C6 with the new ESP32-C6 MCU
+ */
+ TLORA_C6 = 83;
+
+ /*
+ * WisMesh Tap
+ * RAK-4631 w/ TFT in injection modled case
+ */
+ WISMESH_TAP = 84;
+
+ /*
+ * Similar to PORTDUINO but used by Routastic devices, this is not any
+ * particular device and does not run Meshtastic's code but supports
+ * the same frame format.
+ * Runs on linux, see https://github.com/Jorropo/routastic
+ */
+ ROUTASTIC = 85;
+
+ /*
+ * Mesh-Tab, esp32 based
+ * https://github.com/valzzu/Mesh-Tab
+ */
+ MESH_TAB = 86;
+
+ /*
+ * MeshLink board developed by LoraItalia. NRF52840, eByte E22900M22S (Will also come with other frequencies), 25w MPPT solar charger (5v,12v,18v selectable), support for gps, buzzer, oled or e-ink display, 10 gpios, hardware watchdog
+ * https://www.loraitalia.it
+ */
+ MESHLINK = 87;
+
+ /*
+ * Seeed XIAO nRF52840 + Wio SX1262 kit
+ */
+ XIAO_NRF52_KIT = 88;
+
+ /*
+ * Elecrow ThinkNode M1 & M2
+ * https://www.elecrow.com/wiki/ThinkNode-M1_Transceiver_Device(Meshtastic)_Power_By_nRF52840.html
+ * https://www.elecrow.com/wiki/ThinkNode-M2_Transceiver_Device(Meshtastic)_Power_By_NRF52840.html (this actually uses ESP32-S3)
+ */
+ THINKNODE_M1 = 89;
+ THINKNODE_M2 = 90;
+
+ /*
+ * Lilygo T-ETH-Elite
+ */
+ T_ETH_ELITE = 91;
+
+ /*
+ * Heltec HRI-3621 industrial probe
+ */
+ HELTEC_SENSOR_HUB = 92;
+
+ /*
+ * Muzi Works Muzi-Base device
+ */
+ MUZI_BASE = 93;
+
+ /*
+ * Heltec Magnetic Power Bank with Meshtastic compatible
+ */
+ HELTEC_MESH_POCKET = 94;
+
+ /*
+ * Seeed Solar Node
+ */
+ SEEED_SOLAR_NODE = 95;
+
+ /*
+ * NomadStar Meteor Pro https://nomadstar.ch/
+ */
+ NOMADSTAR_METEOR_PRO = 96;
+
+ /*
+ * Elecrow CrowPanel Advance models, ESP32-S3 and TFT with SX1262 radio plugin
+ */
+ CROWPANEL = 97;
+
+ /*
+ * Lilygo LINK32 board with sensors
+ */
+ LINK_32 = 98;
+
+ /*
+ * Seeed Tracker L1
+ */
+ SEEED_WIO_TRACKER_L1 = 99;
+
+ /*
+ * Seeed Tracker L1 EINK driver
+ */
+ SEEED_WIO_TRACKER_L1_EINK = 100;
+
+ /*
+ * Muzi Works R1 Neo
+ */
+ MUZI_R1_NEO = 101;
+
+ /*
+ * Lilygo T-Deck Pro
+ */
+ T_DECK_PRO = 102;
+
+ /*
+ * Lilygo TLora Pager
+ */
+ T_LORA_PAGER = 103;
+
+ /*
+ * M5Stack Reserved
+ */
+ M5STACK_RESERVED = 104; // 0x68
+
+ /*
+ * RAKwireless WisMesh Tag
+ */
+ WISMESH_TAG = 105;
+
+ /*
+ * RAKwireless WisBlock Core RAK3312 https://docs.rakwireless.com/product-categories/wisduo/rak3112-module/overview/
+ */
+ RAK3312 = 106;
+
+ /*
+ * Elecrow ThinkNode M5 https://www.elecrow.com/wiki/ThinkNode_M5_Meshtastic_LoRa_Signal_Transceiver_ESP32-S3.html
+ */
+ THINKNODE_M5 = 107;
+
+ /*
+ * MeshSolar is an integrated power management and communication solution designed for outdoor low-power devices.
+ * https://heltec.org/project/meshsolar/
+ */
+ HELTEC_MESH_SOLAR = 108;
+
+ /*
+ * Lilygo T-Echo Lite
+ */
+ T_ECHO_LITE = 109;
+
+ /*
+ * New Heltec LoRA32 with ESP32-S3 CPU
+ */
+ HELTEC_V4 = 110;
+
+ /*
+ * M5Stack C6L
+ */
+ M5STACK_C6L = 111;
+
+ /*
+ * M5Stack Cardputer Adv
+ */
+ M5STACK_CARDPUTER_ADV = 112;
+
+ /*
+ * ESP32S3 main controller with GPS and TFT screen.
+ */
+ HELTEC_WIRELESS_TRACKER_V2 = 113;
+
+ /*
+ * LilyGo T-Watch Ultra
+ */
+ T_WATCH_ULTRA = 114;
+
+ /*
+ * Elecrow ThinkNode M3
+ */
+ THINKNODE_M3 = 115;
+
+ /*
+ * RAK WISMESH_TAP_V2 with ESP32-S3 CPU
+ */
+ WISMESH_TAP_V2 = 116;
+
+ /*
+ * RAK3401
+ */
+ RAK3401 = 117;
+
+ /*
+ * RAK6421 Hat+
+ */
+ RAK6421 = 118;
+
+ /*
+ * Elecrow ThinkNode M4
+ */
+ THINKNODE_M4 = 119;
+
+ /*
+ * Elecrow ThinkNode M6
+ */
+ THINKNODE_M6 = 120;
+
+ /*
+ * Elecrow Meshstick 1262
+ */
+ MESHSTICK_1262 = 121;
+
+ /*
+ * LilyGo T-Beam 1W
+ */
+ TBEAM_1_WATT = 122;
+
+ /*
+ * LilyGo T5 S3 ePaper Pro (V1 and V2)
+ */
+ T5_S3_EPAPER_PRO = 123;
+
+ /*
+ * LilyGo T-Beam BPF (144-148Mhz)
+ */
+ TBEAM_BPF = 124;
+
+ /*
+ * LilyGo T-Mini E-paper S3 Kit
+ */
+ MINI_EPAPER_S3 = 125;
+
+ /*
+ * LilyGo T-Display S3 Pro LR1121
+ */
+ TDISPLAY_S3_PRO = 126;
+
+ /*
+ * Heltec Mesh Node T096 board features an nRF52840 CPU and a TFT screen.
+ */
+ HELTEC_MESH_NODE_T096 = 127;
+
+ /*
+ * Seeed studio T1000-E Pro tracker card. NRF52840 w/ LR2021 radio,
+ * GPS, button, buzzer, and sensors.
+ */
+ TRACKER_T1000_E_PRO = 128;
+
+ /*
+ * Elecrow ThinkNode M7, M8 and M9
+ */
+ THINKNODE_M7 = 129;
+ THINKNODE_M8 = 130;
+ THINKNODE_M9 = 131;
+
/*
* ------------------------------------------------------------------------------------------------------------------------------------------
* Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
@@ -575,16 +964,42 @@ message User {
* Indicates that the user's role in the mesh
*/
Config.DeviceConfig.Role role = 7;
+
+ /*
+ * The public key of the user's device.
+ * This is sent out to other nodes on the mesh to allow them to compute a shared secret key.
+ */
+ bytes public_key = 8;
+
+ /*
+ * Whether or not the node can be messaged
+ */
+ optional bool is_unmessagable = 9;
}
/*
- * A message used in our Dynamic Source Routing protocol (RFC 4728 based)
+ * A message used in a traceroute
*/
message RouteDiscovery {
/*
- * The list of nodenums this packet has visited so far
+ * The list of nodenums this packet has visited so far to the destination.
*/
repeated fixed32 route = 1;
+
+ /*
+ * The list of SNRs (in dB, scaled by 4) in the route towards the destination.
+ */
+ repeated int32 snr_towards = 2;
+
+ /*
+ * The list of nodenums the packet has visited on the way back from the destination.
+ */
+ repeated fixed32 route_back = 3;
+
+ /*
+ * The list of SNRs (in dB, scaled by 4) in the route back from the destination.
+ */
+ repeated int32 snr_back = 4;
}
/*
@@ -657,6 +1072,38 @@ message Routing {
* (i.e you did not send the request on the required bound channel)
*/
NOT_AUTHORIZED = 33;
+
+ /*
+ * The client specified a PKI transport, but the node was unable to send the packet using PKI (and did not send the message at all)
+ */
+ PKI_FAILED = 34;
+
+ /*
+ * The receiving node does not have a Public Key to decode with
+ */
+ PKI_UNKNOWN_PUBKEY = 35;
+
+ /*
+ * Admin packet otherwise checks out, but uses a bogus or expired session key
+ */
+ ADMIN_BAD_SESSION_KEY = 36;
+
+ /*
+ * Admin packet sent using PKC, but not from a public key on the admin key list
+ */
+ ADMIN_PUBLIC_KEY_UNAUTHORIZED = 37;
+
+ /*
+ * Airtime fairness rate limit exceeded for a packet
+ * This typically enforced per portnum and is used to prevent a single node from monopolizing airtime
+ */
+ RATE_LIMIT_EXCEEDED = 38;
+
+ /*
+ * PKI encryption failed, due to no public key for the remote node
+ * This is different from PKI_UNKNOWN_PUBKEY which indicates a failure upon receiving a packet
+ */
+ PKI_SEND_FAIL_PUBLIC_KEY = 39;
}
oneof variant {
@@ -733,6 +1180,202 @@ message Data {
* a message a heart or poop emoji.
*/
fixed32 emoji = 8;
+
+ /*
+ * Bitfield for extra flags. First use is to indicate that user approves the packet being uploaded to MQTT.
+ */
+ optional uint32 bitfield = 9;
+}
+
+/*
+ * The actual over-the-mesh message doing KeyVerification
+ */
+message KeyVerification {
+ /*
+ * random value Selected by the requesting node
+ */
+ uint64 nonce = 1;
+
+ /*
+ * The final authoritative hash, only to be sent by NodeA at the end of the handshake
+ */
+ bytes hash1 = 2;
+
+ /*
+ * The intermediary hash (actually derived from hash1),
+ * sent from NodeB to NodeA in response to the initial message.
+ */
+ bytes hash2 = 3;
+}
+
+/*
+ * The actual over-the-mesh message doing store and forward++
+ */
+message StoreForwardPlusPlus {
+ /*
+ * Enum of message types
+ */
+ enum SFPP_message_type {
+ /*
+ * Send an announcement of the canonical tip of a chain
+ */
+ CANON_ANNOUNCE = 0;
+
+ /*
+ * Query whether a specific link is on the chain
+ */
+ CHAIN_QUERY = 1;
+
+ /*
+ * Request the next link in the chain
+ */
+ LINK_REQUEST = 3;
+
+ /*
+ * Provide a link to add to the chain
+ */
+ LINK_PROVIDE = 4;
+
+ /*
+ * If we must fragment, send the first half
+ */
+ LINK_PROVIDE_FIRSTHALF = 5;
+
+ /*
+ * If we must fragment, send the second half
+ */
+ LINK_PROVIDE_SECONDHALF = 6;
+ }
+
+ /*
+ * Which message type is this
+ */
+ SFPP_message_type sfpp_message_type = 1;
+
+ /*
+ * The hash of the specific message
+ */
+ bytes message_hash = 2;
+
+ /*
+ * The hash of a link on a chain
+ */
+ bytes commit_hash = 3;
+
+ /*
+ * the root hash of a chain
+ */
+ bytes root_hash = 4;
+
+ /*
+ * The encrypted bytes from a message
+ */
+ bytes message = 5;
+
+ /*
+ * Message ID of the contained message
+ */
+ uint32 encapsulated_id = 6;
+
+ /*
+ * Destination of the contained message
+ */
+ uint32 encapsulated_to = 7;
+
+ /*
+ * Sender of the contained message
+ */
+ uint32 encapsulated_from = 8;
+
+ /*
+ * The receive time of the message in question
+ */
+ uint32 encapsulated_rxtime = 9;
+
+ /*
+ * Used in a LINK_REQUEST to specify the message X spots back from head
+ */
+ uint32 chain_count = 10;
+}
+
+/*
+ * The actual over-the-mesh message doing RemoteShell
+ */
+message RemoteShell {
+ /*
+ * Frame op code for PTY session control and stream transport.
+ *
+ * Values 1-63 are client->server requests.
+ * Values 64-127 are server->client responses/events.
+ */
+ enum OpCode {
+ OP_UNSET = 0;
+
+ // Client -> server
+ OPEN = 1;
+ INPUT = 2;
+ RESIZE = 3;
+ CLOSE = 4;
+ PING = 5;
+ ACK = 6;
+
+ // Server -> client
+ OPEN_OK = 64;
+ OUTPUT = 65;
+ CLOSED = 66;
+ ERROR = 67;
+ PONG = 68;
+ }
+
+ /*
+ * Structured frame operation.
+ */
+ OpCode op = 1;
+
+ /*
+ * Logical PTY session identifier.
+ */
+ uint32 session_id = 2;
+
+ /*
+ * Monotonic sequence number for this frame.
+ */
+ uint32 seq = 3;
+
+ /*
+ * Cumulative ack sequence number.
+ */
+ uint32 ack_seq = 4;
+
+ /*
+ * Opaque bytes payload for INPUT/OUTPUT/ERROR and other frame bodies.
+ */
+ bytes payload = 5;
+
+ /*
+ * Terminal size columns used for OPEN/RESIZE signaling.
+ */
+ uint32 cols = 6;
+
+ /*
+ * Terminal size rows used for OPEN/RESIZE signaling.
+ */
+ uint32 rows = 7;
+
+ /*
+ * Bit flags for protocol extensions.
+ */
+ uint32 flags = 8;
+
+ /*
+ * The last sequence number TX'd.
+ */
+ uint32 last_tx_seq = 9;
+
+ /*
+ * The last sequence number RX'd.
+ */
+ uint32 last_rx_seq = 10;
}
/*
@@ -747,12 +1390,12 @@ message Waypoint {
/*
* latitude_i
*/
- sfixed32 latitude_i = 2;
+ optional sfixed32 latitude_i = 2;
/*
* longitude_i
*/
- sfixed32 longitude_i = 3;
+ optional sfixed32 longitude_i = 3;
/*
* Time the waypoint is to expire (epoch)
@@ -781,10 +1424,17 @@ message Waypoint {
fixed32 icon = 8;
}
+/*
+ * Message for node status
+ */
+message StatusMessage {
+ string status = 1;
+}
+
/*
* This message will be proxied over the PhoneAPI for the client to deliver to the MQTT server
*/
- message MqttClientProxyMessage {
+message MqttClientProxyMessage {
/*
* The MQTT topic this message will be sent /received on
*/
@@ -865,6 +1515,22 @@ message MeshPacket {
*/
RELIABLE = 70;
+ /*
+ * If priority is unset but the packet is a response to a request, we want it to get there relatively quickly.
+ * Furthermore, responses stop relaying packets directed to a node early.
+ */
+ RESPONSE = 80;
+
+ /*
+ * Higher priority for specific message types (portnums) to distinguish between other reliable packets.
+ */
+ HIGH = 100;
+
+ /*
+ * Higher priority alert message used for critical alerts which take priority over other reliable packets.
+ */
+ ALERT = 110;
+
/*
* Ack/naks are sent with very high priority to ensure that retransmission
* stops as soon as possible
@@ -897,6 +1563,51 @@ message MeshPacket {
DELAYED_DIRECT = 2;
}
+ /*
+ * Enum to identify which transport mechanism this packet arrived over
+ */
+ enum TransportMechanism {
+ /*
+ * The default case is that the node generated a packet itself
+ */
+ TRANSPORT_INTERNAL = 0;
+
+ /*
+ * Arrived via the primary LoRa radio
+ */
+ TRANSPORT_LORA = 1;
+
+ /*
+ * Arrived via a secondary LoRa radio
+ */
+ TRANSPORT_LORA_ALT1 = 2;
+
+ /*
+ * Arrived via a tertiary LoRa radio
+ */
+ TRANSPORT_LORA_ALT2 = 3;
+
+ /*
+ * Arrived via a quaternary LoRa radio
+ */
+ TRANSPORT_LORA_ALT3 = 4;
+
+ /*
+ * Arrived via an MQTT connection
+ */
+ TRANSPORT_MQTT = 5;
+
+ /*
+ * Arrived via Multicast UDP
+ */
+ TRANSPORT_MULTICAST_UDP = 6;
+
+ /*
+ * Arrived via API connection
+ */
+ TRANSPORT_API = 7;
+ }
+
/*
* The sending node number.
* Note: Our crypto implementation uses this field as well.
@@ -906,6 +1617,10 @@ message MeshPacket {
/*
* The (immediate) destination for this packet
+ * If the value is 4,294,967,295 (maximum value of an unsigned 32bit integer), this indicates that the packet was
+ * not destined for a specific node, but for a channel as indicated by the value of `channel` below.
+ * If the value is another, this indicates that the packet was destined for a specific
+ * node (i.e. a kind of "Direct Message" to this node) and not broadcast on a channel.
*/
fixed32 to = 2;
@@ -969,7 +1684,7 @@ message MeshPacket {
float rx_snr = 8;
/*
- * If unset treated as zero (no forwarding, send to adjacent nodes only)
+ * If unset treated as zero (no forwarding, send to direct neighbor nodes only)
* if 1, allow hopping through one node, etc...
* For our usecase real world topologies probably have a max of about 3.
* This field is normally placed into a few of bits in the header.
@@ -1010,11 +1725,45 @@ message MeshPacket {
*/
bool via_mqtt = 14;
- /*
- * Hop limit with which the original packet started. Sent via LoRa using three bits in the unencrypted header.
+ /*
+ * Hop limit with which the original packet started. Sent via LoRa using three bits in the unencrypted header.
* When receiving a packet, the difference between hop_start and hop_limit gives how many hops it traveled.
- */
+ */
uint32 hop_start = 15;
+
+ /*
+ * Records the public key the packet was encrypted with, if applicable.
+ */
+ bytes public_key = 16;
+
+ /*
+ * Indicates whether the packet was en/decrypted using PKI
+ */
+ bool pki_encrypted = 17;
+
+ /*
+ * Last byte of the node number of the node that should be used as the next hop in routing.
+ * Set by the firmware internally, clients are not supposed to set this.
+ */
+ uint32 next_hop = 18;
+
+ /*
+ * Last byte of the node number of the node that will relay/relayed this packet.
+ * Set by the firmware internally, clients are not supposed to set this.
+ */
+ uint32 relay_node = 19;
+
+ /*
+ * *Never* sent over the radio links.
+ * Timestamp after which this packet may be sent.
+ * Set by the firmware internally, clients are not supposed to set this.
+ */
+ uint32 tx_after = 20;
+
+ /*
+ * Indicates which transport mechanism this packet arrived over
+ */
+ TransportMechanism transport_mechanism = 21;
}
/*
@@ -1032,7 +1781,7 @@ enum Constants {
* note: this payload length is ONLY the bytes that are sent inside of the Data protobuf (excluding protobuf overhead). The 16 byte header is
* outside of this envelope
*/
- DATA_PAYLOAD_LEN = 237;
+ DATA_PAYLOAD_LEN = 233;
}
/*
@@ -1099,7 +1848,7 @@ message NodeInfo {
/*
* TODO: REMOVE/INTEGRATE
* Not currently used (till full DSR deployment?) Our current preferred node node for routing - might be the same as num if
- * we are adjacent Or zero if we don't yet know a route to this node.
+ * we are direct neighbor or zero if we don't yet know a route to this node.
* fixed32 next_hop = 5;
*/
@@ -1123,15 +1872,34 @@ message NodeInfo {
bool via_mqtt = 8;
/*
- * Number of hops away from us this node is (0 if adjacent)
+ * Number of hops away from us this node is (0 if direct neighbor)
*/
- uint32 hops_away = 9;
-
+ optional uint32 hops_away = 9;
+
/*
* True if node is in our favorites list
* Persists between NodeDB internal clean ups
*/
bool is_favorite = 10;
+
+ /*
+ * True if node is in our ignored list
+ * Persists between NodeDB internal clean ups
+ */
+ bool is_ignored = 11;
+
+ /*
+ * True if node public key has been verified.
+ * Persists between NodeDB internal clean ups
+ * LSB 0 of the bitfield
+ */
+ bool is_key_manually_verified = 12;
+
+ /*
+ * True if node has been muted
+ * Persistes between NodeDB internal clean ups
+ */
+ bool is_muted = 13;
}
/*
@@ -1201,6 +1969,60 @@ enum CriticalErrorCode {
* If this occurs on your board, please post in the forum so that we can ask you to collect some information to allow fixing this bug
*/
RADIO_SPI_BUG = 11;
+
+ /*
+ * Corruption was detected on the flash filesystem but we were able to repair things.
+ * If you see this failure in the field please post in the forum because we are interested in seeing if this is occurring in the field.
+ */
+ FLASH_CORRUPTION_RECOVERABLE = 12;
+
+ /*
+ * Corruption was detected on the flash filesystem but we were unable to repair things.
+ * NOTE: Your node will probably need to be reconfigured the next time it reboots (it will lose the region code etc...)
+ * If you see this failure in the field please post in the forum because we are interested in seeing if this is occurring in the field.
+ */
+ FLASH_CORRUPTION_UNRECOVERABLE = 13;
+}
+
+/*
+ * Enum to indicate to clients whether this firmware is a special firmware build, like an event.
+ * The first 16 values are reserved for non-event special firmwares, like the Smart Citizen use case.
+ */
+enum FirmwareEdition {
+ /*
+ * Vanilla firmware
+ */
+ VANILLA = 0;
+
+ /*
+ * Firmware for use in the Smart Citizen environmental monitoring network
+ */
+ SMART_CITIZEN = 1;
+
+ /*
+ * Open Sauce, the maker conference held yearly in CA
+ */
+ OPEN_SAUCE = 16;
+
+ /*
+ * DEFCON, the yearly hacker conference
+ */
+ DEFCON = 17;
+
+ /*
+ * Burning Man, the yearly hippie gathering in the desert
+ */
+ BURNING_MAN = 18;
+
+ /*
+ * Hamvention, the Dayton amateur radio convention
+ */
+ HAMVENTION = 19;
+
+ /*
+ * Placeholder for DIY and unofficial events
+ */
+ DIY_EDITION = 127;
}
/*
@@ -1226,6 +2048,27 @@ message MyNodeInfo {
* Phone/PC apps should compare this to their build number and if too low tell the user they must update their app
*/
uint32 min_app_version = 11;
+
+ /*
+ * Unique hardware identifier for this device
+ */
+ bytes device_id = 12;
+
+ /*
+ * The PlatformIO environment used to build this firmware
+ */
+ string pio_env = 13;
+
+ /*
+ * The indicator for whether this device is running event firmware and which
+ */
+ FirmwareEdition firmware_edition = 14;
+
+ /*
+ * The number of nodes in the nodedb.
+ * This is used by the phone to know how many NodeInfo packets to expect on want_config
+ */
+ uint32 nodedb_count = 15;
}
/*
@@ -1400,9 +2243,92 @@ message FromRadio {
* MQTT Client Proxy Message (device sending to client / phone for publishing to MQTT)
*/
MqttClientProxyMessage mqttClientProxyMessage = 14;
+
+ /*
+ * File system manifest messages
+ */
+ FileInfo fileInfo = 15;
+
+ /*
+ * Notification message to the client
+ */
+ ClientNotification clientNotification = 16;
+
+ /*
+ * Persistent data for device-ui
+ */
+ DeviceUIConfig deviceuiConfig = 17;
}
}
+/*
+ * A notification message from the device to the client
+ * To be used for important messages that should to be displayed to the user
+ * in the form of push notifications or validation messages when saving
+ * invalid configuration.
+ */
+message ClientNotification {
+ /*
+ * The id of the packet we're notifying in response to
+ */
+ optional uint32 reply_id = 1;
+
+ /*
+ * Seconds since 1970 - or 0 for unknown/unset
+ */
+ fixed32 time = 2;
+
+ /*
+ * The level type of notification
+ */
+ LogRecord.Level level = 3;
+ /*
+ * The message body of the notification
+ */
+ string message = 4;
+
+ oneof payload_variant {
+ KeyVerificationNumberInform key_verification_number_inform = 11;
+ KeyVerificationNumberRequest key_verification_number_request = 12;
+ KeyVerificationFinal key_verification_final = 13;
+ DuplicatedPublicKey duplicated_public_key = 14;
+ LowEntropyKey low_entropy_key = 15;
+ }
+}
+
+message KeyVerificationNumberInform {
+ uint64 nonce = 1;
+ string remote_longname = 2;
+ uint32 security_number = 3;
+}
+message KeyVerificationNumberRequest {
+ uint64 nonce = 1;
+ string remote_longname = 2;
+}
+message KeyVerificationFinal {
+ uint64 nonce = 1;
+ string remote_longname = 2;
+ bool isSender = 3;
+ string verification_characters = 4;
+}
+message DuplicatedPublicKey {}
+message LowEntropyKey {}
+
+/*
+ * Individual File info for the device
+ */
+message FileInfo {
+ /*
+ * The fully qualified path of the file
+ */
+ string file_name = 1;
+
+ /*
+ * The size of the file in bytes
+ */
+ uint32 size_bytes = 2;
+}
+
/*
* Packets/commands to the radio will be written (reliably) to the toRadio characteristic.
* Once the write completes the phone can assume it is handled.
@@ -1507,9 +2433,9 @@ message Neighbor {
float snr = 2;
/*
- * Reception time (in secs since 1970) of last message that was last sent by this ID.
- * Note: this is for local storage only and will not be sent out over the mesh.
- */
+ * Reception time (in secs since 1970) of last message that was last sent by this ID.
+ * Note: this is for local storage only and will not be sent out over the mesh.
+ */
fixed32 last_rx_time = 3;
/*
@@ -1572,12 +2498,183 @@ message DeviceMetadata {
* Has Remote Hardware enabled
*/
bool hasRemoteHardware = 10;
+
+ /*
+ * Has PKC capabilities
+ */
+ bool hasPKC = 11;
+
+ /*
+ * Bit field of boolean for excluded modules
+ * (bitwise OR of ExcludedModules)
+ */
+ uint32 excluded_modules = 12;
}
-/*
+/*
+ * Enum for modules excluded from a device's configuration.
+ * Each value represents a ModuleConfigType that can be toggled as excluded
+ * by setting its corresponding bit in the `excluded_modules` bitmask field.
+ */
+enum ExcludedModules {
+ /*
+ * Default value of 0 indicates no modules are excluded.
+ */
+ EXCLUDED_NONE = 0x0000;
+
+ /*
+ * MQTT module
+ */
+ MQTT_CONFIG = 0x0001;
+
+ /*
+ * Serial module
+ */
+ SERIAL_CONFIG = 0x0002;
+
+ /*
+ * External Notification module
+ */
+ EXTNOTIF_CONFIG = 0x0004;
+
+ /*
+ * Store and Forward module
+ */
+ STOREFORWARD_CONFIG = 0x0008;
+
+ /*
+ * Range Test module
+ */
+ RANGETEST_CONFIG = 0x0010;
+
+ /*
+ * Telemetry module
+ */
+ TELEMETRY_CONFIG = 0x0020;
+
+ /*
+ * Canned Message module
+ */
+ CANNEDMSG_CONFIG = 0x0040;
+
+ /*
+ * Audio module
+ */
+ AUDIO_CONFIG = 0x0080;
+
+ /*
+ * Remote Hardware module
+ */
+ REMOTEHARDWARE_CONFIG = 0x0100;
+
+ /*
+ * Neighbor Info module
+ */
+ NEIGHBORINFO_CONFIG = 0x0200;
+
+ /*
+ * Ambient Lighting module
+ */
+ AMBIENTLIGHTING_CONFIG = 0x0400;
+
+ /*
+ * Detection Sensor module
+ */
+ DETECTIONSENSOR_CONFIG = 0x0800;
+
+ /*
+ * Paxcounter module
+ */
+ PAXCOUNTER_CONFIG = 0x1000;
+
+ /*
+ * Bluetooth config (not technically a module, but used to indicate bluetooth capabilities)
+ */
+ BLUETOOTH_CONFIG = 0x2000;
+
+ /*
+ * Network config (not technically a module, but used to indicate network capabilities)
+ */
+ NETWORK_CONFIG = 0x4000;
+}
+
+/*
* A heartbeat message is sent to the node from the client to keep the connection alive.
* This is currently only needed to keep serial connections alive, but can be used by any PhoneAPI.
*/
message Heartbeat {
-
+ /*
+ * The nonce of the heartbeat message
+ */
+ uint32 nonce = 1;
+}
+
+/*
+ * RemoteHardwarePins associated with a node
+ */
+message NodeRemoteHardwarePin {
+ /*
+ * The node_num exposing the available gpio pin
+ */
+ uint32 node_num = 1;
+
+ /*
+ * The the available gpio pin for usage with RemoteHardware module
+ */
+ RemoteHardwarePin pin = 2;
+}
+
+message ChunkedPayload {
+ /*
+ * The ID of the entire payload
+ */
+ uint32 payload_id = 1;
+
+ /*
+ * The total number of chunks in the payload
+ */
+ uint32 chunk_count = 2;
+
+ /*
+ * The current chunk index in the total
+ */
+ uint32 chunk_index = 3;
+
+ /*
+ * The binary data of the current chunk
+ */
+ bytes payload_chunk = 4;
+}
+
+/*
+ * Wrapper message for broken repeated oneof support
+ */
+message resend_chunks {
+ repeated uint32 chunks = 1;
+}
+
+/*
+ * Responses to a ChunkedPayload request
+ */
+message ChunkedPayloadResponse {
+ /*
+ * The ID of the entire payload
+ */
+ uint32 payload_id = 1;
+
+ oneof payload_variant {
+ /*
+ * Request to transfer chunked payload
+ */
+ bool request_transfer = 2;
+
+ /*
+ * Accept the transfer chunked payload
+ */
+ bool accept_transfer = 3;
+ /*
+ * Request missing indexes in the chunked payload
+ */
+ resend_chunks resend_chunks = 4;
+ }
}
diff --git a/meshtastic/module_config.options b/meshtastic/module_config.options
index 68aba7c..c6158be 100644
--- a/meshtastic/module_config.options
+++ b/meshtastic/module_config.options
@@ -2,7 +2,7 @@
*MQTTConfig.address max_size:64
*MQTTConfig.username max_size:64
-*MQTTConfig.password max_size:64
+*MQTTConfig.password max_size:32
*MQTTConfig.root max_size:32
*AudioConfig.ptt_pin int_size:8
@@ -26,3 +26,6 @@
*DetectionSensorConfig.monitor_pin int_size:8
*DetectionSensorConfig.name max_size:20
+*DetectionSensorConfig.detection_trigger_type max_size:8
+
+*StatusMessageConfig.node_status max_size:80
diff --git a/meshtastic/module_config.proto b/meshtastic/module_config.proto
index f2c2805..10753c6 100644
--- a/meshtastic/module_config.proto
+++ b/meshtastic/module_config.proto
@@ -2,10 +2,12 @@ syntax = "proto3";
package meshtastic;
+import "meshtastic/atak.proto";
+
option csharp_namespace = "Meshtastic.Protobufs";
option go_package = "github.com/meshtastic/go/generated";
option java_outer_classname = "ModuleConfigProtos";
-option java_package = "com.geeksville.mesh";
+option java_package = "org.meshtastic.proto";
option swift_prefix = "";
/*
@@ -95,6 +97,11 @@ message ModuleConfig {
* Bits of precision for the location sent (default of 32 is full precision).
*/
uint32 position_precision = 2;
+
+ /*
+ * Whether we have opted-in to report our location to the map
+ */
+ bool should_report_location = 3;
}
/*
@@ -125,34 +132,59 @@ message ModuleConfig {
* Whether the Module is enabled
*/
bool enabled = 1;
-
+
/*
* Interval in seconds of how often we should try to send our
- * Neighbor Info to the mesh
+ * Neighbor Info (minimum is 14400, i.e., 4 hours)
*/
uint32 update_interval = 2;
+
+ /*
+ * Whether in addition to sending it to MQTT and the PhoneAPI, our NeighborInfo should be transmitted over LoRa.
+ * Note that this is not available on a channel with default key and name.
+ */
+ bool transmit_over_lora = 3;
}
/*
* Detection Sensor Module Config
*/
- message DetectionSensorConfig {
+ message DetectionSensorConfig {
+ enum TriggerType {
+ // Event is triggered if pin is low
+ LOGIC_LOW = 0;
+ // Event is triggered if pin is high
+ LOGIC_HIGH = 1;
+ // Event is triggered when pin goes high to low
+ FALLING_EDGE = 2;
+ // Event is triggered when pin goes low to high
+ RISING_EDGE = 3;
+ // Event is triggered on every pin state change, low is considered to be
+ // "active"
+ EITHER_EDGE_ACTIVE_LOW = 4;
+ // Event is triggered on every pin state change, high is considered to be
+ // "active"
+ EITHER_EDGE_ACTIVE_HIGH = 5;
+ }
/*
* Whether the Module is enabled
*/
bool enabled = 1;
/*
- * Interval in seconds of how often we can send a message to the mesh when a state change is detected
+ * Interval in seconds of how often we can send a message to the mesh when a
+ * trigger event is detected
*/
uint32 minimum_broadcast_secs = 2;
/*
- * Interval in seconds of how often we should send a message to the mesh with the current state regardless of changes
- * When set to 0, only state changes will be broadcasted
- * Works as a sort of status heartbeat for peace of mind
+ * Interval in seconds of how often we should send a message to the mesh
+ * with the current state regardless of trigger events When set to 0, only
+ * trigger events will be broadcasted Works as a sort of status heartbeat
+ * for peace of mind
*/
uint32 state_broadcast_secs = 3;
+
/*
* Send ASCII bell with alert message
* Useful for triggering ext. notification on bell
@@ -172,10 +204,9 @@ message ModuleConfig {
uint32 monitor_pin = 6;
/*
- * Whether or not the GPIO pin state detection is triggered on HIGH (1)
- * Otherwise LOW (0)
+ * The type of trigger event to be used
*/
- bool detection_triggered_high = 7;
+ TriggerType detection_trigger_type = 7;
/*
* Whether or not use INPUT_PULLUP mode for GPIO pin
@@ -254,6 +285,92 @@ message ModuleConfig {
*/
uint32 paxcounter_update_interval = 2;
+
+ /*
+ * WiFi RSSI threshold. Defaults to -80
+ */
+ int32 wifi_threshold = 3;
+
+ /*
+ * BLE RSSI threshold. Defaults to -80
+ */
+ int32 ble_threshold = 4;
+ }
+
+ /*
+ * Config for the Traffic Management module.
+ * Provides packet inspection and traffic shaping to help reduce channel utilization
+ */
+ message TrafficManagementConfig {
+ /*
+ * Master enable for traffic management module
+ */
+ bool enabled = 1;
+
+ /*
+ * Enable position deduplication to drop redundant position broadcasts
+ */
+ bool position_dedup_enabled = 2;
+
+ /*
+ * Number of bits of precision for position deduplication (0-32)
+ */
+ uint32 position_precision_bits = 3;
+
+ /*
+ * Minimum interval in seconds between position updates from the same node
+ */
+ uint32 position_min_interval_secs = 4;
+
+ /*
+ * Enable direct response to NodeInfo requests from local cache
+ */
+ bool nodeinfo_direct_response = 5;
+
+ /*
+ * Minimum hop distance from requestor before responding to NodeInfo requests
+ */
+ uint32 nodeinfo_direct_response_max_hops = 6;
+
+ /*
+ * Enable per-node rate limiting to throttle chatty nodes
+ */
+ bool rate_limit_enabled = 7;
+
+ /*
+ * Time window in seconds for rate limiting calculations
+ */
+ uint32 rate_limit_window_secs = 8;
+
+ /*
+ * Maximum packets allowed per node within the rate limit window
+ */
+ uint32 rate_limit_max_packets = 9;
+
+ /*
+ * Enable dropping of unknown/undecryptable packets per rate_limit_window_secs
+ */
+ bool drop_unknown_enabled = 10;
+
+ /*
+ * Number of unknown packets before dropping from a node
+ */
+ uint32 unknown_packet_threshold = 11;
+
+ /*
+ * Set hop_limit to 0 for relayed telemetry broadcasts (own packets unaffected)
+ */
+ bool exhaust_hop_telemetry = 12;
+
+ /*
+ * Set hop_limit to 0 for relayed position broadcasts (own packets unaffected)
+ */
+ bool exhaust_hop_position = 13;
+
+ /*
+ * Preserve hop_limit for router-to-router traffic
+ */
+ bool router_preserve_hops = 14;
}
/*
@@ -293,6 +410,17 @@ message ModuleConfig {
NMEA = 4;
// NMEA messages specifically tailored for CalTopo
CALTOPO = 5;
+ // Ecowitt WS85 weather station
+ WS85 = 6;
+ // VE.Direct is a serial protocol used by Victron Energy products
+ // https://beta.ivc.no/wiki/index.php/Victron_VE_Direct_DIY_Cable
+ VE_DIRECT = 7;
+ // Used to configure and view some parameters of MeshSolar.
+ // https://heltec.org/project/meshsolar/
+ MS_CONFIG = 8;
+ // Logs mesh traffic to the serial pins, ideal for logging via openLog or similar.
+ LOG = 9; // includes other packets
+ LOGTEXT = 10; // only text (channel & DM)
}
/*
@@ -457,6 +585,11 @@ message ModuleConfig {
* TODO: REPLACE
*/
uint32 history_return_window = 5;
+
+ /*
+ * Set to true to let this node act as a server that stores received messages and resends them upon request.
+ */
+ bool is_server = 6;
}
/*
@@ -478,6 +611,12 @@ message ModuleConfig {
* ESP32 Only
*/
bool save = 3;
+
+ /*
+ * Bool indicating that the node should cleanup / destroy it's RangeTest.csv file.
+ * ESP32 Only
+ */
+ bool clear_on_reboot = 4;
}
/*
@@ -526,35 +665,52 @@ message ModuleConfig {
uint32 air_quality_interval = 7;
/*
- * Interval in seconds of how often we should try to send our
- * air quality metrics to the mesh
+ * Enable/disable Power metrics
*/
bool power_measurement_enabled = 8;
/*
* Interval in seconds of how often we should try to send our
- * air quality metrics to the mesh
+ * power metrics to the mesh
*/
uint32 power_update_interval = 9;
/*
- * Interval in seconds of how often we should try to send our
- * air quality metrics to the mesh
+ * Enable/Disable the power measurement module on-device display
*/
bool power_screen_enabled = 10;
+ /*
+ * Preferences for the (Health) Telemetry Module
+ * Enable/Disable the telemetry measurement module measurement collection
+ */
+ bool health_measurement_enabled = 11;
+ /*
+ * Interval in seconds of how often we should try to send our
+ * health metrics to the mesh
+ */
+ uint32 health_update_interval = 12;
+ /*
+ * Enable/Disable the health telemetry module on-device display
+ */
+ bool health_screen_enabled = 13;
+ /*
+ * Enable/Disable the device telemetry module to send metrics to the mesh
+ * Note: We will still send telemtry to the connected phone / client every minute over the API
+ */
+ bool device_telemetry_enabled = 14;
-
-
-
-
+ /*
+ * Enable/Disable the air quality telemetry measurement module on-device display
+ */
+ bool air_quality_screen_enabled = 15;
}
/*
- * TODO: REPLACE
+ * Canned Messages Module Config
*/
message CannedMessageConfig {
/*
@@ -645,13 +801,13 @@ message ModuleConfig {
/*
* Enable/disable CannedMessageModule.
*/
- bool enabled = 9;
+ bool enabled = 9 [deprecated = true];
/*
* Input event origin accepted by the canned message module.
- * Can be e.g. "rotEnc1", "upDownEnc1" or keyword "_any"
+ * Can be e.g. "rotEnc1", "upDownEnc1", "scanAndSelect", "cardkb", "serialkb", or keyword "_any"
*/
- string allow_input_source = 10;
+ string allow_input_source = 10 [deprecated = true];
/*
* CannedMessageModule also sends a bell character with the messages.
@@ -661,11 +817,10 @@ message ModuleConfig {
}
/*
- Ambient Lighting Module - Settings for control of onboard LEDs to allow users to adjust the brightness levels and respective color levels.
- Initially created for the RAK14001 RGB LED module.
+ Ambient Lighting Module - Settings for control of onboard LEDs to allow users to adjust the brightness levels and respective color levels.
+ Initially created for the RAK14001 RGB LED module.
*/
message AmbientLightingConfig {
-
/*
* Sets LED to on or off.
*/
@@ -692,6 +847,16 @@ message ModuleConfig {
uint32 blue = 5;
}
+ /*
+ * StatusMessage config - Allows setting a status message for a node to periodically rebroadcast
+ */
+ message StatusMessageConfig {
+ /*
+ * The actual status string
+ */
+ string node_status = 1;
+ }
+
/*
* TODO: REPLACE
*/
@@ -760,6 +925,37 @@ message ModuleConfig {
* TODO: REPLACE
*/
PaxcounterConfig paxcounter = 13;
+
+ /*
+ * TODO: REPLACE
+ */
+ StatusMessageConfig statusmessage = 14;
+
+ /*
+ * Traffic management module config for mesh network optimization
+ */
+ TrafficManagementConfig traffic_management = 15;
+
+ /*
+ * TAK team/role configuration for TAK_TRACKER
+ */
+ TAKConfig tak = 16;
+ }
+
+ /*
+ * TAK team/role configuration
+ */
+ message TAKConfig {
+ /*
+ * Team color.
+ * Default Unspecifed_Color -> firmware uses Cyan
+ */
+ Team team = 1;
+ /*
+ * Member role.
+ * Default Unspecifed -> firmware uses TeamMember
+ */
+ MemberRole role = 2;
}
}
@@ -798,4 +994,4 @@ enum RemoteHardwarePinType {
* GPIO pin can be written to (high / low)
*/
DIGITAL_WRITE = 2;
-}
\ No newline at end of file
+}
diff --git a/meshtastic/mqtt.proto b/meshtastic/mqtt.proto
index 17ebf0e..616780d 100644
--- a/meshtastic/mqtt.proto
+++ b/meshtastic/mqtt.proto
@@ -2,13 +2,13 @@ syntax = "proto3";
package meshtastic;
-import "meshtastic/mesh.proto";
import "meshtastic/config.proto";
+import "meshtastic/mesh.proto";
option csharp_namespace = "Meshtastic.Protobufs";
option go_package = "github.com/meshtastic/go/generated";
option java_outer_classname = "MQTTProtos";
-option java_package = "com.geeksville.mesh";
+option java_package = "org.meshtastic.proto";
option swift_prefix = "";
/*
@@ -49,8 +49,8 @@ message MapReport {
string short_name = 2;
/*
- * Role of the node that applies specific settings for a particular use-case
- */
+ * Role of the node that applies specific settings for a particular use-case
+ */
Config.DeviceConfig.Role role = 3;
/*
@@ -64,19 +64,19 @@ message MapReport {
string firmware_version = 5;
/*
- * The region code for the radio (US, CN, EU433, etc...)
- */
+ * The region code for the radio (US, CN, EU433, etc...)
+ */
Config.LoRaConfig.RegionCode region = 6;
/*
- * Modem preset used by the radio (LongFast, MediumSlow, etc...)
- */
+ * Modem preset used by the radio (LongFast, MediumSlow, etc...)
+ */
Config.LoRaConfig.ModemPreset modem_preset = 7;
/*
- * Whether the node has a channel with default PSK and name (LongFast, MediumSlow, etc...)
- * and it uses the default frequency slot given the region and modem preset.
- */
+ * Whether the node has a channel with default PSK and name (LongFast, MediumSlow, etc...)
+ * and it uses the default frequency slot given the region and modem preset.
+ */
bool has_default_channel = 8;
/*
@@ -103,4 +103,10 @@ message MapReport {
* Number of online nodes (heard in the last 2 hours) this node has in its list that were received locally (not via MQTT)
*/
uint32 num_online_local_nodes = 13;
-}
\ No newline at end of file
+
+ /*
+ * User has opted in to share their location (map report) with the mqtt server
+ * Controlled by map_report.should_report_location
+ */
+ bool has_opted_report_location = 14;
+}
diff --git a/meshtastic/paxcount.proto b/meshtastic/paxcount.proto
index 47b2639..5084f9d 100644
--- a/meshtastic/paxcount.proto
+++ b/meshtastic/paxcount.proto
@@ -5,7 +5,7 @@ package meshtastic;
option csharp_namespace = "Meshtastic.Protobufs";
option go_package = "github.com/meshtastic/go/generated";
option java_outer_classname = "PaxcountProtos";
-option java_package = "com.geeksville.mesh";
+option java_package = "org.meshtastic.proto";
option swift_prefix = "";
/*
diff --git a/meshtastic/portnums.proto b/meshtastic/portnums.proto
index b02651a..61412cf 100644
--- a/meshtastic/portnums.proto
+++ b/meshtastic/portnums.proto
@@ -5,7 +5,7 @@ package meshtastic;
option csharp_namespace = "Meshtastic.Protobufs";
option go_package = "github.com/meshtastic/go/generated";
option java_outer_classname = "Portnums";
-option java_package = "com.geeksville.mesh";
+option java_package = "org.meshtastic.proto";
option swift_prefix = "";
/*
@@ -105,6 +105,21 @@ enum PortNum {
*/
DETECTION_SENSOR_APP = 10;
+ /*
+ * Same as Text Message but used for critical alerts.
+ */
+ ALERT_APP = 11;
+
+ /*
+ * Module/port for handling key verification requests.
+ */
+ KEY_VERIFICATION_APP = 12;
+
+ /*
+ * Module/port for handling primitive remote shell access.
+ */
+ REMOTE_SHELL_APP = 13;
+
/*
* Provides a 'ping' service that replies to any packet it receives.
* Also serves as a small example module.
@@ -124,6 +139,22 @@ enum PortNum {
*/
PAXCOUNTER_APP = 34;
+ /*
+ * Store and Forward++ module included in the firmware
+ * ENCODING: protobuf
+ * This module is specifically for Native Linux nodes, and provides a Git-style
+ * chain of messages.
+ */
+ STORE_FORWARD_PLUSPLUS_APP = 35;
+
+ /*
+ * Node Status module
+ * ENCODING: protobuf
+ * This module allows setting an extra string of status for a node.
+ * Broadcasts on change and on a timer, possibly once a day.
+ */
+ NODE_STATUS_APP = 36;
+
/*
* Provides a hardware serial interface to send and receive from the Meshtastic network.
* Connect to the RX/TX pins of a device with 38400 8N1. Packets received from the Meshtastic
@@ -174,7 +205,7 @@ enum PortNum {
/*
* Provides a traceroute functionality to show the route a packet towards
- * a certain destination would take on the mesh.
+ * a certain destination would take on the mesh. Contains a RouteDiscovery message as payload.
* ENCODING: Protobuf
*/
TRACEROUTE_APP = 70;
@@ -184,7 +215,7 @@ enum PortNum {
* ENCODING: Protobuf
*/
NEIGHBORINFO_APP = 71;
-
+
/*
* ATAK Plugin
* Portnum for payloads from the official Meshtastic ATAK plugin
@@ -196,6 +227,44 @@ enum PortNum {
*/
MAP_REPORT_APP = 73;
+ /*
+ * PowerStress based monitoring support (for automated power consumption testing)
+ */
+ POWERSTRESS_APP = 74;
+
+ /*
+ * LoraWAN Payload Transport
+ * ENCODING: compact binary LoRaWAN uplink (10-byte RF metadata + PHY payload) - see LoRaWANBridgeModule
+ */
+ LORAWAN_BRIDGE = 75;
+
+ /*
+ * Reticulum Network Stack Tunnel App
+ * ENCODING: Fragmented RNS Packet. Handled by Meshtastic RNS interface
+ */
+ RETICULUM_TUNNEL_APP = 76;
+
+ /*
+ * App for transporting Cayenne Low Power Payload, popular for LoRaWAN sensor nodes. Offers ability to send
+ * arbitrary telemetry over meshtastic that is not covered by telemetry.proto
+ * ENCODING: CayenneLLP
+ */
+ CAYENNE_APP = 77;
+
+ /*
+ * ATAK Plugin V2
+ * Portnum for payloads from the official Meshtastic ATAK plugin using
+ * TAKPacketV2 with zstd dictionary compression.
+ */
+ ATAK_PLUGIN_V2 = 78;
+
+ /*
+ * GroupAlarm integration
+ * Used for transporting GroupAlarm-related messages between Meshtastic nodes
+ * and companion applications/services.
+ */
+ GROUPALARM_APP = 112;
+
/*
* Private applications should use portnums >= 256.
* To simplify initial development and testing you can use "PRIVATE_APP"
@@ -213,4 +282,4 @@ enum PortNum {
* Currently we limit port nums to no higher than this value
*/
MAX = 511;
-}
\ No newline at end of file
+}
diff --git a/meshtastic/powermon.proto b/meshtastic/powermon.proto
new file mode 100644
index 0000000..5973b16
--- /dev/null
+++ b/meshtastic/powermon.proto
@@ -0,0 +1,103 @@
+syntax = "proto3";
+
+package meshtastic;
+
+option csharp_namespace = "Meshtastic.Protobufs";
+option go_package = "github.com/meshtastic/go/generated";
+option java_outer_classname = "PowerMonProtos";
+option java_package = "org.meshtastic.proto";
+option swift_prefix = "";
+
+/* Note: There are no 'PowerMon' messages normally in use (PowerMons are sent only as structured logs - slogs).
+ * But we wrap our State enum in this message to effectively nest a namespace (without our linter yelling at us)
+ */
+message PowerMon {
+ /* Any significant power changing event in meshtastic should be tagged with a powermon state transition.
+ * If you are making new meshtastic features feel free to add new entries at the end of this definition.
+ */
+ enum State {
+ None = 0;
+
+ CPU_DeepSleep = 0x01;
+ CPU_LightSleep = 0x02;
+
+ /*
+ The external Vext1 power is on. Many boards have auxillary power rails that the CPU turns on only
+ occasionally. In cases where that rail has multiple devices on it we usually want to have logging on
+ the state of that rail as an independent record.
+ For instance on the Heltec Tracker 1.1 board, this rail is the power source for the GPS and screen.
+
+ The log messages will be short and complete (see PowerMon.Event in the protobufs for details).
+ something like "S:PM:C,0x00001234,REASON" where the hex number is the bitmask of all current states.
+ (We use a bitmask for states so that if a log message gets lost it won't be fatal)
+ */
+ Vext1_On = 0x04;
+
+ Lora_RXOn = 0x08;
+ Lora_TXOn = 0x10;
+ Lora_RXActive = 0x20;
+ BT_On = 0x40;
+ LED_On = 0x80;
+
+ Screen_On = 0x100;
+ Screen_Drawing = 0x200;
+ Wifi_On = 0x400;
+
+ /*
+ * GPS is actively trying to find our location
+ * See GPSPowerState for more details
+ */
+ GPS_Active = 0x800;
+ }
+}
+
+/*
+ * PowerStress testing support via the C++ PowerStress module
+ */
+message PowerStressMessage {
+ /*
+ * What operation would we like the UUT to perform.
+ * note: senders should probably set want_response in their request packets, so that they can know when the state
+ * machine has started processing their request
+ */
+ enum Opcode {
+ /*
+ * Unset/unused
+ */
+ UNSET = 0;
+
+ PRINT_INFO = 1; // Print board version slog and send an ack that we are alive and ready to process commands
+ FORCE_QUIET = 2; // Try to turn off all automatic processing of packets, screen, sleeping, etc (to make it easier to measure in isolation)
+ END_QUIET = 3; // Stop powerstress processing - probably by just rebooting the board
+
+ SCREEN_ON = 16; // Turn the screen on
+ SCREEN_OFF = 17; // Turn the screen off
+
+ CPU_IDLE = 32; // Let the CPU run but we assume mostly idling for num_seconds
+ CPU_DEEPSLEEP = 33; // Force deep sleep for FIXME seconds
+ CPU_FULLON = 34; // Spin the CPU as fast as possible for num_seconds
+
+ LED_ON = 48; // Turn the LED on for num_seconds (and leave it on - for baseline power measurement purposes)
+ LED_OFF = 49; // Force the LED off for num_seconds
+
+ LORA_OFF = 64; // Completely turn off the LORA radio for num_seconds
+ LORA_TX = 65; // Send Lora packets for num_seconds
+ LORA_RX = 66; // Receive Lora packets for num_seconds (node will be mostly just listening, unless an external agent is helping stress this by sending packets on the current channel)
+
+ BT_OFF = 80; // Turn off the BT radio for num_seconds
+ BT_ON = 81; // Turn on the BT radio for num_seconds
+
+ WIFI_OFF = 96; // Turn off the WIFI radio for num_seconds
+ WIFI_ON = 97; // Turn on the WIFI radio for num_seconds
+
+ GPS_OFF = 112; // Turn off the GPS radio for num_seconds
+ GPS_ON = 113; // Turn on the GPS radio for num_seconds
+ }
+
+ /*
+ * What type of HardwareMessage is this?
+ */
+ Opcode cmd = 1;
+
+ float num_seconds = 2;
+}
diff --git a/meshtastic/remote_hardware.proto b/meshtastic/remote_hardware.proto
index ba4a693..d919203 100644
--- a/meshtastic/remote_hardware.proto
+++ b/meshtastic/remote_hardware.proto
@@ -5,7 +5,7 @@ package meshtastic;
option csharp_namespace = "Meshtastic.Protobufs";
option go_package = "github.com/meshtastic/go/generated";
option java_outer_classname = "RemoteHardware";
-option java_package = "com.geeksville.mesh";
+option java_package = "org.meshtastic.proto";
option swift_prefix = "";
/*
diff --git a/meshtastic/rtttl.options b/meshtastic/rtttl.options
index 1ae0c2f..171e426 100644
--- a/meshtastic/rtttl.options
+++ b/meshtastic/rtttl.options
@@ -1 +1 @@
-*RTTTLConfig.ringtone max_size:230
+*RTTTLConfig.ringtone max_size:231
diff --git a/meshtastic/rtttl.proto b/meshtastic/rtttl.proto
index 11c8b92..06d94fc 100644
--- a/meshtastic/rtttl.proto
+++ b/meshtastic/rtttl.proto
@@ -5,7 +5,7 @@ package meshtastic;
option csharp_namespace = "Meshtastic.Protobufs";
option go_package = "github.com/meshtastic/go/generated";
option java_outer_classname = "RTTTLConfigProtos";
-option java_package = "com.geeksville.mesh";
+option java_package = "org.meshtastic.proto";
option swift_prefix = "";
/*
diff --git a/meshtastic/storeforward.options b/meshtastic/storeforward.options
index 8580aab..57a122c 100644
--- a/meshtastic/storeforward.options
+++ b/meshtastic/storeforward.options
@@ -1 +1 @@
-*StoreAndForward.text max_size:237
\ No newline at end of file
+*StoreAndForward.text max_size:233
\ No newline at end of file
diff --git a/meshtastic/storeforward.proto b/meshtastic/storeforward.proto
index ef7de2c..a4a18b2 100644
--- a/meshtastic/storeforward.proto
+++ b/meshtastic/storeforward.proto
@@ -5,7 +5,7 @@ package meshtastic;
option csharp_namespace = "Meshtastic.Protobufs";
option go_package = "github.com/meshtastic/go/generated";
option java_outer_classname = "StoreAndForwardProtos";
-option java_package = "com.geeksville.mesh";
+option java_package = "org.meshtastic.proto";
option swift_prefix = "";
/*
@@ -215,4 +215,4 @@ message StoreAndForward {
*/
bytes text = 5;
}
-}
\ No newline at end of file
+}
diff --git a/meshtastic/telemetry.options b/meshtastic/telemetry.options
index 6c80df9..5db1af5 100644
--- a/meshtastic/telemetry.options
+++ b/meshtastic/telemetry.options
@@ -1,4 +1,19 @@
# options for nanopb
# https://jpa.kapsi.fi/nanopb/docs/reference.html#proto-file-options
+*EnvironmentMetrics.iaq int_size:16
+*EnvironmentMetrics.wind_direction int_size:16
+*EnvironmentMetrics.soil_moisture int_size:8
+*EnvironmentMetrics.one_wire_temperature max_count:8
+*LocalStats.num_online_nodes int_size:16
+*LocalStats.num_total_nodes int_size:16
+*LocalStats.num_tx_dropped int_size:16
+
+*HealthMetrics.heart_bpm int_size:8
+*HealthMetrics.spO2 int_size:8
+
+*HostMetrics.load1 int_size:16
+*HostMetrics.load5 int_size:16
+*HostMetrics.load15 int_size:16
+*HostMetrics.user_string max_size:200
diff --git a/meshtastic/telemetry.proto b/meshtastic/telemetry.proto
index 282b32c..f541ca9 100644
--- a/meshtastic/telemetry.proto
+++ b/meshtastic/telemetry.proto
@@ -1,287 +1,934 @@
-syntax = "proto3";
-
-package meshtastic;
-
-option csharp_namespace = "Meshtastic.Protobufs";
-option go_package = "github.com/meshtastic/go/generated";
-option java_outer_classname = "TelemetryProtos";
-option java_package = "com.geeksville.mesh";
-option swift_prefix = "";
-
-/*
- * Key native device metrics such as battery level
- */
-message DeviceMetrics {
- /*
- * 0-100 (>100 means powered)
- */
- uint32 battery_level = 1;
-
- /*
- * Voltage measured
- */
- float voltage = 2;
-
- /*
- * Utilization for the current channel, including well formed TX, RX and malformed RX (aka noise).
- */
- float channel_utilization = 3;
-
- /*
- * Percent of airtime for transmission used within the last hour.
- */
- float air_util_tx = 4;
-}
-
-/*
- * Weather station or other environmental metrics
- */
-message EnvironmentMetrics {
- /*
- * Temperature measured
- */
- float temperature = 1;
-
- /*
- * Relative humidity percent measured
- */
- float relative_humidity = 2;
-
- /*
- * Barometric pressure in hPA measured
- */
- float barometric_pressure = 3;
-
- /*
- * Gas resistance in MOhm measured
- */
- float gas_resistance = 4;
-
- /*
- * Voltage measured (To be depreciated in favor of PowerMetrics in Meshtastic 3.x)
- */
- float voltage = 5;
-
- /*
- * Current measured (To be depreciated in favor of PowerMetrics in Meshtastic 3.x)
- */
- float current = 6;
-}
-
-/*
- * Power Metrics (voltage / current / etc)
- */
-message PowerMetrics {
- /*
- * Voltage (Ch1)
- */
- float ch1_voltage = 1;
-
- /*
- * Current (Ch1)
- */
- float ch1_current = 2;
-
- /*
- * Voltage (Ch2)
- */
- float ch2_voltage = 3;
-
- /*
- * Current (Ch2)
- */
- float ch2_current = 4;
-
- /*
- * Voltage (Ch3)
- */
- float ch3_voltage = 5;
-
- /*
- * Current (Ch3)
- */
- float ch3_current = 6;
-}
-
-/*
- * Air quality metrics
- */
-message AirQualityMetrics {
- /*
- * Concentration Units Standard PM1.0
- */
- uint32 pm10_standard = 1;
-
- /*
- * Concentration Units Standard PM2.5
- */
- uint32 pm25_standard = 2;
-
- /*
- * Concentration Units Standard PM10.0
- */
- uint32 pm100_standard = 3;
-
- /*
- * Concentration Units Environmental PM1.0
- */
- uint32 pm10_environmental = 4;
-
- /*
- * Concentration Units Environmental PM2.5
- */
- uint32 pm25_environmental = 5;
-
- /*
- * Concentration Units Environmental PM10.0
- */
- uint32 pm100_environmental = 6;
-
- /*
- * 0.3um Particle Count
- */
- uint32 particles_03um = 7;
-
- /*
- * 0.5um Particle Count
- */
- uint32 particles_05um = 8;
-
- /*
- * 1.0um Particle Count
- */
- uint32 particles_10um = 9;
-
- /*
- * 2.5um Particle Count
- */
- uint32 particles_25um = 10;
-
- /*
- * 5.0um Particle Count
- */
- uint32 particles_50um = 11;
-
- /*
- * 10.0um Particle Count
- */
- uint32 particles_100um = 12;
-}
-
-/*
- * Types of Measurements the telemetry module is equipped to handle
- */
-message Telemetry {
- /*
- * Seconds since 1970 - or 0 for unknown/unset
- */
- fixed32 time = 1;
-
- oneof variant {
- /*
- * Key native device metrics such as battery level
- */
- DeviceMetrics device_metrics = 2;
-
- /*
- * Weather station or other environmental metrics
- */
- EnvironmentMetrics environment_metrics = 3;
-
- /*
- * Air quality metrics
- */
- AirQualityMetrics air_quality_metrics = 4;
-
- /*
- * Power Metrics
- */
- PowerMetrics power_metrics = 5;
- }
-}
-
-/*
- * Supported I2C Sensors for telemetry in Meshtastic
- */
-enum TelemetrySensorType {
- /*
- * No external telemetry sensor explicitly set
- */
- SENSOR_UNSET = 0;
-
- /*
- * High accuracy temperature, pressure, humidity
- */
- BME280 = 1;
-
- /*
- * High accuracy temperature, pressure, humidity, and air resistance
- */
- BME680 = 2;
-
- /*
- * Very high accuracy temperature
- */
- MCP9808 = 3;
-
- /*
- * Moderate accuracy current and voltage
- */
- INA260 = 4;
-
- /*
- * Moderate accuracy current and voltage
- */
- INA219 = 5;
-
- /*
- * High accuracy temperature and pressure
- */
- BMP280 = 6;
-
- /*
- * High accuracy temperature and humidity
- */
- SHTC3 = 7;
-
- /*
- * High accuracy pressure
- */
- LPS22 = 8;
-
- /*
- * 3-Axis magnetic sensor
- */
- QMC6310 = 9;
-
- /*
- * 6-Axis inertial measurement sensor
- */
- QMI8658 = 10;
-
- /*
- * 3-Axis magnetic sensor
- */
- QMC5883L = 11;
-
- /*
- * High accuracy temperature and humidity
- */
- SHT31 = 12;
-
- /*
- * PM2.5 air quality sensor
- */
- PMSA003I = 13;
-
- /*
- * INA3221 3 Channel Voltage / Current Sensor
- */
- INA3221 = 14;
-
- /*
- * BMP085/BMP180 High accuracy temperature and pressure (older Version of BMP280)
- */
- BMP085 = 15;
-
-}
+syntax = "proto3";
+
+package meshtastic;
+
+option csharp_namespace = "Meshtastic.Protobufs";
+option go_package = "github.com/meshtastic/go/generated";
+option java_outer_classname = "TelemetryProtos";
+option java_package = "org.meshtastic.proto";
+option swift_prefix = "";
+
+/*
+ * Key native device metrics such as battery level
+ */
+message DeviceMetrics {
+ /*
+ * 0-100 (>100 means powered)
+ */
+ optional uint32 battery_level = 1;
+
+ /*
+ * Voltage measured
+ */
+ optional float voltage = 2;
+
+ /*
+ * Utilization for the current channel, including well formed TX, RX and malformed RX (aka noise).
+ */
+ optional float channel_utilization = 3;
+
+ /*
+ * Percent of airtime for transmission used within the last hour.
+ */
+ optional float air_util_tx = 4;
+
+ /*
+ * How long the device has been running since the last reboot (in seconds)
+ */
+ optional uint32 uptime_seconds = 5;
+}
+
+/*
+ * Weather station or other environmental metrics
+ */
+message EnvironmentMetrics {
+ /*
+ * Temperature measured
+ */
+ optional float temperature = 1;
+
+ /*
+ * Relative humidity percent measured
+ */
+ optional float relative_humidity = 2;
+
+ /*
+ * Barometric pressure in hPA measured
+ */
+ optional float barometric_pressure = 3;
+
+ /*
+ * Gas resistance in MOhm measured
+ */
+ optional float gas_resistance = 4;
+
+ /*
+ * Voltage measured (To be depreciated in favor of PowerMetrics in Meshtastic 3.x)
+ */
+ optional float voltage = 5;
+
+ /*
+ * Current measured (To be depreciated in favor of PowerMetrics in Meshtastic 3.x)
+ */
+ optional float current = 6;
+
+ /*
+ * relative scale IAQ value as measured by Bosch BME680 . value 0-500.
+ * Belongs to Air Quality but is not particle but VOC measurement. Other VOC values can also be put in here.
+ */
+ optional uint32 iaq = 7;
+
+ /*
+ * RCWL9620 Doppler Radar Distance Sensor, used for water level detection. Float value in mm.
+ */
+ optional float distance = 8;
+
+ /*
+ * VEML7700 high accuracy ambient light(Lux) digital 16-bit resolution sensor.
+ */
+ optional float lux = 9;
+
+ /*
+ * VEML7700 high accuracy white light(irradiance) not calibrated digital 16-bit resolution sensor.
+ */
+ optional float white_lux = 10;
+
+ /*
+ * Infrared lux
+ */
+ optional float ir_lux = 11;
+
+ /*
+ * Ultraviolet lux
+ */
+ optional float uv_lux = 12;
+
+ /*
+ * Wind direction in degrees
+ * 0 degrees = North, 90 = East, etc...
+ */
+ optional uint32 wind_direction = 13;
+
+ /*
+ * Wind speed in m/s
+ */
+ optional float wind_speed = 14;
+
+ /*
+ * Weight in KG
+ */
+ optional float weight = 15;
+
+ /*
+ * Wind gust in m/s
+ */
+ optional float wind_gust = 16;
+
+ /*
+ * Wind lull in m/s
+ */
+ optional float wind_lull = 17;
+
+ /*
+ * Radiation in µR/h
+ */
+ optional float radiation = 18;
+
+ /*
+ * Rainfall in the last hour in mm
+ */
+ optional float rainfall_1h = 19;
+
+ /*
+ * Rainfall in the last 24 hours in mm
+ */
+ optional float rainfall_24h = 20;
+
+ /*
+ * Soil moisture measured (% 1-100)
+ */
+ optional uint32 soil_moisture = 21;
+
+ /*
+ * Soil temperature measured (*C)
+ */
+ optional float soil_temperature = 22;
+
+ /*
+ * One-wire temperature (*C)
+ */
+ repeated float one_wire_temperature = 23;
+}
+
+/*
+ * Power Metrics (voltage / current / etc)
+ */
+message PowerMetrics {
+ /*
+ * Voltage (Ch1)
+ */
+ optional float ch1_voltage = 1;
+
+ /*
+ * Current (Ch1)
+ */
+ optional float ch1_current = 2;
+
+ /*
+ * Voltage (Ch2)
+ */
+ optional float ch2_voltage = 3;
+
+ /*
+ * Current (Ch2)
+ */
+ optional float ch2_current = 4;
+
+ /*
+ * Voltage (Ch3)
+ */
+ optional float ch3_voltage = 5;
+
+ /*
+ * Current (Ch3)
+ */
+ optional float ch3_current = 6;
+
+ /*
+ * Voltage (Ch4)
+ */
+ optional float ch4_voltage = 7;
+
+ /*
+ * Current (Ch4)
+ */
+ optional float ch4_current = 8;
+
+ /*
+ * Voltage (Ch5)
+ */
+ optional float ch5_voltage = 9;
+
+ /*
+ * Current (Ch5)
+ */
+ optional float ch5_current = 10;
+
+ /*
+ * Voltage (Ch6)
+ */
+ optional float ch6_voltage = 11;
+
+ /*
+ * Current (Ch6)
+ */
+ optional float ch6_current = 12;
+
+ /*
+ * Voltage (Ch7)
+ */
+ optional float ch7_voltage = 13;
+
+ /*
+ * Current (Ch7)
+ */
+ optional float ch7_current = 14;
+
+ /*
+ * Voltage (Ch8)
+ */
+ optional float ch8_voltage = 15;
+
+ /*
+ * Current (Ch8)
+ */
+ optional float ch8_current = 16;
+}
+
+/*
+ * Air quality metrics
+ */
+message AirQualityMetrics {
+ /*
+ * Concentration Units Standard PM1.0 in ug/m3
+ */
+ optional uint32 pm10_standard = 1;
+
+ /*
+ * Concentration Units Standard PM2.5 in ug/m3
+ */
+ optional uint32 pm25_standard = 2;
+
+ /*
+ * Concentration Units Standard PM10.0 in ug/m3
+ */
+ optional uint32 pm100_standard = 3;
+
+ /*
+ * Concentration Units Environmental PM1.0 in ug/m3
+ */
+ optional uint32 pm10_environmental = 4;
+
+ /*
+ * Concentration Units Environmental PM2.5 in ug/m3
+ */
+ optional uint32 pm25_environmental = 5;
+
+ /*
+ * Concentration Units Environmental PM10.0 in ug/m3
+ */
+ optional uint32 pm100_environmental = 6;
+
+ /*
+ * 0.3um Particle Count in #/0.1l
+ */
+ optional uint32 particles_03um = 7;
+
+ /*
+ * 0.5um Particle Count in #/0.1l
+ */
+ optional uint32 particles_05um = 8;
+
+ /*
+ * 1.0um Particle Count in #/0.1l
+ */
+ optional uint32 particles_10um = 9;
+
+ /*
+ * 2.5um Particle Count in #/0.1l
+ */
+ optional uint32 particles_25um = 10;
+
+ /*
+ * 5.0um Particle Count in #/0.1l
+ */
+ optional uint32 particles_50um = 11;
+
+ /*
+ * 10.0um Particle Count in #/0.1l
+ */
+ optional uint32 particles_100um = 12;
+
+ /*
+ * CO2 concentration in ppm
+ */
+ optional uint32 co2 = 13;
+
+ /*
+ * CO2 sensor temperature in degC
+ */
+ optional float co2_temperature = 14;
+
+ /*
+ * CO2 sensor relative humidity in %
+ */
+ optional float co2_humidity = 15;
+
+ /*
+ * Formaldehyde sensor formaldehyde concentration in ppb
+ */
+ optional float form_formaldehyde = 16;
+
+ /*
+ * Formaldehyde sensor relative humidity in %RH
+ */
+ optional float form_humidity = 17;
+
+ /*
+ * Formaldehyde sensor temperature in degrees Celsius
+ */
+ optional float form_temperature = 18;
+
+ /*
+ * Concentration Units Standard PM4.0 in ug/m3
+ */
+ optional uint32 pm40_standard = 19;
+
+ /*
+ * 4.0um Particle Count in #/0.1l
+ */
+ optional uint32 particles_40um = 20;
+
+ /*
+ * PM Sensor Temperature
+ */
+ optional float pm_temperature = 21;
+
+ /*
+ * PM Sensor humidity
+ */
+ optional float pm_humidity = 22;
+
+ /*
+ * PM Sensor VOC Index
+ */
+ optional float pm_voc_idx = 23;
+
+ /*
+ * PM Sensor NOx Index
+ */
+ optional float pm_nox_idx = 24;
+
+ /*
+ * Typical Particle Size in um
+ */
+ optional float particles_tps = 25;
+}
+
+/*
+ * Local device mesh statistics
+ */
+message LocalStats {
+ /*
+ * How long the device has been running since the last reboot (in seconds)
+ */
+ uint32 uptime_seconds = 1;
+ /*
+ * Utilization for the current channel, including well formed TX, RX and malformed RX (aka noise).
+ */
+ float channel_utilization = 2;
+ /*
+ * Percent of airtime for transmission used within the last hour.
+ */
+ float air_util_tx = 3;
+
+ /*
+ * Number of packets sent
+ */
+ uint32 num_packets_tx = 4;
+
+ /*
+ * Number of packets received (both good and bad)
+ */
+ uint32 num_packets_rx = 5;
+
+ /*
+ * Number of packets received that are malformed or violate the protocol
+ */
+ uint32 num_packets_rx_bad = 6;
+
+ /*
+ * Number of nodes online (in the past 2 hours)
+ */
+ uint32 num_online_nodes = 7;
+
+ /*
+ * Number of nodes total
+ */
+ uint32 num_total_nodes = 8;
+
+ /*
+ * Number of received packets that were duplicates (due to multiple nodes relaying).
+ * If this number is high, there are nodes in the mesh relaying packets when it's unnecessary, for example due to the ROUTER/REPEATER role.
+ */
+ uint32 num_rx_dupe = 9;
+
+ /*
+ * Number of packets we transmitted that were a relay for others (not originating from ourselves).
+ */
+ uint32 num_tx_relay = 10;
+
+ /*
+ * Number of times we canceled a packet to be relayed, because someone else did it before us.
+ * This will always be zero for ROUTERs/REPEATERs. If this number is high, some other node(s) is/are relaying faster than you.
+ */
+ uint32 num_tx_relay_canceled = 11;
+
+ /*
+ * Number of bytes used in the heap
+ */
+ uint32 heap_total_bytes = 12;
+
+ /*
+ * Number of bytes free in the heap
+ */
+ uint32 heap_free_bytes = 13;
+
+ /*
+ * Number of packets that were dropped because the transmit queue was full.
+ */
+ uint32 num_tx_dropped = 14;
+
+ /*
+ * Noise floor value measured in dBm
+ */
+ int32 noise_floor = 15;
+}
+
+/*
+ * Traffic management statistics for mesh network optimization
+ */
+message TrafficManagementStats {
+ /*
+ * Total number of packets inspected by traffic management
+ */
+ uint32 packets_inspected = 1;
+
+ /*
+ * Number of position packets dropped due to deduplication
+ */
+ uint32 position_dedup_drops = 2;
+
+ /*
+ * Number of NodeInfo requests answered from cache
+ */
+ uint32 nodeinfo_cache_hits = 3;
+
+ /*
+ * Number of packets dropped due to rate limiting
+ */
+ uint32 rate_limit_drops = 4;
+
+ /*
+ * Number of unknown/undecryptable packets dropped
+ */
+ uint32 unknown_packet_drops = 5;
+
+ /*
+ * Number of packets with hop_limit exhausted for local-only broadcast
+ */
+ uint32 hop_exhausted_packets = 6;
+
+ /*
+ * Number of times router hop preservation was applied
+ */
+ uint32 router_hops_preserved = 7;
+}
+
+/*
+ * Health telemetry metrics
+ */
+message HealthMetrics {
+ /*
+ * Heart rate (beats per minute)
+ */
+ optional uint32 heart_bpm = 1;
+
+ /*
+ * SpO2 (blood oxygen saturation) level
+ */
+ optional uint32 spO2 = 2;
+
+ /*
+ * Body temperature in degrees Celsius
+ */
+ optional float temperature = 3;
+}
+
+/*
+ * Linux host metrics
+ */
+message HostMetrics {
+ /*
+ * Host system uptime
+ */
+ uint32 uptime_seconds = 1;
+
+ /*
+ * Host system free memory
+ */
+ uint64 freemem_bytes = 2;
+
+ /*
+ * Host system disk space free for /
+ */
+ uint64 diskfree1_bytes = 3;
+
+ /*
+ * Secondary system disk space free
+ */
+ optional uint64 diskfree2_bytes = 4;
+
+ /*
+ * Tertiary disk space free
+ */
+ optional uint64 diskfree3_bytes = 5;
+
+ /*
+ * Host system one minute load in 1/100ths
+ */
+ uint32 load1 = 6;
+
+ /*
+ * Host system five minute load in 1/100ths
+ */
+ uint32 load5 = 7;
+
+ /*
+ * Host system fifteen minute load in 1/100ths
+ */
+ uint32 load15 = 8;
+
+ /*
+ * Optional User-provided string for arbitrary host system information
+ * that doesn't make sense as a dedicated entry.
+ */
+ optional string user_string = 9;
+}
+
+/*
+ * Types of Measurements the telemetry module is equipped to handle
+ */
+message Telemetry {
+ /*
+ * Seconds since 1970 - or 0 for unknown/unset
+ */
+ fixed32 time = 1;
+
+ oneof variant {
+ /*
+ * Key native device metrics such as battery level
+ */
+ DeviceMetrics device_metrics = 2;
+
+ /*
+ * Weather station or other environmental metrics
+ */
+ EnvironmentMetrics environment_metrics = 3;
+
+ /*
+ * Air quality metrics
+ */
+ AirQualityMetrics air_quality_metrics = 4;
+
+ /*
+ * Power Metrics
+ */
+ PowerMetrics power_metrics = 5;
+
+ /*
+ * Local device mesh statistics
+ */
+ LocalStats local_stats = 6;
+
+ /*
+ * Health telemetry metrics
+ */
+ HealthMetrics health_metrics = 7;
+
+ /*
+ * Linux host metrics
+ */
+ HostMetrics host_metrics = 8;
+
+ /*
+ * Traffic management statistics
+ */
+ TrafficManagementStats traffic_management_stats = 9;
+ }
+}
+
+/*
+ * Supported I2C Sensors for telemetry in Meshtastic
+ */
+enum TelemetrySensorType {
+ /*
+ * No external telemetry sensor explicitly set
+ */
+ SENSOR_UNSET = 0;
+
+ /*
+ * High accuracy temperature, pressure, humidity
+ */
+ BME280 = 1;
+
+ /*
+ * High accuracy temperature, pressure, humidity, and air resistance
+ */
+ BME680 = 2;
+
+ /*
+ * Very high accuracy temperature
+ */
+ MCP9808 = 3;
+
+ /*
+ * Moderate accuracy current and voltage
+ */
+ INA260 = 4;
+
+ /*
+ * Moderate accuracy current and voltage
+ */
+ INA219 = 5;
+
+ /*
+ * High accuracy temperature and pressure
+ */
+ BMP280 = 6;
+
+ /*
+ * TODO - REMOVE High accuracy temperature and humidity
+ */
+ SHTC3 = 7;
+
+ /*
+ * High accuracy pressure
+ */
+ LPS22 = 8;
+
+ /*
+ * 3-Axis magnetic sensor
+ */
+ QMC6310 = 9;
+
+ /*
+ * 6-Axis inertial measurement sensor
+ */
+ QMI8658 = 10;
+
+ /*
+ * 3-Axis magnetic sensor
+ */
+ QMC5883L = 11;
+
+ /*
+ * TODO - REMOVE High accuracy temperature and humidity
+ */
+ SHT31 = 12;
+
+ /*
+ * PM2.5 air quality sensor
+ */
+ PMSA003I = 13;
+
+ /*
+ * INA3221 3 Channel Voltage / Current Sensor
+ */
+ INA3221 = 14;
+
+ /*
+ * BMP085/BMP180 High accuracy temperature and pressure (older Version of BMP280)
+ */
+ BMP085 = 15;
+
+ /*
+ * RCWL-9620 Doppler Radar Distance Sensor, used for water level detection
+ */
+ RCWL9620 = 16;
+
+ /*
+ * TODO - REMOVE Sensirion High accuracy temperature and humidity
+ */
+ SHT4X = 17;
+
+ /*
+ * VEML7700 high accuracy ambient light(Lux) digital 16-bit resolution sensor.
+ */
+ VEML7700 = 18;
+
+ /*
+ * MLX90632 non-contact IR temperature sensor.
+ */
+ MLX90632 = 19;
+
+ /*
+ * TI OPT3001 Ambient Light Sensor
+ */
+ OPT3001 = 20;
+
+ /*
+ * Lite On LTR-390UV-01 UV Light Sensor
+ */
+ LTR390UV = 21;
+
+ /*
+ * AMS TSL25911FN RGB Light Sensor
+ */
+ TSL25911FN = 22;
+
+ /*
+ * AHT10 Integrated temperature and humidity sensor
+ */
+ AHT10 = 23;
+
+ /*
+ * DFRobot Lark Weather station (temperature, humidity, pressure, wind speed and direction)
+ */
+ DFROBOT_LARK = 24;
+
+ /*
+ * NAU7802 Scale Chip or compatible
+ */
+ NAU7802 = 25;
+
+ /*
+ * BMP3XX High accuracy temperature and pressure
+ */
+ BMP3XX = 26;
+
+ /*
+ * ICM-20948 9-Axis digital motion processor
+ */
+ ICM20948 = 27;
+
+ /*
+ * MAX17048 1S lipo battery sensor (voltage, state of charge, time to go)
+ */
+ MAX17048 = 28;
+
+ /*
+ * Custom I2C sensor implementation based on https://github.com/meshtastic/i2c-sensor
+ */
+ CUSTOM_SENSOR = 29;
+
+ /*
+ * MAX30102 Pulse Oximeter and Heart-Rate Sensor
+ */
+ MAX30102 = 30;
+
+ /*
+ * MLX90614 non-contact IR temperature sensor
+ */
+ MLX90614 = 31;
+
+ /*
+ * SCD40/SCD41 CO2, humidity, temperature sensor
+ */
+ SCD4X = 32;
+
+ /*
+ * ClimateGuard RadSens, radiation, Geiger-Muller Tube
+ */
+ RADSENS = 33;
+
+ /*
+ * High accuracy current and voltage
+ */
+ INA226 = 34;
+
+ /*
+ * DFRobot Gravity tipping bucket rain gauge
+ */
+ DFROBOT_RAIN = 35;
+
+ /*
+ * Infineon DPS310 High accuracy pressure and temperature
+ */
+ DPS310 = 36;
+
+ /*
+ * RAKWireless RAK12035 Soil Moisture Sensor Module
+ */
+ RAK12035 = 37;
+
+ /*
+ * MAX17261 lipo battery gauge
+ */
+ MAX17261 = 38;
+
+ /*
+ * PCT2075 Temperature Sensor
+ */
+ PCT2075 = 39;
+
+ /*
+ * ADS1X15 ADC
+ */
+ ADS1X15 = 40;
+
+ /*
+ * ADS1X15 ADC_ALT
+ */
+ ADS1X15_ALT = 41;
+
+ /*
+ * Sensirion SFA30 Formaldehyde sensor
+ */
+ SFA30 = 42;
+
+ /*
+ * SEN5X PM SENSORS
+ */
+ SEN5X = 43;
+
+ /*
+ * TSL2561 light sensor
+ */
+ TSL2561 = 44;
+
+ /*
+ * BH1750 light sensor
+ */
+ BH1750 = 45;
+
+ /*
+ * HDC1080 Temperature and Humidity Sensor
+ */
+ HDC1080 = 46;
+
+ /*
+ * TODO - REMOVE STH21 Temperature and R. Humidity sensor
+ */
+ SHT21 = 47;
+
+ /*
+ * Sensirion STC31 CO2 sensor
+ */
+ STC31 = 48;
+
+ /*
+ * SCD30 CO2, humidity, temperature sensor
+ */
+ SCD30 = 49;
+
+ /*
+ * SHT family of sensors for temperature and humidity
+ */
+ SHTXX = 50;
+
+ /*
+ * DS248X Bridge for one-wire temperature sensors
+ */
+ DS248X = 51;
+}
+
+/*
+ * NAU7802 Telemetry configuration, for saving to flash
+ */
+message Nau7802Config {
+ /*
+ * The offset setting for the NAU7802
+ */
+ int32 zeroOffset = 1;
+
+ /*
+ * The calibration factor for the NAU7802
+ */
+ float calibrationFactor = 2;
+}
+
+/*
+ * SEN5X State, for saving to flash
+ */
+message SEN5XState {
+ /*
+ * Last cleaning time for SEN5X
+ */
+ uint32 last_cleaning_time = 1;
+
+ /*
+ * Last cleaning time for SEN5X - valid flag
+ */
+ bool last_cleaning_valid = 2;
+
+ /*
+ * Config flag for one-shot mode (see admin.proto)
+ */
+ bool one_shot_mode = 3;
+
+ /*
+ * Last VOC state time for SEN55
+ */
+ optional uint32 voc_state_time = 4;
+
+ /*
+ * Last VOC state validity flag for SEN55
+ */
+ optional bool voc_state_valid = 5;
+
+ /*
+ * VOC state array (8x uint8t) for SEN55
+ */
+ optional fixed64 voc_state_array = 6;
+}
diff --git a/meshtastic/xmodem.proto b/meshtastic/xmodem.proto
index 732780a..2a049d1 100644
--- a/meshtastic/xmodem.proto
+++ b/meshtastic/xmodem.proto
@@ -5,7 +5,7 @@ package meshtastic;
option csharp_namespace = "Meshtastic.Protobufs";
option go_package = "github.com/meshtastic/go/generated";
option java_outer_classname = "XmodemProtos";
-option java_package = "com.geeksville.mesh";
+option java_package = "org.meshtastic.proto";
option swift_prefix = "";
message XModem {
diff --git a/nanopb.proto b/nanopb.proto
index 5e36eaa..1c107c1 100644
--- a/nanopb.proto
+++ b/nanopb.proto
@@ -6,40 +6,42 @@
// for memory-limited environments.
syntax = "proto2";
+
import "google/protobuf/descriptor.proto";
+option go_package = "github.com/meshtastic/go/generated";
option java_package = "fi.kapsi.koti.jpa.nanopb";
enum FieldType {
- FT_DEFAULT = 0; // Automatically decide field type, generate static field if possible.
- FT_CALLBACK = 1; // Always generate a callback field.
- FT_POINTER = 4; // Always generate a dynamically allocated field.
- FT_STATIC = 2; // Generate a static field or raise an exception if not possible.
- FT_IGNORE = 3; // Ignore the field completely.
- FT_INLINE = 5; // Legacy option, use the separate 'fixed_length' option instead
+ FT_DEFAULT = 0; // Automatically decide field type, generate static field if possible.
+ FT_CALLBACK = 1; // Always generate a callback field.
+ FT_POINTER = 4; // Always generate a dynamically allocated field.
+ FT_STATIC = 2; // Generate a static field or raise an exception if not possible.
+ FT_IGNORE = 3; // Ignore the field completely.
+ FT_INLINE = 5; // Legacy option, use the separate 'fixed_length' option instead
}
enum IntSize {
- IS_DEFAULT = 0; // Default, 32/64bit based on type in .proto
- IS_8 = 8;
- IS_16 = 16;
- IS_32 = 32;
- IS_64 = 64;
+ IS_DEFAULT = 0; // Default, 32/64bit based on type in .proto
+ IS_8 = 8;
+ IS_16 = 16;
+ IS_32 = 32;
+ IS_64 = 64;
}
enum TypenameMangling {
- M_NONE = 0; // Default, no typename mangling
- M_STRIP_PACKAGE = 1; // Strip current package name
- M_FLATTEN = 2; // Only use last path component
- M_PACKAGE_INITIALS = 3; // Replace the package name by the initials
+ M_NONE = 0; // Default, no typename mangling
+ M_STRIP_PACKAGE = 1; // Strip current package name
+ M_FLATTEN = 2; // Only use last path component
+ M_PACKAGE_INITIALS = 3; // Replace the package name by the initials
}
enum DescriptorSize {
- DS_AUTO = 0; // Select minimal size based on field type
- DS_1 = 1; // 1 word; up to 15 byte fields, no arrays
- DS_2 = 2; // 2 words; up to 4095 byte fields, 4095 entry arrays
- DS_4 = 4; // 4 words; up to 2^32-1 byte fields, 2^16-1 entry arrays
- DS_8 = 8; // 8 words; up to 2^32-1 entry arrays
+ DS_AUTO = 0; // Select minimal size based on field type
+ DS_1 = 1; // 1 word; up to 15 byte fields, no arrays
+ DS_2 = 2; // 2 words; up to 4095 byte fields, 4095 entry arrays
+ DS_4 = 4; // 4 words; up to 2^32-1 byte fields, 2^16-1 entry arrays
+ DS_8 = 8; // 8 words; up to 2^32-1 entry arrays
}
// This is the inner options message, which basically defines options for
@@ -49,32 +51,32 @@ message NanoPBOptions {
// Allocated size for 'bytes' and 'string' fields.
// For string fields, this should include the space for null terminator.
optional int32 max_size = 1;
-
+
// Maximum length for 'string' fields. Setting this is equivalent
// to setting max_size to a value of length+1.
optional int32 max_length = 14;
-
+
// Allocated number of entries in arrays ('repeated' fields)
optional int32 max_count = 2;
-
+
// Size of integer fields. Can save some memory if you don't need
// full 32 bits for the value.
optional IntSize int_size = 7 [default = IS_DEFAULT];
// Force type of field (callback or static allocation)
optional FieldType type = 3 [default = FT_DEFAULT];
-
+
// Use long names for enums, i.e. EnumName_EnumValue.
optional bool long_names = 4 [default = true];
-
+
// Add 'packed' attribute to generated structs.
// Note: this cannot be used on CPUs that break on unaligned
// accesses to variables.
optional bool packed_struct = 5 [default = false];
-
+
// Add 'packed' attribute to generated enums.
optional bool packed_enum = 10 [default = false];
-
+
// Skip this message
optional bool skip_message = 6 [default = false];
@@ -89,7 +91,7 @@ message NanoPBOptions {
// Proto3 singular field does not generate a "has_" flag
optional bool proto3 = 12 [default = false];
-
+
// Force proto3 messages to have no "has_" flag.
// This was default behavior until nanopb-0.4.0.
optional bool proto3_singular_msgs = 21 [default = false];
@@ -139,7 +141,7 @@ message NanoPBOptions {
// Package name that applies only for nanopb.
optional string package = 25;
-
+
// Override type of the field in generated C code. Only to be used with related field types
optional google.protobuf.FieldDescriptorProto.Type type_override = 27;
@@ -152,7 +154,7 @@ message NanoPBOptions {
// A field that can become a static member of a c struct (e.g. int, bool, etc)
// will be a a static field.
// Fields with dynamic length are converted to either a pointer or a callback.
- optional FieldType fallback_type = 29 [default = FT_CALLBACK];
+ optional FieldType fallback_type = 29 [default = FT_CALLBACK];
}
// Extensions to protoc 'Descriptor' type in order to define options
@@ -167,19 +169,17 @@ message NanoPBOptions {
// --------------------------------
extend google.protobuf.FileOptions {
- optional NanoPBOptions nanopb_fileopt = 1010;
+ optional NanoPBOptions nanopb_fileopt = 1010;
}
extend google.protobuf.MessageOptions {
- optional NanoPBOptions nanopb_msgopt = 1010;
+ optional NanoPBOptions nanopb_msgopt = 1010;
}
extend google.protobuf.EnumOptions {
- optional NanoPBOptions nanopb_enumopt = 1010;
+ optional NanoPBOptions nanopb_enumopt = 1010;
}
extend google.protobuf.FieldOptions {
- optional NanoPBOptions nanopb = 1010;
+ optional NanoPBOptions nanopb = 1010;
}
-
-
diff --git a/packages/rust/Cargo.lock b/packages/rust/Cargo.lock
new file mode 100644
index 0000000..0b80556
--- /dev/null
+++ b/packages/rust/Cargo.lock
@@ -0,0 +1,105 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "anyhow"
+version = "1.0.102"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
+
+[[package]]
+name = "bytes"
+version = "1.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
+
+[[package]]
+name = "either"
+version = "1.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
+
+[[package]]
+name = "itertools"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "meshtastic_protobufs"
+version = "2.5.5"
+dependencies = [
+ "prost",
+ "prost-types",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.106"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "prost"
+version = "0.14.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568"
+dependencies = [
+ "bytes",
+ "prost-derive",
+]
+
+[[package]]
+name = "prost-derive"
+version = "0.14.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b"
+dependencies = [
+ "anyhow",
+ "itertools",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "prost-types"
+version = "0.14.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7"
+dependencies = [
+ "prost",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.117"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
diff --git a/packages/rust/Cargo.toml b/packages/rust/Cargo.toml
new file mode 100644
index 0000000..f8dda5d
--- /dev/null
+++ b/packages/rust/Cargo.toml
@@ -0,0 +1,15 @@
+[package]
+name = "meshtastic_protobufs"
+edition = "2021"
+version = "__PACKAGE_VERSION__"
+description = "Meshtastic Protobuf definitions"
+repository = "https://github.com/meshtastic/protobufs"
+license-file = "LICENSE"
+include = [
+ "**/*.rs",
+ "Cargo.toml",
+]
+
+[dependencies]
+prost = "0.14.3"
+prost-types = "0.14.3"
diff --git a/packages/rust/src/generated/.gitkeep b/packages/rust/src/generated/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/packages/rust/src/lib.rs b/packages/rust/src/lib.rs
new file mode 100644
index 0000000..a5bf95a
--- /dev/null
+++ b/packages/rust/src/lib.rs
@@ -0,0 +1,5 @@
+extern crate prost;
+extern crate core;
+extern crate prost_types;
+
+include!("generated/mod.rs");
diff --git a/packages/ts/deno.json b/packages/ts/deno.json
new file mode 100644
index 0000000..99b801a
--- /dev/null
+++ b/packages/ts/deno.json
@@ -0,0 +1,15 @@
+{
+ "name": "@meshtastic/protobufs",
+ "version": "__PACKAGE_VERSION__",
+ "exports": {
+ ".": "./mod.ts"
+ },
+ "imports": {
+ "@bufbuild/protobuf": "npm:@bufbuild/protobuf@^2.2.3"
+ },
+ "publish": {
+ "exclude": [
+ "!lib"
+ ]
+ }
+}
diff --git a/packages/ts/deno.lock b/packages/ts/deno.lock
new file mode 100644
index 0000000..d39f28e
--- /dev/null
+++ b/packages/ts/deno.lock
@@ -0,0 +1,16 @@
+{
+ "version": "4",
+ "specifiers": {
+ "npm:@bufbuild/protobuf@^2.2.3": "2.2.3"
+ },
+ "npm": {
+ "@bufbuild/protobuf@2.2.3": {
+ "integrity": "sha512-tFQoXHJdkEOSwj5tRIZSPNUuXK3RaR7T1nUrPgbYX1pUbvqqaaZAsfo+NXBPsz5rZMSKVFrgK1WL8Q/MSLvprg=="
+ }
+ },
+ "workspace": {
+ "dependencies": [
+ "npm:@bufbuild/protobuf@^2.2.3"
+ ]
+ }
+}
diff --git a/packages/ts/lib/.gitkeep b/packages/ts/lib/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/packages/ts/mod.ts b/packages/ts/mod.ts
new file mode 100644
index 0000000..b043e49
--- /dev/null
+++ b/packages/ts/mod.ts
@@ -0,0 +1,20 @@
+export * as Admin from "./lib/admin_pb.ts";
+export * as AppOnly from "./lib/apponly_pb.ts";
+export * as ATAK from "./lib/atak_pb.ts";
+export * as CannedMessages from "./lib/cannedmessages_pb.ts";
+export * as Channel from "./lib/channel_pb.ts";
+export * as ClientOnly from "./lib/clientonly_pb.ts";
+export * as Config from "./lib/config_pb.ts";
+export * as ConnectionStatus from "./lib/connection_status_pb.ts";
+export * as LocalOnly from "./lib/localonly_pb.ts";
+export * as Mesh from "./lib/mesh_pb.ts";
+export * as ModuleConfig from "./lib/module_config_pb.ts";
+export * as Mqtt from "./lib/mqtt_pb.ts";
+export * as PaxCount from "./lib/paxcount_pb.ts";
+export * as Portnums from "./lib/portnums_pb.ts";
+export * as PowerMon from "./lib/powermon_pb.ts";
+export * as RemoteHardware from "./lib/remote_hardware_pb.ts";
+export * as Rtttl from "./lib/rtttl_pb.ts";
+export * as StoreForward from "./lib/storeforward_pb.ts";
+export * as Telemetry from "./lib/telemetry_pb.ts";
+export * as Xmodem from "./lib/xmodem_pb.ts";
diff --git a/packages/ts/package.json b/packages/ts/package.json
new file mode 100755
index 0000000..04f1162
--- /dev/null
+++ b/packages/ts/package.json
@@ -0,0 +1,32 @@
+{
+ "name": "@meshtastic/protobufs",
+ "description": "Protobuf definitions for the Meshtastic project",
+ "version": "__PACKAGE_VERSION__",
+ "homepage": "https://github.com/meshtastic/protobufs",
+ "license": "GPLV3",
+ "publishConfig": {
+ "access": "public"
+ },
+ "type": "module",
+ "main": "./dist/mod.js",
+ "module": "./dist/mod.js",
+ "types": "./dist/mod.d.ts",
+ "dependencies": {
+ "@bufbuild/protobuf": "^2.2.3"
+ },
+ "devDependencies": {
+ "tsdown": "^0.13.4",
+ "typescript": "^5.8.3"
+ },
+ "scripts": {
+ "build": "tsdown"
+ },
+ "tsdown": {
+ "entry": "mod.ts",
+ "dts": true,
+ "format": [
+ "esm"
+ ],
+ "splitting": false
+ }
+}
diff --git a/renovate.json b/renovate.json
new file mode 100644
index 0000000..5db72dd
--- /dev/null
+++ b/renovate.json
@@ -0,0 +1,6 @@
+{
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
+ "extends": [
+ "config:recommended"
+ ]
+}