diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..aa0afdc --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,206 @@ +# Copilot Instructions for Meshtastic Python + +## Project Overview + +This is the Meshtastic Python library and CLI - a Python API for interacting with Meshtastic mesh radio devices. It supports communication via Serial, TCP, and BLE interfaces. + +## Technology Stack + +- **Language**: Python 3.9 - 3.14 +- **Package Manager**: Poetry +- **Testing**: pytest with hypothesis for property-based testing +- **Linting**: pylint +- **Type Checking**: mypy (working toward strict mode) +- **Documentation**: pdoc3 +- **License**: GPL-3.0 + +## Project Structure + +``` +meshtastic/ # Main library package +├── __init__.py # Core interface classes and pub/sub topics +├── __main__.py # CLI entry point +├── mesh_interface.py # Base interface class for all connection types +├── serial_interface.py +├── tcp_interface.py +├── ble_interface.py +├── node.py # Node representation and configuration +├── protobuf/ # Generated Protocol Buffer files (*_pb2.py, *_pb2.pyi) +├── tests/ # Unit and integration tests +├── powermon/ # Power monitoring tools +└── analysis/ # Data analysis tools +examples/ # Usage examples +protobufs/ # Protocol Buffer source definitions +``` + +## Coding Standards + +### Style Guidelines + +- Follow PEP 8 style conventions +- Use type hints for function parameters and return values +- Document public functions and classes with docstrings +- Prefer explicit imports over wildcard imports +- Use `logging` module instead of print statements for debug output + +### Type Annotations + +- Add type hints to all new code +- Use `Optional[T]` for nullable types +- Use `Dict`, `List`, `Tuple` from `typing` module for Python 3.9 compatibility +- Protobuf types are in `meshtastic.protobuf.*_pb2` modules + +### Naming Conventions + +- Classes: `PascalCase` (e.g., `MeshInterface`, `SerialInterface`) +- Functions/methods: `camelCase` for public API (e.g., `sendText`, `sendData`) +- Internal functions: `snake_case` with leading underscore (e.g., `_send_packet`) +- Constants: `UPPER_SNAKE_CASE` (e.g., `BROADCAST_ADDR`, `LOCAL_ADDR`) + +### Error Handling + +- Use custom exception classes when appropriate (e.g., `MeshInterface.MeshInterfaceError`) +- Provide meaningful error messages +- Use `our_exit()` from `meshtastic.util` for CLI exits with error codes + +## Testing + +### Test Organization + +Tests are in `meshtastic/tests/` and use pytest markers: + +- `@pytest.mark.unit` - Fast unit tests (default) +- `@pytest.mark.unitslow` - Slower unit tests +- `@pytest.mark.int` - Integration tests +- `@pytest.mark.smoke1` - Single device smoke tests +- `@pytest.mark.smoke2` - Two device smoke tests +- `@pytest.mark.smokevirt` - Virtual device smoke tests +- `@pytest.mark.examples` - Example validation tests + +### Running Tests + +```bash +# Run unit tests only (default) +make test +# or +pytest -m unit + +# Run all tests +pytest + +# Run with coverage +make cov +``` + +### Writing Tests + +- Use `pytest` fixtures from `conftest.py` +- Use `hypothesis` for property-based testing where appropriate +- Mock external dependencies (serial ports, network connections) +- Test file naming: `test_.py` + +## Pub/Sub Events + +The library uses pypubsub for event handling. Key topics: + +- `meshtastic.connection.established` - Connection successful +- `meshtastic.connection.lost` - Connection lost +- `meshtastic.receive.text(packet)` - Text message received +- `meshtastic.receive.position(packet)` - Position update received +- `meshtastic.receive.data.portnum(packet)` - Data packet by port number +- `meshtastic.node.updated(node)` - Node database changed +- `meshtastic.log.line(line)` - Raw log line from device + +## Protocol Buffers + +- Protobuf definitions are in `protobufs/meshtastic/` +- Generated Python files are in `meshtastic/protobuf/` +- Never edit `*_pb2.py` or `*_pb2.pyi` files directly +- Regenerate with: `make protobufs` or `./bin/regen-protobufs.sh` + +## Common Patterns + +### Creating an Interface + +```python +import meshtastic.serial_interface + +# Auto-detect device +iface = meshtastic.serial_interface.SerialInterface() + +# Specific device +iface = meshtastic.serial_interface.SerialInterface(devPath="/dev/ttyUSB0") + +# Always close when done +iface.close() + +# Or use context manager +with meshtastic.serial_interface.SerialInterface() as iface: + iface.sendText("Hello mesh") +``` + +### Sending Messages + +```python +# Text message (broadcast) +iface.sendText("Hello") + +# Text message to specific node +iface.sendText("Hello", destinationId="!abcd1234") + +# Binary data +iface.sendData(data, portNum=portnums_pb2.PRIVATE_APP) +``` + +### Subscribing to Events + +```python +from pubsub import pub + +def on_receive(packet, interface): + print(f"Received: {packet}") + +pub.subscribe(on_receive, "meshtastic.receive") +``` + +## Development Workflow + +1. Install dependencies: `poetry install --all-extras --with dev` +2. Make changes +3. Run linting: `poetry run pylint meshtastic examples/` +4. Run type checking: `poetry run mypy meshtastic/` +5. Run tests: `poetry run pytest -m unit` +6. Update documentation if needed + +## CLI Development + +The CLI is in `meshtastic/__main__.py`. When adding new CLI commands: + +- Use argparse for argument parsing +- Support `--dest` for specifying target node +- Provide `--help` documentation +- Handle errors gracefully with meaningful messages + +## Dependencies + +### Required +- `pyserial` - Serial port communication +- `protobuf` - Protocol Buffers +- `pypubsub` - Pub/sub messaging +- `bleak` - BLE communication +- `tabulate` - Table formatting +- `pyyaml` - YAML config support +- `requests` - HTTP requests + +### Optional (extras) +- `cli` extra: `pyqrcode`, `print-color`, `dotmap`, `argcomplete` +- `tunnel` extra: `pytap2` +- `analysis` extra: `dash`, `pandas` + +## Important Notes + +- Always test with actual Meshtastic hardware when possible +- Be mindful of radio regulations in your region +- The nodedb (`interface.nodes`) is read-only +- Packet IDs are random 32-bit integers +- Default timeout is 300 seconds for operations diff --git a/.github/workflows/update_protobufs.yml b/.github/workflows/update_protobufs.yml index c7b9375..b9c7558 100644 --- a/.github/workflows/update_protobufs.yml +++ b/.github/workflows/update_protobufs.yml @@ -1,6 +1,9 @@ name: "Update protobufs" on: workflow_dispatch +permissions: + contents: write + jobs: update-protobufs: runs-on: ubuntu-latest @@ -9,23 +12,34 @@ jobs: - name: Checkout code uses: actions/checkout@v4 with: + fetch-depth: 0 submodules: true - - name: Update Submodule + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install Poetry run: | - git pull --recurse-submodules + python -m pip install --upgrade pip + python -m pip install poetry + + - name: Update protobuf submodule + run: | + git submodule sync --recursive + git submodule update --init --recursive git submodule update --remote --recursive - name: Download nanopb run: | - wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.8-linux-x86.tar.gz + curl -L -o nanopb-0.4.8-linux-x86.tar.gz https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.8-linux-x86.tar.gz tar xvzf nanopb-0.4.8-linux-x86.tar.gz mv nanopb-0.4.8-linux-x86 nanopb-0.4.8 - - name: Install poetry (needed by regen-protobufs.sh) + - name: Install Python dependencies run: | - python -m pip install --upgrade pip - pip3 install poetry + poetry install --with dev - name: Re-generate protocol buffers run: | @@ -38,4 +52,9 @@ jobs: git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }} git add protobufs git add meshtastic/protobuf - git commit -m "Update protobuf submodule" && git push || echo "No changes to commit" + if [[ -n "$(git status --porcelain)" ]]; then + git commit -m "Update protobufs" + git push + else + echo "No changes to commit" + fi diff --git a/bin/inject_nanopb_options.py b/bin/inject_nanopb_options.py new file mode 100644 index 0000000..38df902 --- /dev/null +++ b/bin/inject_nanopb_options.py @@ -0,0 +1,332 @@ +#!/usr/bin/env python3 +"""Inject nanopb .options constraints as inline field options into a .proto file. + +The nanopb .options file format is specific to the nanopb C generator and is +ignored by standard protoc (including --python_out). By injecting the options +directly into the proto file's field declarations, protoc will embed them in +the serialized descriptor, making them accessible in Python via: + + from meshtastic.protobuf import mesh_pb2, nanopb_pb2 + field = mesh_pb2.DESCRIPTOR.message_types_by_name['User'].fields_by_name['long_name'] + opts = field.GetOptions().Extensions[nanopb_pb2.nanopb] + print(opts.max_size) # 40 + +Usage: + inject_nanopb_options.py + +The proto_file is modified in-place. Intended to operate on temporary copies +generated by regen-protobufs.sh, not the source .proto files. +""" + +import re +import sys +from pathlib import Path +from typing import Any, Dict, List, Tuple + +# IntSize enum values from nanopb.proto +INT_SIZE_ENUM = {8: "IS_8", 16: "IS_16", 32: "IS_32", 64: "IS_64"} + +# Options that are valid proto FieldOptions and useful outside of C code generation. +# We skip C-only options (anonymous_oneof, no_unions, skip_message, packed_struct, +# packed_enum, mangle_names, callback_datatype, callback_function, descriptorsize, +# type_override) since they either don't apply to proto fields or are C-specific. +FIELD_OPTIONS = frozenset( + { + "max_size", + "max_length", + "max_count", + "int_size", + "fixed_length", + "fixed_count", + "long_names", + "proto3", + "default_has", + "sort_by_tag", + "msgid", + } +) + + +def parse_value(s: str) -> Any: + """Convert an option value string to an appropriate Python type.""" + if re.fullmatch(r"-?[0-9]+", s): + return int(s) + if s.lower() == "true": + return True + if s.lower() == "false": + return False + return s + + +def parse_options_file( + path: Path, +) -> Tuple[Dict[Tuple[str, ...], Dict[str, Any]], Dict[str, Dict[str, Any]]]: + """Parse a nanopb .options file. + + Returns: + specific: maps (message_path..., field_name) -> {option: value} + e.g. ('User', 'long_name') or ('Route', 'Link', 'uid') + wildcard: maps field_name -> {option: value} + applies to any field with this name in the same proto file + """ + specific: Dict[Tuple[str, ...], Dict[str, Any]] = {} + wildcard: Dict[str, Dict[str, Any]] = {} + + with open(path, encoding="utf-8") as f: + for line in f: + # Strip inline comments + comment_pos = line.find("#") + if comment_pos >= 0: + line = line[:comment_pos] + line = line.strip().lstrip("*").strip() + if not line: + continue + + tokens = line.split() + if len(tokens) < 2: + continue + + pattern = tokens[0] + opts: Dict[str, Any] = {} + for tok in tokens[1:]: + if ":" in tok: + k, v = tok.split(":", 1) + if k in FIELD_OPTIONS: + opts[k] = parse_value(v) + + if not opts: + continue + + if "." in pattern: + # e.g. "User.long_name" -> key=('User', 'long_name') + # or "Route.Link.uid" -> key=('Route', 'Link', 'uid') + parts = tuple(pattern.split(".")) + if parts in specific: + specific[parts].update(opts) + else: + specific[parts] = opts + else: + # wildcard: applies to any field with this name + if pattern in wildcard: + wildcard[pattern].update(opts) + else: + wildcard[pattern] = opts + + return specific, wildcard + + +def format_nanopb_opts(opts: Dict[str, Any]) -> str: + """Format a dict of nanopb options as a proto field options annotation string.""" + parts = [] + for k, v in opts.items(): + if k == "int_size": + enum_val = INT_SIZE_ENUM.get(v, f"IS_{v}") + parts.append(f"(nanopb).int_size = {enum_val}") + elif isinstance(v, bool): + parts.append(f"(nanopb).{k} = {'true' if v else 'false'}") + else: + parts.append(f"(nanopb).{k} = {v}") + return ", ".join(parts) + + +def message_path_matches( + context_stack: List[Tuple[str, str]], msg_path: Tuple[str, ...] +) -> bool: + """Check if the current message context ends with msg_path. + + context_stack entries are ('message'|'oneof'|'enum', name). + msg_path is the tuple of message names from the options pattern, + e.g. ('User',) or ('Route', 'Link'). + """ + msg_names = [name for kind, name in context_stack if kind == "message"] + n = len(msg_path) + return len(msg_names) >= n and tuple(msg_names[-n:]) == msg_path + + +def inject_into_proto( + content: str, + specific: Dict[Tuple[str, ...], Dict[str, Any]], + wildcard: Dict[str, Dict[str, Any]], + nanopb_import_path: str, +) -> str: + """Inject nanopb field options into a proto file's text content. + + Adds an import for nanopb.proto if not already present. + Returns the modified content. + """ + if not specific and not wildcard: + return content + + lines = content.split("\n") + + # Check if nanopb is already imported (after sed fixup, it will be + # 'meshtastic/protobuf/nanopb.proto') + nanopb_already_imported = any( + "nanopb.proto" in line + for line in lines + if line.strip().startswith("import") + ) + + # Track the index of the last import line so we can insert after it + last_import_idx = max( + ( + i + for i, line in enumerate(lines) + if line.strip().startswith("import ") and line.strip().endswith(";") + ), + default=-1, + ) + + # State + context_stack: List[Tuple[str, str]] = [] # ('message'|'oneof'|'enum', name) + result: List[str] = [] + import_added = nanopb_already_imported + + # Patterns for proto structural elements + message_re = re.compile(r"^(\s*)message\s+(\w+)\s*\{") + oneof_re = re.compile(r"^(\s*)oneof\s+(\w+)\s*\{") + enum_re = re.compile(r"^(\s*)enum\s+(\w+)\s*\{") + close_re = re.compile(r"^\s*\}") + + # Pattern for field declarations: + # indent [optional|repeated] type name = number [options] ; + # We exclude map<> fields (different syntax, nanopb handles them differently) + # and enum value lines (no type keyword before the name). + field_re = re.compile( + r"^(\s*)" # (1) indent + r"(optional\s+|repeated\s+)?" # (2) optional qualifier + r"([\w.]+)\s+" # (3) field type (possibly qualified like google.protobuf.Any) + r"(\w+)\s*" # (4) field name + r"=\s*(\d+)" # (5) field number + r"(?:\s*\[([^\]]*)\])?" # (6) existing options, without brackets + r"\s*;" # trailing semicolon + ) + + for i, line in enumerate(lines): + # Insert nanopb import right after the last existing import line. + # Only do this when there IS an existing import (last_import_idx >= 0); + # if there are no imports we fall through to the syntax-line fallback below. + if not import_added and last_import_idx >= 0 and i == last_import_idx + 1: + result.append(f'import "{nanopb_import_path}";') + import_added = True + + # --- Track message/oneof/enum nesting --- + m = message_re.match(line) + if m: + context_stack.append(("message", m.group(2))) + result.append(line) + continue + + m = oneof_re.match(line) + if m: + context_stack.append(("oneof", m.group(2))) + result.append(line) + continue + + m = enum_re.match(line) + if m: + context_stack.append(("enum", m.group(2))) + result.append(line) + continue + + if close_re.match(line) and context_stack: + context_stack.pop() + result.append(line) + continue + + # Skip field injection inside enum bodies (enum values look like fields + # but should not have nanopb options added) + in_enum = bool(context_stack) and context_stack[-1][0] == "enum" + + # --- Try to match and modify a field declaration --- + m = field_re.match(line) + if m and not in_enum: + indent = m.group(1) + qualifier = m.group(2) or "" + ftype = m.group(3) + fname = m.group(4) + fnum = m.group(5) + existing_opts = m.group(6) or "" + + # Collect applicable nanopb options (wildcard < specific) + extra: Dict[str, Any] = {} + + # 1. Wildcard: any field with this name in this proto file + if fname in wildcard: + extra.update(wildcard[fname]) + + # 2. Specific: check all keys whose last element is fname and whose + # preceding path matches the current message context + for key, opts in specific.items(): + if key[-1] == fname: + msg_path = key[:-1] + if message_path_matches(context_stack, msg_path): + extra.update(opts) + break + + if extra: + nanopb_str = format_nanopb_opts(extra) + if existing_opts.strip(): + opts_block = f"[{existing_opts}, {nanopb_str}]" + else: + opts_block = f"[{nanopb_str}]" + qual = qualifier.rstrip() + sep = " " if qual else "" + line = f"{indent}{qual}{sep}{ftype} {fname} = {fnum} {opts_block};" + + result.append(line) + + # Edge case: if there were no import lines, add nanopb import after syntax line + if not import_added: + for i, line in enumerate(result): + if line.strip().startswith("syntax") and line.strip().endswith(";"): + result.insert(i + 1, f'import "{nanopb_import_path}";') + break + + return "\n".join(result) + + +def main() -> int: + """Parse an .options file and inject its constraints into a .proto file in-place.""" + if len(sys.argv) != 3: + print( + f"Usage: {sys.argv[0]} ", + file=sys.stderr, + ) + return 1 + + opts_path = Path(sys.argv[1]) + proto_path = Path(sys.argv[2]) + + if not opts_path.exists(): + print(f"Options file not found: {opts_path}", file=sys.stderr) + return 1 + + if not proto_path.exists(): + print(f"Proto file not found: {proto_path}", file=sys.stderr) + return 1 + + specific, wildcard = parse_options_file(opts_path) + total = len(specific) + len(wildcard) + + if total == 0: + print(f" [{opts_path.name}] No injectable options found, skipping.") + return 0 + + content = proto_path.read_text(encoding="utf-8") + + # After regen-protobufs.sh's sed fixup, the nanopb import path is: + nanopb_import_path = "meshtastic/protobuf/nanopb.proto" + + modified = inject_into_proto(content, specific, wildcard, nanopb_import_path) + proto_path.write_text(modified, encoding="utf-8") + + print( + f" [{opts_path.name}] Injected {len(specific)} specific + " + f"{len(wildcard)} wildcard option(s) into {proto_path.name}" + ) + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/bin/regen-protobufs.sh b/bin/regen-protobufs.sh index 23def7b..70df9e2 100755 --- a/bin/regen-protobufs.sh +++ b/bin/regen-protobufs.sh @@ -28,6 +28,7 @@ OUTDIR=${TMPDIR}/out PYIDIR=${TMPDIR}/out mkdir -p "${OUTDIR}" "${INDIR}" "${PYIDIR}" cp ./protobufs/meshtastic/*.proto "${INDIR}" +cp ./protobufs/meshtastic/*.options "${INDIR}" cp ./protobufs/nanopb.proto "${INDIR}" # OS-X sed is apparently a little different and expects an arg for -i @@ -45,6 +46,19 @@ $SEDCMD 's/^import "meshtastic\//import "meshtastic\/protobuf\//' "${INDIR}/"*.p $SEDCMD 's/^import "nanopb.proto"/import "meshtastic\/protobuf\/nanopb.proto"/' "${INDIR}/"*.proto +# Inject nanopb .options constraints as inline proto field options so that +# protoc --python_out embeds them in the generated descriptors. Python code +# can then read them via: +# field.GetOptions().Extensions[nanopb_pb2.nanopb].max_size +echo "Injecting nanopb options into proto files..." +for OPTS_FILE in "${INDIR}"/*.options; do + BASENAME=$(basename "${OPTS_FILE}" .options) + PROTO_FILE="${INDIR}/${BASENAME}.proto" + if [ -f "${PROTO_FILE}" ]; then + python3 ./bin/inject_nanopb_options.py "${OPTS_FILE}" "${PROTO_FILE}" + fi +done + # Generate the python files ./nanopb-0.4.8/generator-bin/protoc -I=$TMPDIR/in --python_out "${OUTDIR}" "--mypy_out=${PYIDIR}" $INDIR/*.proto diff --git a/examples/pub_sub_example2.py b/examples/pub_sub_example2.py index c5d3791..64819be 100644 --- a/examples/pub_sub_example2.py +++ b/examples/pub_sub_example2.py @@ -7,8 +7,7 @@ import time from pubsub import pub -import meshtastic -import meshtastic.tcp_interface +from meshtastic.tcp_interface import TCPInterface # simple arg check if len(sys.argv) < 2: @@ -29,11 +28,15 @@ def onConnection(interface, topic=pub.AUTO_TOPIC): # pylint: disable=unused-arg pub.subscribe(onReceive, "meshtastic.receive") pub.subscribe(onConnection, "meshtastic.connection.established") + +iface=None try: - iface = meshtastic.tcp_interface.TCPInterface(hostname=sys.argv[1]) + iface = TCPInterface(hostname=sys.argv[1]) while True: time.sleep(1000) - iface.close() except Exception as ex: print(f"Error: Could not connect to {sys.argv[1]} {ex}") - sys.exit(1) + raise +finally: + if iface: + iface.close() diff --git a/examples/replymessage.py b/examples/replymessage.py new file mode 100644 index 0000000..f6f48a2 --- /dev/null +++ b/examples/replymessage.py @@ -0,0 +1,73 @@ +"""Reply message demo script. + To run: python examples/replymessage.py + To run with TCP: python examples/replymessage.py --host 192.168.1.5 + To run with BLE: python examples/replymessage.py --ble 24:62:AB:DD:DF:3A +""" + +import argparse +import time +from typing import Any, Optional, Union +from pubsub import pub +import meshtastic.serial_interface +import meshtastic.tcp_interface +import meshtastic.ble_interface +from meshtastic.mesh_interface import MeshInterface + +def onReceive(packet: dict, interface: MeshInterface) -> None: # pylint: disable=unused-argument + """Reply to every received packet with some info""" + text: Optional[str] = packet.get("decoded", {}).get("text") + if text: + rx_snr: Any = packet.get("rxSnr", "unknown") + hop_limit: Any = packet.get("hopLimit", "unknown") + print(f"message: {text}") + reply: str = f"got msg '{text}' with rxSnr: {rx_snr} and hopLimit: {hop_limit}" + print("Sending reply: ", reply) + interface.sendText(reply) + +def onConnection(interface: MeshInterface, topic: Any = pub.AUTO_TOPIC) -> None: # pylint: disable=unused-argument + """called when we (re)connect to the radio""" + print("Connected. Will auto-reply to all messages while running.") + +parser = argparse.ArgumentParser(description="Meshtastic Auto-Reply Feature Demo") +group = parser.add_mutually_exclusive_group() +group.add_argument("--host", help="Connect via TCP to this hostname or IP") +group.add_argument("--ble", help="Connect via BLE to this MAC address") + +args = parser.parse_args() + +pub.subscribe(onReceive, "meshtastic.receive") +pub.subscribe(onConnection, "meshtastic.connection.established") + +iface: Optional[Union[ + meshtastic.tcp_interface.TCPInterface, + meshtastic.ble_interface.BLEInterface, + meshtastic.serial_interface.SerialInterface +]] = None + +# defaults to serial, use --host for TCP or --ble for Bluetooth +try: + if args.host: + # note: timeout only applies after connection, not during the initial connect attempt + # TCPInterface.myConnect() calls socket.create_connection() without a timeout + iface = meshtastic.tcp_interface.TCPInterface(hostname=args.host, timeout=10) + elif args.ble: + iface = meshtastic.ble_interface.BLEInterface(address=args.ble, timeout=10) + else: + iface = meshtastic.serial_interface.SerialInterface(timeout=10) +except KeyboardInterrupt as exc: + raise SystemExit(0) from exc +except Exception as e: + print(f"Error: Could not connect. {e}") + raise SystemExit(1) from e + +try: + while True: + time.sleep(1) +except KeyboardInterrupt: + pass +finally: + try: + if iface: + iface.close() + except AttributeError: + pass diff --git a/examples/textchat.py b/examples/textchat.py new file mode 100644 index 0000000..bfceb0b --- /dev/null +++ b/examples/textchat.py @@ -0,0 +1,73 @@ +"""Simple text chat demo for meshtastic. + To run: python examples/textchat.py + To run with TCP: python examples/textchat.py --host 192.168.1.5 + To run with BLE: python examples/textchat.py --ble 24:62:AB:DD:DF:3A +""" + +import argparse +from typing import Any, Optional, Union +from pubsub import pub +import meshtastic.serial_interface +import meshtastic.tcp_interface +import meshtastic.ble_interface +from meshtastic.mesh_interface import MeshInterface + +def onReceive(packet: dict, interface: MeshInterface) -> None: # pylint: disable=unused-argument + """called when a packet arrives""" + text: Optional[str] = packet.get("decoded", {}).get("text") + if text: + sender: str = packet.get("fromId", "unknown") + print(f"{sender}: {text}") + +def onConnection(interface: MeshInterface, topic: Any = pub.AUTO_TOPIC) -> None: # pylint: disable=unused-argument + """called when we (re)connect to the radio""" + print("Connected. Type a message and press Enter to send. Ctrl+C to exit.") + +parser = argparse.ArgumentParser(description="Meshtastic text chat demo") +group = parser.add_mutually_exclusive_group() +group.add_argument("--host", help="Connect via TCP to this hostname or IP") +group.add_argument("--ble", help="Connect via BLE to this MAC address or device name") + +args = parser.parse_args() + +pub.subscribe(onReceive, "meshtastic.receive") +pub.subscribe(onConnection, "meshtastic.connection.established") + +iface: Optional[Union[ + meshtastic.tcp_interface.TCPInterface, + meshtastic.ble_interface.BLEInterface, + meshtastic.serial_interface.SerialInterface +]] = None + +# defaults to serial, use --host for TCP or --ble for Bluetooth +try: + if args.host: + # note: timeout only applies after connection, not during the initial connect attempt + # TCPInterface.myConnect() calls socket.create_connection() without a timeout + iface = meshtastic.tcp_interface.TCPInterface(hostname=args.host, timeout=10) + elif args.ble: + iface = meshtastic.ble_interface.BLEInterface(address=args.ble, timeout=10) + else: + iface = meshtastic.serial_interface.SerialInterface(timeout=10) +except KeyboardInterrupt as exc: + raise SystemExit(0) from exc +except Exception as e: + print(f"Error: Could not connect. {e}") + raise SystemExit(1) from e + +assert iface is not None +try: + while True: + line = input() + if line: + iface.sendText(line) +except KeyboardInterrupt: + pass +except EOFError: + pass +finally: + try: + if iface: + iface.close() + except AttributeError: + pass diff --git a/meshtastic/__init__.py b/meshtastic/__init__.py index 34cc731..b3aa8c4 100644 --- a/meshtastic/__init__.py +++ b/meshtastic/__init__.py @@ -179,8 +179,30 @@ def _onPositionReceive(iface, asDict): logger.debug(f"p:{p}") p = iface._fixupPosition(p) logger.debug(f"after fixup p:{p}") - # update node DB as needed - iface._getOrCreateByNum(asDict["from"])["position"] = p + # For the local node, only accept position updates with equal + # or better precision. The local GPS is authoritative, and + # low-precision echoes from the mesh (e.g., map reports relayed + # by other nodes) should not overwrite it. + # For remote nodes, always accept the latest position since + # any update from them reflects their current state. + node = iface._getOrCreateByNum(asDict["from"]) + is_local_node = ( + iface.myInfo is not None + and asDict["from"] == iface.myInfo.my_node_num + ) + if is_local_node: + existing = node.get("position", {}) + existing_precision = existing.get("precisionBits", 0) or 0 + new_precision = p.get("precisionBits", 0) or 0 + if existing_precision == 0 or new_precision >= existing_precision: + node["position"] = p + else: + logger.debug( + f"Ignoring low-precision position echo for local node " + f"({new_precision} < {existing_precision})" + ) + else: + node["position"] = p def _onNodeInfoReceive(iface, asDict): diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 1685400..89390e6 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -37,6 +37,7 @@ try: except ImportError as e: have_test = False +import meshtastic.ota import meshtastic.util import meshtastic.serial_interface import meshtastic.tcp_interface @@ -60,7 +61,7 @@ except ImportError as e: have_powermon = False powermon_exception = e meter = None -from meshtastic.protobuf import channel_pb2, config_pb2, portnums_pb2, mesh_pb2 +from meshtastic.protobuf import admin_pb2, channel_pb2, config_pb2, portnums_pb2, mesh_pb2 from meshtastic.version import get_active_version logger = logging.getLogger(__name__) @@ -85,12 +86,17 @@ def onReceive(packet, interface) -> None: if d is not None and args and args.reply: msg = d.get("text") if msg: - rxSnr = packet["rxSnr"] - hopLimit = packet["hopLimit"] - print(f"message: {msg}") - reply = f"got msg '{msg}' with rxSnr: {rxSnr} and hopLimit: {hopLimit}" - print("Sending reply: ", reply) - interface.sendText(reply) + rxChannel = packet.get("channel", 0) + targetChannel = int(args.ch_index or 0) + if rxChannel == targetChannel: + rxSnr = packet["rxSnr"] + hopLimit = packet["hopLimit"] + print(f"message: {msg}") + reply = f"got msg '{msg}' with rxSnr: {rxSnr} and hopLimit: {hopLimit}" + print(f"Received channel {rxChannel}. Sending reply: {reply}") + interface.sendText(reply,channelIndex=rxChannel) + else: + print(f"Ignored message on channel {rxChannel} (waiting for channel {targetChannel})") except Exception as ex: print(f"Warning: Error processing received packet: {ex}.") @@ -158,11 +164,11 @@ def getPref(node, comp_name) -> bool: config_values = getattr(config, config_type.name) if not wholeField: pref_value = getattr(config_values, pref.name) - repeated = pref.label == pref.LABEL_REPEATED + repeated = _is_repeated_field(pref) _printSetting(config_type, uni_name, pref_value, repeated) else: for field in config_values.ListFields(): - repeated = field[0].label == field[0].LABEL_REPEATED + repeated = _is_repeated_field(field[0]) _printSetting(config_type, field[0].name, field[1], repeated) else: # Always show whole field for remote node @@ -253,7 +259,7 @@ def setPref(config, comp_name, raw_val) -> bool: return False # repeating fields need to be handled with append, not setattr - if pref.label != pref.LABEL_REPEATED: + if not _is_repeated_field(pref): try: if config_type.message_type is not None: config_values = getattr(config_part, config_type.name) @@ -452,6 +458,41 @@ def onConnected(interface): waitForAckNak = True interface.getNode(args.dest, False, **getNode_kwargs).rebootOTA() + if args.ota_update: + closeNow = True + waitForAckNak = True + + if not isinstance(interface, meshtastic.tcp_interface.TCPInterface): + meshtastic.util.our_exit( + "Error: OTA update currently requires a TCP connection to the node (use --host)." + ) + + ota = meshtastic.ota.ESP32WiFiOTA(args.ota_update, interface.hostname) + + print(f"Triggering OTA update on {interface.hostname}...") + interface.getNode(args.dest, False, **getNode_kwargs).startOTA( + ota_mode=admin_pb2.OTAMode.OTA_WIFI, + ota_file_hash=ota.hash_bytes() + ) + + print("Waiting for device to reboot into OTA mode...") + time.sleep(5) + + retries = 5 + while retries > 0: + try: + ota.update() + break + + except Exception as e: + retries -= 1 + if retries == 0: + meshtastic.util.our_exit(f"\nOTA update failed: {e}") + + time.sleep(2) + + print("\nOTA update completed successfully!") + if args.enter_dfu: closeNow = True waitForAckNak = True @@ -1131,6 +1172,14 @@ def subscribe() -> None: # pub.subscribe(onNode, "meshtastic.node") +def _is_repeated_field(field_desc) -> bool: + """Return True if the protobuf field is repeated. + Protobuf 6.31.0 and later use an is_repeated property, while older versions compare against the label field. + """ + if hasattr(field_desc, "is_repeated"): + return bool(field_desc.is_repeated) + return field_desc.label == field_desc.LABEL_REPEATED + def set_missing_flags_false(config_dict: dict, true_defaults: set[tuple[str, str]]) -> None: """Ensure that missing default=True keys are present in the config_dict and set to False.""" for path in true_defaults: @@ -1883,7 +1932,10 @@ def addRemoteActionArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentPar ) group.add_argument( - "--reply", help="Reply to received messages", action="store_true" + "--reply", + help="Reply to received messages on the channel they were received. " + "If '--ch-index' is set, only messages on that channel are replied to.", + action="store_true", ) return parser @@ -1904,10 +1956,18 @@ def addRemoteAdminArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentPars group.add_argument( "--reboot-ota", - help="Tell the destination node to reboot into factory firmware (ESP32)", + help="Tell the destination node to reboot into factory firmware (ESP32, firmware version <2.7.18)", action="store_true", ) + group.add_argument( + "--ota-update", + help="Perform an OTA update on the local node (ESP32, firmware version >=2.7.18, WiFi/TCP only for now). " + "Specify the path to the firmware file.", + metavar="FIRMWARE_FILE", + action="store", + ) + group.add_argument( "--enter-dfu", help="Tell the destination node to enter DFU mode (NRF52)", diff --git a/meshtastic/mesh_interface.py b/meshtastic/mesh_interface.py index 20e43b9..5dfb393 100644 --- a/meshtastic/mesh_interface.py +++ b/meshtastic/mesh_interface.py @@ -419,6 +419,7 @@ class MeshInterface: # pylint: disable=R0902 channelIndex: int = 0, portNum: portnums_pb2.PortNum.ValueType = portnums_pb2.PortNum.TEXT_MESSAGE_APP, replyId: Optional[int]=None, + hopLimit: Optional[int]=None, ): """Send a utf8 string to some other node, if the node has a display it will also be shown on the device. @@ -436,6 +437,7 @@ class MeshInterface: # pylint: disable=R0902 portNum -- the application portnum (similar to IP port numbers) of the destination, see portnums.proto for a list replyId -- the ID of the message that this packet is a response to + hopLimit {int} -- hop limit to use Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks. @@ -449,7 +451,8 @@ class MeshInterface: # pylint: disable=R0902 wantResponse=wantResponse, onResponse=onResponse, channelIndex=channelIndex, - replyId=replyId + replyId=replyId, + hopLimit=hopLimit, ) @@ -459,6 +462,7 @@ class MeshInterface: # pylint: disable=R0902 destinationId: Union[int, str] = BROADCAST_ADDR, onResponse: Optional[Callable[[dict], Any]] = None, channelIndex: int = 0, + hopLimit: Optional[int]=None, ): """Send an alert text to some other node. This is similar to a text message, but carries a higher priority and is capable of generating special notifications @@ -470,6 +474,7 @@ class MeshInterface: # pylint: disable=R0902 Keyword Arguments: destinationId {nodeId or nodeNum} -- where to send this message (default: {BROADCAST_ADDR}) + hopLimit {int} -- hop limit to use Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks. @@ -483,7 +488,8 @@ class MeshInterface: # pylint: disable=R0902 wantResponse=False, onResponse=onResponse, channelIndex=channelIndex, - priority=mesh_pb2.MeshPacket.Priority.ALERT + priority=mesh_pb2.MeshPacket.Priority.ALERT, + hopLimit=hopLimit, ) def sendMqttClientProxyMessage(self, topic: str, data: bytes): @@ -585,6 +591,7 @@ class MeshInterface: # pylint: disable=R0902 wantAck: bool = False, wantResponse: bool = False, channelIndex: int = 0, + hopLimit: Optional[int]=None, ): """ Send a position packet to some other node (normally a broadcast) @@ -621,6 +628,7 @@ class MeshInterface: # pylint: disable=R0902 wantResponse=wantResponse, onResponse=onResponse, channelIndex=channelIndex, + hopLimit=hopLimit, ) if wantResponse: self.waitForPosition() @@ -673,7 +681,8 @@ class MeshInterface: # pylint: disable=R0902 hopLimit=hopLimit, ) # extend timeout based on number of nodes, limit by configured hopLimit - waitFactor = min(len(self.nodes) - 1 if self.nodes else 0, hopLimit) + nodes_based_factor = (len(self.nodes) - 1) if self.nodes else (hopLimit + 1) + waitFactor = max(1, min(nodes_based_factor, hopLimit + 1)) self.waitForTraceRoute(waitFactor) def onResponseTraceRoute(self, p: dict): @@ -726,7 +735,8 @@ class MeshInterface: # pylint: disable=R0902 destinationId: Union[int, str] = BROADCAST_ADDR, wantResponse: bool = False, channelIndex: int = 0, - telemetryType: str = "device_metrics" + telemetryType: str = "device_metrics", + hopLimit: Optional[int]=None, ): """Send telemetry and optionally ask for a response""" r = telemetry_pb2.Telemetry() @@ -773,6 +783,7 @@ class MeshInterface: # pylint: disable=R0902 wantResponse=wantResponse, onResponse=onResponse, channelIndex=channelIndex, + hopLimit=hopLimit, ) if wantResponse: self.waitForTelemetry() @@ -842,6 +853,7 @@ class MeshInterface: # pylint: disable=R0902 wantAck: bool = True, wantResponse: bool = False, channelIndex: int = 0, + hopLimit: Optional[int]=None, ): # pylint: disable=R0913 """ Send a waypoint packet to some other node (normally a broadcast) @@ -882,6 +894,7 @@ class MeshInterface: # pylint: disable=R0902 wantResponse=wantResponse, onResponse=onResponse, channelIndex=channelIndex, + hopLimit=hopLimit, ) if wantResponse: self.waitForWaypoint() @@ -894,6 +907,7 @@ class MeshInterface: # pylint: disable=R0902 wantAck: bool = True, wantResponse: bool = False, channelIndex: int = 0, + hopLimit: Optional[int]=None, ): """ Send a waypoint deletion packet to some other node (normally a broadcast) @@ -920,6 +934,7 @@ class MeshInterface: # pylint: disable=R0902 wantResponse=wantResponse, onResponse=onResponse, channelIndex=channelIndex, + hopLimit=hopLimit, ) if wantResponse: self.waitForWaypoint() @@ -1455,6 +1470,10 @@ class MeshInterface: # pylint: disable=R0902 self.localNode.moduleConfig.paxcounter.CopyFrom( fromRadio.moduleConfig.paxcounter ) + elif fromRadio.moduleConfig.HasField("traffic_management"): + self.localNode.moduleConfig.traffic_management.CopyFrom( + fromRadio.moduleConfig.traffic_management + ) else: logger.debug("Unexpected FromRadio payload") diff --git a/meshtastic/node.py b/meshtastic/node.py index afb5611..b18eff0 100644 --- a/meshtastic/node.py +++ b/meshtastic/node.py @@ -170,11 +170,10 @@ class Node: p.get_config_request = configType else: - msgIndex = configType.index if configType.containing_type.name == "LocalConfig": - p.get_config_request = msgIndex + p.get_config_request = admin_pb2.AdminMessage.ConfigType.Value(configType.name.upper() + "_CONFIG") else: - p.get_module_config_request = msgIndex + p.get_module_config_request = configType.index self._sendAdmin(p, wantResponse=True, onResponse=onResponse) if onResponse: @@ -245,6 +244,8 @@ class Node: p.set_module_config.ambient_lighting.CopyFrom(self.moduleConfig.ambient_lighting) elif config_name == "paxcounter": p.set_module_config.paxcounter.CopyFrom(self.moduleConfig.paxcounter) + elif config_name == "traffic_management": + p.set_module_config.traffic_management.CopyFrom(self.moduleConfig.traffic_management) else: our_exit(f"Error: No valid config with name {config_name}") @@ -654,7 +655,7 @@ class Node: return self._sendAdmin(p, onResponse=onResponse) def rebootOTA(self, secs: int = 10): - """Tell the node to reboot into factory firmware.""" + """Tell the node to reboot into factory firmware (firmware < 2.7.18).""" self.ensureSessionKey() p = admin_pb2.AdminMessage() p.reboot_ota_seconds = secs @@ -667,6 +668,22 @@ class Node: onResponse = self.onAckNak return self._sendAdmin(p, onResponse=onResponse) + def startOTA( + self, + ota_mode: admin_pb2.OTAMode.ValueType, + ota_file_hash: bytes, + ): + """Tell the node to start OTA mode (firmware >= 2.7.18).""" + if self != self.iface.localNode: + raise ValueError("startOTA only possible in local node") + + self.ensureSessionKey() + p = admin_pb2.AdminMessage() + p.ota_request.reboot_ota_mode = ota_mode + p.ota_request.ota_hash = ota_file_hash + + return self._sendAdmin(p) + def enterDFUMode(self): """Tell the node to enter DFU mode (NRF52).""" self.ensureSessionKey() @@ -711,10 +728,10 @@ class Node: self.ensureSessionKey() p = admin_pb2.AdminMessage() if full: - p.factory_reset_device = True + p.factory_reset_device = 1 logger.info(f"Telling node to factory reset (full device reset)") else: - p.factory_reset_config = True + p.factory_reset_config = 1 logger.info(f"Telling node to factory reset (config reset)") # If sending to a remote node, wait for ACK/NAK diff --git a/meshtastic/ota.py b/meshtastic/ota.py new file mode 100644 index 0000000..af9feae --- /dev/null +++ b/meshtastic/ota.py @@ -0,0 +1,128 @@ +"""Meshtastic ESP32 Unified OTA +""" +import os +import hashlib +import socket +import logging +from typing import Optional, Callable + + +logger = logging.getLogger(__name__) + + +def _file_sha256(filename: str): + """Calculate SHA256 hash of a file.""" + sha256_hash = hashlib.sha256() + + with open(filename, "rb") as f: + for byte_block in iter(lambda: f.read(4096), b""): + sha256_hash.update(byte_block) + + return sha256_hash + + +class OTAError(Exception): + """Exception for OTA errors.""" + + +class ESP32WiFiOTA: + """ESP32 WiFi Unified OTA updates.""" + + def __init__(self, filename: str, hostname: str, port: int = 3232): + self._filename = filename + self._hostname = hostname + self._port = port + self._socket: Optional[socket.socket] = None + + if not os.path.exists(self._filename): + raise FileNotFoundError(f"File {self._filename} does not exist") + + self._file_hash = _file_sha256(self._filename) + + def _read_line(self) -> str: + """Read a line from the socket.""" + if not self._socket: + raise ConnectionError("Socket not connected") + + line = b"" + while not line.endswith(b"\n"): + char = self._socket.recv(1) + + if not char: + raise ConnectionError("Connection closed while waiting for response") + + line += char + + return line.decode("utf-8").strip() + + def hash_bytes(self) -> bytes: + """Return the hash as bytes.""" + return self._file_hash.digest() + + def hash_hex(self) -> str: + """Return the hash as a hex string.""" + return self._file_hash.hexdigest() + + def update(self, progress_callback: Optional[Callable[[int, int], None]] = None): + """Perform the OTA update.""" + with open(self._filename, "rb") as f: + data = f.read() + size = len(data) + + logger.info(f"Starting OTA update with {self._filename} ({size} bytes, hash {self.hash_hex()})") + + self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self._socket.settimeout(15) + try: + self._socket.connect((self._hostname, self._port)) + logger.debug(f"Connected to {self._hostname}:{self._port}") + + # Send start command + self._socket.sendall(f"OTA {size} {self.hash_hex()}\n".encode("utf-8")) + + # Wait for OK from the device + while True: + response = self._read_line() + if response == "OK": + break + + if response == "ERASING": + logger.info("Device is erasing flash...") + elif response.startswith("ERR "): + raise OTAError(f"Device reported error: {response}") + else: + logger.warning(f"Unexpected response: {response}") + + # Stream firmware + sent_bytes = 0 + chunk_size = 1024 + while sent_bytes < size: + chunk = data[sent_bytes : sent_bytes + chunk_size] + self._socket.sendall(chunk) + sent_bytes += len(chunk) + + if progress_callback: + progress_callback(sent_bytes, size) + else: + print(f"[{sent_bytes / size * 100:5.1f}%] Sent {sent_bytes} of {size} bytes...", end="\r") + + if not progress_callback: + print() + + # Wait for OK from device + logger.info("Firmware sent, waiting for verification...") + while True: + response = self._read_line() + if response == "OK": + logger.info("OTA update completed successfully!") + break + + if response.startswith("ERR "): + raise OTAError(f"OTA update failed: {response}") + elif response != "ACK": + logger.warning(f"Unexpected final response: {response}") + + finally: + if self._socket: + self._socket.close() + self._socket = None diff --git a/meshtastic/protobuf/admin_pb2.py b/meshtastic/protobuf/admin_pb2.py index a4fa81e..7f82d0d 100644 --- a/meshtastic/protobuf/admin_pb2.py +++ b/meshtastic/protobuf/admin_pb2.py @@ -17,9 +17,10 @@ from meshtastic.protobuf import connection_status_pb2 as meshtastic_dot_protobuf from meshtastic.protobuf import device_ui_pb2 as meshtastic_dot_protobuf_dot_device__ui__pb2 from meshtastic.protobuf import mesh_pb2 as meshtastic_dot_protobuf_dot_mesh__pb2 from meshtastic.protobuf import module_config_pb2 as meshtastic_dot_protobuf_dot_module__config__pb2 +from meshtastic.protobuf import nanopb_pb2 as meshtastic_dot_protobuf_dot_nanopb__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmeshtastic/protobuf/admin.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a+meshtastic/protobuf/connection_status.proto\x1a#meshtastic/protobuf/device_ui.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a\'meshtastic/protobuf/module_config.proto\"\xf8\x1b\n\x0c\x41\x64minMessage\x12\x17\n\x0fsession_passkey\x18\x65 \x01(\x0c\x12\x1d\n\x13get_channel_request\x18\x01 \x01(\rH\x00\x12<\n\x14get_channel_response\x18\x02 \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x1b\n\x11get_owner_request\x18\x03 \x01(\x08H\x00\x12\x37\n\x12get_owner_response\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12J\n\x12get_config_request\x18\x05 \x01(\x0e\x32,.meshtastic.protobuf.AdminMessage.ConfigTypeH\x00\x12:\n\x13get_config_response\x18\x06 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12W\n\x19get_module_config_request\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.AdminMessage.ModuleConfigTypeH\x00\x12G\n\x1aget_module_config_response\x18\x08 \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12\x34\n*get_canned_message_module_messages_request\x18\n \x01(\x08H\x00\x12\x35\n+get_canned_message_module_messages_response\x18\x0b \x01(\tH\x00\x12%\n\x1bget_device_metadata_request\x18\x0c \x01(\x08H\x00\x12K\n\x1cget_device_metadata_response\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12\x1e\n\x14get_ringtone_request\x18\x0e \x01(\x08H\x00\x12\x1f\n\x15get_ringtone_response\x18\x0f \x01(\tH\x00\x12.\n$get_device_connection_status_request\x18\x10 \x01(\x08H\x00\x12\\\n%get_device_connection_status_response\x18\x11 \x01(\x0b\x32+.meshtastic.protobuf.DeviceConnectionStatusH\x00\x12:\n\x0cset_ham_mode\x18\x12 \x01(\x0b\x32\".meshtastic.protobuf.HamParametersH\x00\x12/\n%get_node_remote_hardware_pins_request\x18\x13 \x01(\x08H\x00\x12\x65\n&get_node_remote_hardware_pins_response\x18\x14 \x01(\x0b\x32\x33.meshtastic.protobuf.NodeRemoteHardwarePinsResponseH\x00\x12 \n\x16\x65nter_dfu_mode_request\x18\x15 \x01(\x08H\x00\x12\x1d\n\x13\x64\x65lete_file_request\x18\x16 \x01(\tH\x00\x12\x13\n\tset_scale\x18\x17 \x01(\rH\x00\x12N\n\x12\x62\x61\x63kup_preferences\x18\x18 \x01(\x0e\x32\x30.meshtastic.protobuf.AdminMessage.BackupLocationH\x00\x12O\n\x13restore_preferences\x18\x19 \x01(\x0e\x32\x30.meshtastic.protobuf.AdminMessage.BackupLocationH\x00\x12U\n\x19remove_backup_preferences\x18\x1a \x01(\x0e\x32\x30.meshtastic.protobuf.AdminMessage.BackupLocationH\x00\x12H\n\x10send_input_event\x18\x1b \x01(\x0b\x32,.meshtastic.protobuf.AdminMessage.InputEventH\x00\x12.\n\tset_owner\x18 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12\x33\n\x0bset_channel\x18! \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x31\n\nset_config\x18\" \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12>\n\x11set_module_config\x18# \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12,\n\"set_canned_message_module_messages\x18$ \x01(\tH\x00\x12\x1e\n\x14set_ringtone_message\x18% \x01(\tH\x00\x12\x1b\n\x11remove_by_nodenum\x18& \x01(\rH\x00\x12\x1b\n\x11set_favorite_node\x18\' \x01(\rH\x00\x12\x1e\n\x14remove_favorite_node\x18( \x01(\rH\x00\x12;\n\x12set_fixed_position\x18) \x01(\x0b\x32\x1d.meshtastic.protobuf.PositionH\x00\x12\x1f\n\x15remove_fixed_position\x18* \x01(\x08H\x00\x12\x17\n\rset_time_only\x18+ \x01(\x07H\x00\x12\x1f\n\x15get_ui_config_request\x18, \x01(\x08H\x00\x12\x45\n\x16get_ui_config_response\x18- \x01(\x0b\x32#.meshtastic.protobuf.DeviceUIConfigH\x00\x12>\n\x0fstore_ui_config\x18. \x01(\x0b\x32#.meshtastic.protobuf.DeviceUIConfigH\x00\x12\x1a\n\x10set_ignored_node\x18/ \x01(\rH\x00\x12\x1d\n\x13remove_ignored_node\x18\x30 \x01(\rH\x00\x12\x1b\n\x11toggle_muted_node\x18\x31 \x01(\rH\x00\x12\x1d\n\x13\x62\x65gin_edit_settings\x18@ \x01(\x08H\x00\x12\x1e\n\x14\x63ommit_edit_settings\x18\x41 \x01(\x08H\x00\x12\x39\n\x0b\x61\x64\x64_contact\x18\x42 \x01(\x0b\x32\".meshtastic.protobuf.SharedContactH\x00\x12\x45\n\x10key_verification\x18\x43 \x01(\x0b\x32).meshtastic.protobuf.KeyVerificationAdminH\x00\x12\x1e\n\x14\x66\x61\x63tory_reset_device\x18^ \x01(\x05H\x00\x12 \n\x12reboot_ota_seconds\x18_ \x01(\x05\x42\x02\x18\x01H\x00\x12\x18\n\x0e\x65xit_simulator\x18` \x01(\x08H\x00\x12\x18\n\x0ereboot_seconds\x18\x61 \x01(\x05H\x00\x12\x1a\n\x10shutdown_seconds\x18\x62 \x01(\x05H\x00\x12\x1e\n\x14\x66\x61\x63tory_reset_config\x18\x63 \x01(\x05H\x00\x12\x16\n\x0cnodedb_reset\x18\x64 \x01(\x08H\x00\x12\x41\n\x0bota_request\x18\x66 \x01(\x0b\x32*.meshtastic.protobuf.AdminMessage.OTAEventH\x00\x1aS\n\nInputEvent\x12\x12\n\nevent_code\x18\x01 \x01(\r\x12\x0f\n\x07kb_char\x18\x02 \x01(\r\x12\x0f\n\x07touch_x\x18\x03 \x01(\r\x12\x0f\n\x07touch_y\x18\x04 \x01(\r\x1aS\n\x08OTAEvent\x12\x35\n\x0freboot_ota_mode\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.OTAMode\x12\x10\n\x08ota_hash\x18\x02 \x01(\x0c\"\xd6\x01\n\nConfigType\x12\x11\n\rDEVICE_CONFIG\x10\x00\x12\x13\n\x0fPOSITION_CONFIG\x10\x01\x12\x10\n\x0cPOWER_CONFIG\x10\x02\x12\x12\n\x0eNETWORK_CONFIG\x10\x03\x12\x12\n\x0e\x44ISPLAY_CONFIG\x10\x04\x12\x0f\n\x0bLORA_CONFIG\x10\x05\x12\x14\n\x10\x42LUETOOTH_CONFIG\x10\x06\x12\x13\n\x0fSECURITY_CONFIG\x10\x07\x12\x15\n\x11SESSIONKEY_CONFIG\x10\x08\x12\x13\n\x0f\x44\x45VICEUI_CONFIG\x10\t\"\xd5\x02\n\x10ModuleConfigType\x12\x0f\n\x0bMQTT_CONFIG\x10\x00\x12\x11\n\rSERIAL_CONFIG\x10\x01\x12\x13\n\x0f\x45XTNOTIF_CONFIG\x10\x02\x12\x17\n\x13STOREFORWARD_CONFIG\x10\x03\x12\x14\n\x10RANGETEST_CONFIG\x10\x04\x12\x14\n\x10TELEMETRY_CONFIG\x10\x05\x12\x14\n\x10\x43\x41NNEDMSG_CONFIG\x10\x06\x12\x10\n\x0c\x41UDIO_CONFIG\x10\x07\x12\x19\n\x15REMOTEHARDWARE_CONFIG\x10\x08\x12\x17\n\x13NEIGHBORINFO_CONFIG\x10\t\x12\x1a\n\x16\x41MBIENTLIGHTING_CONFIG\x10\n\x12\x1a\n\x16\x44\x45TECTIONSENSOR_CONFIG\x10\x0b\x12\x15\n\x11PAXCOUNTER_CONFIG\x10\x0c\x12\x18\n\x14STATUSMESSAGE_CONFIG\x10\r\"#\n\x0e\x42\x61\x63kupLocation\x12\t\n\x05\x46LASH\x10\x00\x12\x06\n\x02SD\x10\x01\x42\x11\n\x0fpayload_variant\"[\n\rHamParameters\x12\x11\n\tcall_sign\x18\x01 \x01(\t\x12\x10\n\x08tx_power\x18\x02 \x01(\x05\x12\x11\n\tfrequency\x18\x03 \x01(\x02\x12\x12\n\nshort_name\x18\x04 \x01(\t\"o\n\x1eNodeRemoteHardwarePinsResponse\x12M\n\x19node_remote_hardware_pins\x18\x01 \x03(\x0b\x32*.meshtastic.protobuf.NodeRemoteHardwarePin\"|\n\rSharedContact\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12\x15\n\rshould_ignore\x18\x03 \x01(\x08\x12\x19\n\x11manually_verified\x18\x04 \x01(\x08\"\xa5\x02\n\x14KeyVerificationAdmin\x12K\n\x0cmessage_type\x18\x01 \x01(\x0e\x32\x35.meshtastic.protobuf.KeyVerificationAdmin.MessageType\x12\x16\n\x0eremote_nodenum\x18\x02 \x01(\r\x12\r\n\x05nonce\x18\x03 \x01(\x04\x12\x1c\n\x0fsecurity_number\x18\x04 \x01(\rH\x00\x88\x01\x01\"g\n\x0bMessageType\x12\x19\n\x15INITIATE_VERIFICATION\x10\x00\x12\x1b\n\x17PROVIDE_SECURITY_NUMBER\x10\x01\x12\r\n\tDO_VERIFY\x10\x02\x12\x11\n\rDO_NOT_VERIFY\x10\x03\x42\x12\n\x10_security_number*7\n\x07OTAMode\x12\x11\n\rNO_REBOOT_OTA\x10\x00\x12\x0b\n\x07OTA_BLE\x10\x01\x12\x0c\n\x08OTA_WIFI\x10\x02\x42\x61\n\x14org.meshtastic.protoB\x0b\x41\x64minProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmeshtastic/protobuf/admin.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a+meshtastic/protobuf/connection_status.proto\x1a#meshtastic/protobuf/device_ui.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a meshtastic/protobuf/nanopb.proto\"\xf0\x1d\n\x0c\x41\x64minMessage\x12\x1e\n\x0fsession_passkey\x18\x65 \x01(\x0c\x42\x05\x92?\x02\x08\x08\x12\x1d\n\x13get_channel_request\x18\x01 \x01(\rH\x00\x12<\n\x14get_channel_response\x18\x02 \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x1b\n\x11get_owner_request\x18\x03 \x01(\x08H\x00\x12\x37\n\x12get_owner_response\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12J\n\x12get_config_request\x18\x05 \x01(\x0e\x32,.meshtastic.protobuf.AdminMessage.ConfigTypeH\x00\x12:\n\x13get_config_response\x18\x06 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12W\n\x19get_module_config_request\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.AdminMessage.ModuleConfigTypeH\x00\x12G\n\x1aget_module_config_response\x18\x08 \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12\x34\n*get_canned_message_module_messages_request\x18\n \x01(\x08H\x00\x12=\n+get_canned_message_module_messages_response\x18\x0b \x01(\tB\x06\x92?\x03\x08\xc9\x01H\x00\x12%\n\x1bget_device_metadata_request\x18\x0c \x01(\x08H\x00\x12K\n\x1cget_device_metadata_response\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12\x1e\n\x14get_ringtone_request\x18\x0e \x01(\x08H\x00\x12\'\n\x15get_ringtone_response\x18\x0f \x01(\tB\x06\x92?\x03\x08\xe7\x01H\x00\x12.\n$get_device_connection_status_request\x18\x10 \x01(\x08H\x00\x12\\\n%get_device_connection_status_response\x18\x11 \x01(\x0b\x32+.meshtastic.protobuf.DeviceConnectionStatusH\x00\x12:\n\x0cset_ham_mode\x18\x12 \x01(\x0b\x32\".meshtastic.protobuf.HamParametersH\x00\x12/\n%get_node_remote_hardware_pins_request\x18\x13 \x01(\x08H\x00\x12\x65\n&get_node_remote_hardware_pins_response\x18\x14 \x01(\x0b\x32\x33.meshtastic.protobuf.NodeRemoteHardwarePinsResponseH\x00\x12 \n\x16\x65nter_dfu_mode_request\x18\x15 \x01(\x08H\x00\x12%\n\x13\x64\x65lete_file_request\x18\x16 \x01(\tB\x06\x92?\x03\x08\xc9\x01H\x00\x12\x13\n\tset_scale\x18\x17 \x01(\rH\x00\x12N\n\x12\x62\x61\x63kup_preferences\x18\x18 \x01(\x0e\x32\x30.meshtastic.protobuf.AdminMessage.BackupLocationH\x00\x12O\n\x13restore_preferences\x18\x19 \x01(\x0e\x32\x30.meshtastic.protobuf.AdminMessage.BackupLocationH\x00\x12U\n\x19remove_backup_preferences\x18\x1a \x01(\x0e\x32\x30.meshtastic.protobuf.AdminMessage.BackupLocationH\x00\x12H\n\x10send_input_event\x18\x1b \x01(\x0b\x32,.meshtastic.protobuf.AdminMessage.InputEventH\x00\x12.\n\tset_owner\x18 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12\x33\n\x0bset_channel\x18! \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x31\n\nset_config\x18\" \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12>\n\x11set_module_config\x18# \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12\x34\n\"set_canned_message_module_messages\x18$ \x01(\tB\x06\x92?\x03\x08\xc9\x01H\x00\x12&\n\x14set_ringtone_message\x18% \x01(\tB\x06\x92?\x03\x08\xe7\x01H\x00\x12\x1b\n\x11remove_by_nodenum\x18& \x01(\rH\x00\x12\x1b\n\x11set_favorite_node\x18\' \x01(\rH\x00\x12\x1e\n\x14remove_favorite_node\x18( \x01(\rH\x00\x12;\n\x12set_fixed_position\x18) \x01(\x0b\x32\x1d.meshtastic.protobuf.PositionH\x00\x12\x1f\n\x15remove_fixed_position\x18* \x01(\x08H\x00\x12\x17\n\rset_time_only\x18+ \x01(\x07H\x00\x12\x1f\n\x15get_ui_config_request\x18, \x01(\x08H\x00\x12\x45\n\x16get_ui_config_response\x18- \x01(\x0b\x32#.meshtastic.protobuf.DeviceUIConfigH\x00\x12>\n\x0fstore_ui_config\x18. \x01(\x0b\x32#.meshtastic.protobuf.DeviceUIConfigH\x00\x12\x1a\n\x10set_ignored_node\x18/ \x01(\rH\x00\x12\x1d\n\x13remove_ignored_node\x18\x30 \x01(\rH\x00\x12\x1b\n\x11toggle_muted_node\x18\x31 \x01(\rH\x00\x12\x1d\n\x13\x62\x65gin_edit_settings\x18@ \x01(\x08H\x00\x12\x1e\n\x14\x63ommit_edit_settings\x18\x41 \x01(\x08H\x00\x12\x39\n\x0b\x61\x64\x64_contact\x18\x42 \x01(\x0b\x32\".meshtastic.protobuf.SharedContactH\x00\x12\x45\n\x10key_verification\x18\x43 \x01(\x0b\x32).meshtastic.protobuf.KeyVerificationAdminH\x00\x12\x1e\n\x14\x66\x61\x63tory_reset_device\x18^ \x01(\x05H\x00\x12 \n\x12reboot_ota_seconds\x18_ \x01(\x05\x42\x02\x18\x01H\x00\x12\x18\n\x0e\x65xit_simulator\x18` \x01(\x08H\x00\x12\x18\n\x0ereboot_seconds\x18\x61 \x01(\x05H\x00\x12\x1a\n\x10shutdown_seconds\x18\x62 \x01(\x05H\x00\x12\x1e\n\x14\x66\x61\x63tory_reset_config\x18\x63 \x01(\x05H\x00\x12\x16\n\x0cnodedb_reset\x18\x64 \x01(\x08H\x00\x12\x41\n\x0bota_request\x18\x66 \x01(\x0b\x32*.meshtastic.protobuf.AdminMessage.OTAEventH\x00\x12:\n\rsensor_config\x18g \x01(\x0b\x32!.meshtastic.protobuf.SensorConfigH\x00\x12:\n\rlockdown_auth\x18h \x01(\x0b\x32!.meshtastic.protobuf.LockdownAuthH\x00\x1ao\n\nInputEvent\x12\x19\n\nevent_code\x18\x01 \x01(\rB\x05\x92?\x02\x38\x08\x12\x16\n\x07kb_char\x18\x02 \x01(\rB\x05\x92?\x02\x38\x08\x12\x16\n\x07touch_x\x18\x03 \x01(\rB\x05\x92?\x02\x38\x10\x12\x16\n\x07touch_y\x18\x04 \x01(\rB\x05\x92?\x02\x38\x10\x1aZ\n\x08OTAEvent\x12\x35\n\x0freboot_ota_mode\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.OTAMode\x12\x17\n\x08ota_hash\x18\x02 \x01(\x0c\x42\x05\x92?\x02\x08 \"\xd6\x01\n\nConfigType\x12\x11\n\rDEVICE_CONFIG\x10\x00\x12\x13\n\x0fPOSITION_CONFIG\x10\x01\x12\x10\n\x0cPOWER_CONFIG\x10\x02\x12\x12\n\x0eNETWORK_CONFIG\x10\x03\x12\x12\n\x0e\x44ISPLAY_CONFIG\x10\x04\x12\x0f\n\x0bLORA_CONFIG\x10\x05\x12\x14\n\x10\x42LUETOOTH_CONFIG\x10\x06\x12\x13\n\x0fSECURITY_CONFIG\x10\x07\x12\x15\n\x11SESSIONKEY_CONFIG\x10\x08\x12\x13\n\x0f\x44\x45VICEUI_CONFIG\x10\t\"\x83\x03\n\x10ModuleConfigType\x12\x0f\n\x0bMQTT_CONFIG\x10\x00\x12\x11\n\rSERIAL_CONFIG\x10\x01\x12\x13\n\x0f\x45XTNOTIF_CONFIG\x10\x02\x12\x17\n\x13STOREFORWARD_CONFIG\x10\x03\x12\x14\n\x10RANGETEST_CONFIG\x10\x04\x12\x14\n\x10TELEMETRY_CONFIG\x10\x05\x12\x14\n\x10\x43\x41NNEDMSG_CONFIG\x10\x06\x12\x10\n\x0c\x41UDIO_CONFIG\x10\x07\x12\x19\n\x15REMOTEHARDWARE_CONFIG\x10\x08\x12\x17\n\x13NEIGHBORINFO_CONFIG\x10\t\x12\x1a\n\x16\x41MBIENTLIGHTING_CONFIG\x10\n\x12\x1a\n\x16\x44\x45TECTIONSENSOR_CONFIG\x10\x0b\x12\x15\n\x11PAXCOUNTER_CONFIG\x10\x0c\x12\x18\n\x14STATUSMESSAGE_CONFIG\x10\r\x12\x1c\n\x18TRAFFICMANAGEMENT_CONFIG\x10\x0e\x12\x0e\n\nTAK_CONFIG\x10\x0f\"#\n\x0e\x42\x61\x63kupLocation\x12\t\n\x05\x46LASH\x10\x00\x12\x06\n\x02SD\x10\x01\x42\x11\n\x0fpayload_variant\"o\n\x0cLockdownAuth\x12\x19\n\npassphrase\x18\x01 \x01(\x0c\x42\x05\x92?\x02\x08 \x12\x17\n\x0f\x62oots_remaining\x18\x02 \x01(\r\x12\x19\n\x11valid_until_epoch\x18\x03 \x01(\r\x12\x10\n\x08lock_now\x18\x04 \x01(\x08\"i\n\rHamParameters\x12\x18\n\tcall_sign\x18\x01 \x01(\tB\x05\x92?\x02\x08\x08\x12\x10\n\x08tx_power\x18\x02 \x01(\x05\x12\x11\n\tfrequency\x18\x03 \x01(\x02\x12\x19\n\nshort_name\x18\x04 \x01(\tB\x05\x92?\x02\x08\x05\"v\n\x1eNodeRemoteHardwarePinsResponse\x12T\n\x19node_remote_hardware_pins\x18\x01 \x03(\x0b\x32*.meshtastic.protobuf.NodeRemoteHardwarePinB\x05\x92?\x02\x10\x10\"|\n\rSharedContact\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12\x15\n\rshould_ignore\x18\x03 \x01(\x08\x12\x19\n\x11manually_verified\x18\x04 \x01(\x08\"\xa5\x02\n\x14KeyVerificationAdmin\x12K\n\x0cmessage_type\x18\x01 \x01(\x0e\x32\x35.meshtastic.protobuf.KeyVerificationAdmin.MessageType\x12\x16\n\x0eremote_nodenum\x18\x02 \x01(\r\x12\r\n\x05nonce\x18\x03 \x01(\x04\x12\x1c\n\x0fsecurity_number\x18\x04 \x01(\rH\x00\x88\x01\x01\"g\n\x0bMessageType\x12\x19\n\x15INITIATE_VERIFICATION\x10\x00\x12\x1b\n\x17PROVIDE_SECURITY_NUMBER\x10\x01\x12\r\n\tDO_VERIFY\x10\x02\x12\x11\n\rDO_NOT_VERIFY\x10\x03\x42\x12\n\x10_security_number\"\xf2\x01\n\x0cSensorConfig\x12\x37\n\x0cscd4x_config\x18\x01 \x01(\x0b\x32!.meshtastic.protobuf.SCD4X_config\x12\x37\n\x0csen5x_config\x18\x02 \x01(\x0b\x32!.meshtastic.protobuf.SEN5X_config\x12\x37\n\x0cscd30_config\x18\x03 \x01(\x0b\x32!.meshtastic.protobuf.SCD30_config\x12\x37\n\x0cshtxx_config\x18\x04 \x01(\x0b\x32!.meshtastic.protobuf.SHTXX_config\"\xe2\x02\n\x0cSCD4X_config\x12\x14\n\x07set_asc\x18\x01 \x01(\x08H\x00\x88\x01\x01\x12 \n\x13set_target_co2_conc\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x1c\n\x0fset_temperature\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x19\n\x0cset_altitude\x18\x04 \x01(\rH\x03\x88\x01\x01\x12!\n\x14set_ambient_pressure\x18\x05 \x01(\rH\x04\x88\x01\x01\x12\x1a\n\rfactory_reset\x18\x06 \x01(\x08H\x05\x88\x01\x01\x12\x1b\n\x0eset_power_mode\x18\x07 \x01(\x08H\x06\x88\x01\x01\x42\n\n\x08_set_ascB\x16\n\x14_set_target_co2_concB\x12\n\x10_set_temperatureB\x0f\n\r_set_altitudeB\x17\n\x15_set_ambient_pressureB\x10\n\x0e_factory_resetB\x11\n\x0f_set_power_mode\"v\n\x0cSEN5X_config\x12\x1c\n\x0fset_temperature\x18\x01 \x01(\x02H\x00\x88\x01\x01\x12\x1e\n\x11set_one_shot_mode\x18\x02 \x01(\x08H\x01\x88\x01\x01\x42\x12\n\x10_set_temperatureB\x14\n\x12_set_one_shot_mode\"\xb4\x02\n\x0cSCD30_config\x12\x14\n\x07set_asc\x18\x01 \x01(\x08H\x00\x88\x01\x01\x12 \n\x13set_target_co2_conc\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x1c\n\x0fset_temperature\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x19\n\x0cset_altitude\x18\x04 \x01(\rH\x03\x88\x01\x01\x12%\n\x18set_measurement_interval\x18\x05 \x01(\rH\x04\x88\x01\x01\x12\x17\n\nsoft_reset\x18\x06 \x01(\x08H\x05\x88\x01\x01\x42\n\n\x08_set_ascB\x16\n\x14_set_target_co2_concB\x12\n\x10_set_temperatureB\x0f\n\r_set_altitudeB\x1b\n\x19_set_measurement_intervalB\r\n\x0b_soft_reset\":\n\x0cSHTXX_config\x12\x19\n\x0cset_accuracy\x18\x01 \x01(\rH\x00\x88\x01\x01\x42\x0f\n\r_set_accuracy*7\n\x07OTAMode\x12\x11\n\rNO_REBOOT_OTA\x10\x00\x12\x0b\n\x07OTA_BLE\x10\x01\x12\x0c\n\x08OTA_WIFI\x10\x02\x42\x61\n\x14org.meshtastic.protoB\x0b\x41\x64minProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -27,30 +28,72 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.admin_p if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\013AdminProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' + _ADMINMESSAGE_INPUTEVENT.fields_by_name['event_code']._options = None + _ADMINMESSAGE_INPUTEVENT.fields_by_name['event_code']._serialized_options = b'\222?\0028\010' + _ADMINMESSAGE_INPUTEVENT.fields_by_name['kb_char']._options = None + _ADMINMESSAGE_INPUTEVENT.fields_by_name['kb_char']._serialized_options = b'\222?\0028\010' + _ADMINMESSAGE_INPUTEVENT.fields_by_name['touch_x']._options = None + _ADMINMESSAGE_INPUTEVENT.fields_by_name['touch_x']._serialized_options = b'\222?\0028\020' + _ADMINMESSAGE_INPUTEVENT.fields_by_name['touch_y']._options = None + _ADMINMESSAGE_INPUTEVENT.fields_by_name['touch_y']._serialized_options = b'\222?\0028\020' + _ADMINMESSAGE_OTAEVENT.fields_by_name['ota_hash']._options = None + _ADMINMESSAGE_OTAEVENT.fields_by_name['ota_hash']._serialized_options = b'\222?\002\010 ' + _ADMINMESSAGE.fields_by_name['session_passkey']._options = None + _ADMINMESSAGE.fields_by_name['session_passkey']._serialized_options = b'\222?\002\010\010' + _ADMINMESSAGE.fields_by_name['get_canned_message_module_messages_response']._options = None + _ADMINMESSAGE.fields_by_name['get_canned_message_module_messages_response']._serialized_options = b'\222?\003\010\311\001' + _ADMINMESSAGE.fields_by_name['get_ringtone_response']._options = None + _ADMINMESSAGE.fields_by_name['get_ringtone_response']._serialized_options = b'\222?\003\010\347\001' + _ADMINMESSAGE.fields_by_name['delete_file_request']._options = None + _ADMINMESSAGE.fields_by_name['delete_file_request']._serialized_options = b'\222?\003\010\311\001' + _ADMINMESSAGE.fields_by_name['set_canned_message_module_messages']._options = None + _ADMINMESSAGE.fields_by_name['set_canned_message_module_messages']._serialized_options = b'\222?\003\010\311\001' + _ADMINMESSAGE.fields_by_name['set_ringtone_message']._options = None + _ADMINMESSAGE.fields_by_name['set_ringtone_message']._serialized_options = b'\222?\003\010\347\001' _ADMINMESSAGE.fields_by_name['reboot_ota_seconds']._options = None _ADMINMESSAGE.fields_by_name['reboot_ota_seconds']._serialized_options = b'\030\001' - _globals['_OTAMODE']._serialized_start=4487 - _globals['_OTAMODE']._serialized_end=4542 - _globals['_ADMINMESSAGE']._serialized_start=281 - _globals['_ADMINMESSAGE']._serialized_end=3857 - _globals['_ADMINMESSAGE_INPUTEVENT']._serialized_start=3072 - _globals['_ADMINMESSAGE_INPUTEVENT']._serialized_end=3155 - _globals['_ADMINMESSAGE_OTAEVENT']._serialized_start=3157 - _globals['_ADMINMESSAGE_OTAEVENT']._serialized_end=3240 - _globals['_ADMINMESSAGE_CONFIGTYPE']._serialized_start=3243 - _globals['_ADMINMESSAGE_CONFIGTYPE']._serialized_end=3457 - _globals['_ADMINMESSAGE_MODULECONFIGTYPE']._serialized_start=3460 - _globals['_ADMINMESSAGE_MODULECONFIGTYPE']._serialized_end=3801 - _globals['_ADMINMESSAGE_BACKUPLOCATION']._serialized_start=3803 - _globals['_ADMINMESSAGE_BACKUPLOCATION']._serialized_end=3838 - _globals['_HAMPARAMETERS']._serialized_start=3859 - _globals['_HAMPARAMETERS']._serialized_end=3950 - _globals['_NODEREMOTEHARDWAREPINSRESPONSE']._serialized_start=3952 - _globals['_NODEREMOTEHARDWAREPINSRESPONSE']._serialized_end=4063 - _globals['_SHAREDCONTACT']._serialized_start=4065 - _globals['_SHAREDCONTACT']._serialized_end=4189 - _globals['_KEYVERIFICATIONADMIN']._serialized_start=4192 - _globals['_KEYVERIFICATIONADMIN']._serialized_end=4485 - _globals['_KEYVERIFICATIONADMIN_MESSAGETYPE']._serialized_start=4362 - _globals['_KEYVERIFICATIONADMIN_MESSAGETYPE']._serialized_end=4465 + _LOCKDOWNAUTH.fields_by_name['passphrase']._options = None + _LOCKDOWNAUTH.fields_by_name['passphrase']._serialized_options = b'\222?\002\010 ' + _HAMPARAMETERS.fields_by_name['call_sign']._options = None + _HAMPARAMETERS.fields_by_name['call_sign']._serialized_options = b'\222?\002\010\010' + _HAMPARAMETERS.fields_by_name['short_name']._options = None + _HAMPARAMETERS.fields_by_name['short_name']._serialized_options = b'\222?\002\010\005' + _NODEREMOTEHARDWAREPINSRESPONSE.fields_by_name['node_remote_hardware_pins']._options = None + _NODEREMOTEHARDWAREPINSRESPONSE.fields_by_name['node_remote_hardware_pins']._serialized_options = b'\222?\002\020\020' + _globals['_OTAMODE']._serialized_start=5996 + _globals['_OTAMODE']._serialized_end=6051 + _globals['_ADMINMESSAGE']._serialized_start=315 + _globals['_ADMINMESSAGE']._serialized_end=4139 + _globals['_ADMINMESSAGE_INPUTEVENT']._serialized_start=3273 + _globals['_ADMINMESSAGE_INPUTEVENT']._serialized_end=3384 + _globals['_ADMINMESSAGE_OTAEVENT']._serialized_start=3386 + _globals['_ADMINMESSAGE_OTAEVENT']._serialized_end=3476 + _globals['_ADMINMESSAGE_CONFIGTYPE']._serialized_start=3479 + _globals['_ADMINMESSAGE_CONFIGTYPE']._serialized_end=3693 + _globals['_ADMINMESSAGE_MODULECONFIGTYPE']._serialized_start=3696 + _globals['_ADMINMESSAGE_MODULECONFIGTYPE']._serialized_end=4083 + _globals['_ADMINMESSAGE_BACKUPLOCATION']._serialized_start=4085 + _globals['_ADMINMESSAGE_BACKUPLOCATION']._serialized_end=4120 + _globals['_LOCKDOWNAUTH']._serialized_start=4141 + _globals['_LOCKDOWNAUTH']._serialized_end=4252 + _globals['_HAMPARAMETERS']._serialized_start=4254 + _globals['_HAMPARAMETERS']._serialized_end=4359 + _globals['_NODEREMOTEHARDWAREPINSRESPONSE']._serialized_start=4361 + _globals['_NODEREMOTEHARDWAREPINSRESPONSE']._serialized_end=4479 + _globals['_SHAREDCONTACT']._serialized_start=4481 + _globals['_SHAREDCONTACT']._serialized_end=4605 + _globals['_KEYVERIFICATIONADMIN']._serialized_start=4608 + _globals['_KEYVERIFICATIONADMIN']._serialized_end=4901 + _globals['_KEYVERIFICATIONADMIN_MESSAGETYPE']._serialized_start=4778 + _globals['_KEYVERIFICATIONADMIN_MESSAGETYPE']._serialized_end=4881 + _globals['_SENSORCONFIG']._serialized_start=4904 + _globals['_SENSORCONFIG']._serialized_end=5146 + _globals['_SCD4X_CONFIG']._serialized_start=5149 + _globals['_SCD4X_CONFIG']._serialized_end=5503 + _globals['_SEN5X_CONFIG']._serialized_start=5505 + _globals['_SEN5X_CONFIG']._serialized_end=5623 + _globals['_SCD30_CONFIG']._serialized_start=5626 + _globals['_SCD30_CONFIG']._serialized_end=5934 + _globals['_SHTXX_CONFIG']._serialized_start=5936 + _globals['_SHTXX_CONFIG']._serialized_end=5994 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/admin_pb2.pyi b/meshtastic/protobuf/admin_pb2.pyi index a930665..d7fb2c7 100644 --- a/meshtastic/protobuf/admin_pb2.pyi +++ b/meshtastic/protobuf/admin_pb2.pyi @@ -228,6 +228,14 @@ class AdminMessage(google.protobuf.message.Message): """ TODO: REPLACE """ + TRAFFICMANAGEMENT_CONFIG: AdminMessage._ModuleConfigType.ValueType # 14 + """ + Traffic management module config + """ + TAK_CONFIG: AdminMessage._ModuleConfigType.ValueType # 15 + """ + TAK module config + """ class ModuleConfigType(_ModuleConfigType, metaclass=_ModuleConfigTypeEnumTypeWrapper): """ @@ -290,6 +298,14 @@ class AdminMessage(google.protobuf.message.Message): """ TODO: REPLACE """ + TRAFFICMANAGEMENT_CONFIG: AdminMessage.ModuleConfigType.ValueType # 14 + """ + Traffic management module config + """ + TAK_CONFIG: AdminMessage.ModuleConfigType.ValueType # 15 + """ + TAK module config + """ class _BackupLocation: ValueType = typing.NewType("ValueType", builtins.int) @@ -439,6 +455,8 @@ class AdminMessage(google.protobuf.message.Message): FACTORY_RESET_CONFIG_FIELD_NUMBER: builtins.int NODEDB_RESET_FIELD_NUMBER: builtins.int OTA_REQUEST_FIELD_NUMBER: builtins.int + SENSOR_CONFIG_FIELD_NUMBER: builtins.int + LOCKDOWN_AUTH_FIELD_NUMBER: builtins.int session_passkey: builtins.bytes """ The node generates this key and sends it with any get_x_response packets. @@ -720,6 +738,25 @@ class AdminMessage(google.protobuf.message.Message): Tell the node to reset into the OTA Loader """ + @property + def sensor_config(self) -> global___SensorConfig: + """ + Parameters and sensor configuration + """ + + @property + def lockdown_auth(self) -> global___LockdownAuth: + """ + Lockdown passphrase delivery / unlock / lock-now command for hardened + firmware builds (see MESHTASTIC_LOCKDOWN). Used to provision the + passphrase on first boot, unlock encrypted storage on subsequent + reboots, re-verify on already-unlocked devices to authorize a new + client connection, or immediately re-lock the device. + + Replaces the earlier scheme that repurposed SecurityConfig.private_key + to carry passphrase bytes; that hack is retired. + """ + def __init__( self, *, @@ -780,13 +817,77 @@ class AdminMessage(google.protobuf.message.Message): factory_reset_config: builtins.int = ..., nodedb_reset: builtins.bool = ..., ota_request: global___AdminMessage.OTAEvent | None = ..., + sensor_config: global___SensorConfig | None = ..., + lockdown_auth: global___LockdownAuth | None = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["add_contact", b"add_contact", "backup_preferences", b"backup_preferences", "begin_edit_settings", b"begin_edit_settings", "commit_edit_settings", b"commit_edit_settings", "delete_file_request", b"delete_file_request", "enter_dfu_mode_request", b"enter_dfu_mode_request", "exit_simulator", b"exit_simulator", "factory_reset_config", b"factory_reset_config", "factory_reset_device", b"factory_reset_device", "get_canned_message_module_messages_request", b"get_canned_message_module_messages_request", "get_canned_message_module_messages_response", b"get_canned_message_module_messages_response", "get_channel_request", b"get_channel_request", "get_channel_response", b"get_channel_response", "get_config_request", b"get_config_request", "get_config_response", b"get_config_response", "get_device_connection_status_request", b"get_device_connection_status_request", "get_device_connection_status_response", b"get_device_connection_status_response", "get_device_metadata_request", b"get_device_metadata_request", "get_device_metadata_response", b"get_device_metadata_response", "get_module_config_request", b"get_module_config_request", "get_module_config_response", b"get_module_config_response", "get_node_remote_hardware_pins_request", b"get_node_remote_hardware_pins_request", "get_node_remote_hardware_pins_response", b"get_node_remote_hardware_pins_response", "get_owner_request", b"get_owner_request", "get_owner_response", b"get_owner_response", "get_ringtone_request", b"get_ringtone_request", "get_ringtone_response", b"get_ringtone_response", "get_ui_config_request", b"get_ui_config_request", "get_ui_config_response", b"get_ui_config_response", "key_verification", b"key_verification", "nodedb_reset", b"nodedb_reset", "ota_request", b"ota_request", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_backup_preferences", b"remove_backup_preferences", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "remove_ignored_node", b"remove_ignored_node", "restore_preferences", b"restore_preferences", "send_input_event", b"send_input_event", "set_canned_message_module_messages", b"set_canned_message_module_messages", "set_channel", b"set_channel", "set_config", b"set_config", "set_favorite_node", b"set_favorite_node", "set_fixed_position", b"set_fixed_position", "set_ham_mode", b"set_ham_mode", "set_ignored_node", b"set_ignored_node", "set_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "set_scale", b"set_scale", "set_time_only", b"set_time_only", "shutdown_seconds", b"shutdown_seconds", "store_ui_config", b"store_ui_config", "toggle_muted_node", b"toggle_muted_node"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["add_contact", b"add_contact", "backup_preferences", b"backup_preferences", "begin_edit_settings", b"begin_edit_settings", "commit_edit_settings", b"commit_edit_settings", "delete_file_request", b"delete_file_request", "enter_dfu_mode_request", b"enter_dfu_mode_request", "exit_simulator", b"exit_simulator", "factory_reset_config", b"factory_reset_config", "factory_reset_device", b"factory_reset_device", "get_canned_message_module_messages_request", b"get_canned_message_module_messages_request", "get_canned_message_module_messages_response", b"get_canned_message_module_messages_response", "get_channel_request", b"get_channel_request", "get_channel_response", b"get_channel_response", "get_config_request", b"get_config_request", "get_config_response", b"get_config_response", "get_device_connection_status_request", b"get_device_connection_status_request", "get_device_connection_status_response", b"get_device_connection_status_response", "get_device_metadata_request", b"get_device_metadata_request", "get_device_metadata_response", b"get_device_metadata_response", "get_module_config_request", b"get_module_config_request", "get_module_config_response", b"get_module_config_response", "get_node_remote_hardware_pins_request", b"get_node_remote_hardware_pins_request", "get_node_remote_hardware_pins_response", b"get_node_remote_hardware_pins_response", "get_owner_request", b"get_owner_request", "get_owner_response", b"get_owner_response", "get_ringtone_request", b"get_ringtone_request", "get_ringtone_response", b"get_ringtone_response", "get_ui_config_request", b"get_ui_config_request", "get_ui_config_response", b"get_ui_config_response", "key_verification", b"key_verification", "nodedb_reset", b"nodedb_reset", "ota_request", b"ota_request", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_backup_preferences", b"remove_backup_preferences", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "remove_ignored_node", b"remove_ignored_node", "restore_preferences", b"restore_preferences", "send_input_event", b"send_input_event", "session_passkey", b"session_passkey", "set_canned_message_module_messages", b"set_canned_message_module_messages", "set_channel", b"set_channel", "set_config", b"set_config", "set_favorite_node", b"set_favorite_node", "set_fixed_position", b"set_fixed_position", "set_ham_mode", b"set_ham_mode", "set_ignored_node", b"set_ignored_node", "set_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "set_scale", b"set_scale", "set_time_only", b"set_time_only", "shutdown_seconds", b"shutdown_seconds", "store_ui_config", b"store_ui_config", "toggle_muted_node", b"toggle_muted_node"]) -> None: ... - def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["get_channel_request", "get_channel_response", "get_owner_request", "get_owner_response", "get_config_request", "get_config_response", "get_module_config_request", "get_module_config_response", "get_canned_message_module_messages_request", "get_canned_message_module_messages_response", "get_device_metadata_request", "get_device_metadata_response", "get_ringtone_request", "get_ringtone_response", "get_device_connection_status_request", "get_device_connection_status_response", "set_ham_mode", "get_node_remote_hardware_pins_request", "get_node_remote_hardware_pins_response", "enter_dfu_mode_request", "delete_file_request", "set_scale", "backup_preferences", "restore_preferences", "remove_backup_preferences", "send_input_event", "set_owner", "set_channel", "set_config", "set_module_config", "set_canned_message_module_messages", "set_ringtone_message", "remove_by_nodenum", "set_favorite_node", "remove_favorite_node", "set_fixed_position", "remove_fixed_position", "set_time_only", "get_ui_config_request", "get_ui_config_response", "store_ui_config", "set_ignored_node", "remove_ignored_node", "toggle_muted_node", "begin_edit_settings", "commit_edit_settings", "add_contact", "key_verification", "factory_reset_device", "reboot_ota_seconds", "exit_simulator", "reboot_seconds", "shutdown_seconds", "factory_reset_config", "nodedb_reset", "ota_request"] | None: ... + def HasField(self, field_name: typing.Literal["add_contact", b"add_contact", "backup_preferences", b"backup_preferences", "begin_edit_settings", b"begin_edit_settings", "commit_edit_settings", b"commit_edit_settings", "delete_file_request", b"delete_file_request", "enter_dfu_mode_request", b"enter_dfu_mode_request", "exit_simulator", b"exit_simulator", "factory_reset_config", b"factory_reset_config", "factory_reset_device", b"factory_reset_device", "get_canned_message_module_messages_request", b"get_canned_message_module_messages_request", "get_canned_message_module_messages_response", b"get_canned_message_module_messages_response", "get_channel_request", b"get_channel_request", "get_channel_response", b"get_channel_response", "get_config_request", b"get_config_request", "get_config_response", b"get_config_response", "get_device_connection_status_request", b"get_device_connection_status_request", "get_device_connection_status_response", b"get_device_connection_status_response", "get_device_metadata_request", b"get_device_metadata_request", "get_device_metadata_response", b"get_device_metadata_response", "get_module_config_request", b"get_module_config_request", "get_module_config_response", b"get_module_config_response", "get_node_remote_hardware_pins_request", b"get_node_remote_hardware_pins_request", "get_node_remote_hardware_pins_response", b"get_node_remote_hardware_pins_response", "get_owner_request", b"get_owner_request", "get_owner_response", b"get_owner_response", "get_ringtone_request", b"get_ringtone_request", "get_ringtone_response", b"get_ringtone_response", "get_ui_config_request", b"get_ui_config_request", "get_ui_config_response", b"get_ui_config_response", "key_verification", b"key_verification", "lockdown_auth", b"lockdown_auth", "nodedb_reset", b"nodedb_reset", "ota_request", b"ota_request", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_backup_preferences", b"remove_backup_preferences", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "remove_ignored_node", b"remove_ignored_node", "restore_preferences", b"restore_preferences", "send_input_event", b"send_input_event", "sensor_config", b"sensor_config", "set_canned_message_module_messages", b"set_canned_message_module_messages", "set_channel", b"set_channel", "set_config", b"set_config", "set_favorite_node", b"set_favorite_node", "set_fixed_position", b"set_fixed_position", "set_ham_mode", b"set_ham_mode", "set_ignored_node", b"set_ignored_node", "set_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "set_scale", b"set_scale", "set_time_only", b"set_time_only", "shutdown_seconds", b"shutdown_seconds", "store_ui_config", b"store_ui_config", "toggle_muted_node", b"toggle_muted_node"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["add_contact", b"add_contact", "backup_preferences", b"backup_preferences", "begin_edit_settings", b"begin_edit_settings", "commit_edit_settings", b"commit_edit_settings", "delete_file_request", b"delete_file_request", "enter_dfu_mode_request", b"enter_dfu_mode_request", "exit_simulator", b"exit_simulator", "factory_reset_config", b"factory_reset_config", "factory_reset_device", b"factory_reset_device", "get_canned_message_module_messages_request", b"get_canned_message_module_messages_request", "get_canned_message_module_messages_response", b"get_canned_message_module_messages_response", "get_channel_request", b"get_channel_request", "get_channel_response", b"get_channel_response", "get_config_request", b"get_config_request", "get_config_response", b"get_config_response", "get_device_connection_status_request", b"get_device_connection_status_request", "get_device_connection_status_response", b"get_device_connection_status_response", "get_device_metadata_request", b"get_device_metadata_request", "get_device_metadata_response", b"get_device_metadata_response", "get_module_config_request", b"get_module_config_request", "get_module_config_response", b"get_module_config_response", "get_node_remote_hardware_pins_request", b"get_node_remote_hardware_pins_request", "get_node_remote_hardware_pins_response", b"get_node_remote_hardware_pins_response", "get_owner_request", b"get_owner_request", "get_owner_response", b"get_owner_response", "get_ringtone_request", b"get_ringtone_request", "get_ringtone_response", b"get_ringtone_response", "get_ui_config_request", b"get_ui_config_request", "get_ui_config_response", b"get_ui_config_response", "key_verification", b"key_verification", "lockdown_auth", b"lockdown_auth", "nodedb_reset", b"nodedb_reset", "ota_request", b"ota_request", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_backup_preferences", b"remove_backup_preferences", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "remove_ignored_node", b"remove_ignored_node", "restore_preferences", b"restore_preferences", "send_input_event", b"send_input_event", "sensor_config", b"sensor_config", "session_passkey", b"session_passkey", "set_canned_message_module_messages", b"set_canned_message_module_messages", "set_channel", b"set_channel", "set_config", b"set_config", "set_favorite_node", b"set_favorite_node", "set_fixed_position", b"set_fixed_position", "set_ham_mode", b"set_ham_mode", "set_ignored_node", b"set_ignored_node", "set_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "set_scale", b"set_scale", "set_time_only", b"set_time_only", "shutdown_seconds", b"shutdown_seconds", "store_ui_config", b"store_ui_config", "toggle_muted_node", b"toggle_muted_node"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["get_channel_request", "get_channel_response", "get_owner_request", "get_owner_response", "get_config_request", "get_config_response", "get_module_config_request", "get_module_config_response", "get_canned_message_module_messages_request", "get_canned_message_module_messages_response", "get_device_metadata_request", "get_device_metadata_response", "get_ringtone_request", "get_ringtone_response", "get_device_connection_status_request", "get_device_connection_status_response", "set_ham_mode", "get_node_remote_hardware_pins_request", "get_node_remote_hardware_pins_response", "enter_dfu_mode_request", "delete_file_request", "set_scale", "backup_preferences", "restore_preferences", "remove_backup_preferences", "send_input_event", "set_owner", "set_channel", "set_config", "set_module_config", "set_canned_message_module_messages", "set_ringtone_message", "remove_by_nodenum", "set_favorite_node", "remove_favorite_node", "set_fixed_position", "remove_fixed_position", "set_time_only", "get_ui_config_request", "get_ui_config_response", "store_ui_config", "set_ignored_node", "remove_ignored_node", "toggle_muted_node", "begin_edit_settings", "commit_edit_settings", "add_contact", "key_verification", "factory_reset_device", "reboot_ota_seconds", "exit_simulator", "reboot_seconds", "shutdown_seconds", "factory_reset_config", "nodedb_reset", "ota_request", "sensor_config", "lockdown_auth"] | None: ... global___AdminMessage = AdminMessage +@typing.final +class LockdownAuth(google.protobuf.message.Message): + """ + Lockdown passphrase delivery payload. + + One message handles three operations distinguished by content: + - Provision (first-time): passphrase set, lock_now=false. Firmware + generates DEK, wraps with passphrase-derived KEK, persists. + - Unlock: passphrase set, lock_now=false. Firmware verifies + passphrase against stored DEK, unlocks storage, authorizes the + connection that delivered this packet. + - Lock now: lock_now=true, passphrase ignored. Firmware revokes + all client auth and reboots into the locked state. + + Firmware decides between provision and unlock based on its own state + (whether a DEK file already exists). Clients do not need to track + which case applies. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PASSPHRASE_FIELD_NUMBER: builtins.int + BOOTS_REMAINING_FIELD_NUMBER: builtins.int + VALID_UNTIL_EPOCH_FIELD_NUMBER: builtins.int + LOCK_NOW_FIELD_NUMBER: builtins.int + passphrase: builtins.bytes + """ + Passphrase bytes (1-32). Empty when lock_now is true. + Capped to 32 to match the proto cap on related security fields. + """ + boots_remaining: builtins.int + """ + Optional override of the boot-count token TTL granted on success. + 0 = use firmware default (TOKEN_DEFAULT_BOOTS). + On reboot the firmware decrements this; when it reaches 0 the + device boots fully locked and requires a fresh passphrase. + """ + valid_until_epoch: builtins.int + """ + Optional wall-clock expiry for the unlock token, as absolute + Unix-epoch seconds. 0 = no time limit (only the boot-count TTL + applies). On boot, if the device RTC is set and now > this value, + the token is treated as expired. + """ + lock_now: builtins.bool + """ + If true, ignore passphrase fields, immediately revoke all + connection-level admin authorization, and reboot the device into + the locked state. Always honoured regardless of current lock state. + """ + def __init__( + self, + *, + passphrase: builtins.bytes = ..., + boots_remaining: builtins.int = ..., + valid_until_epoch: builtins.int = ..., + lock_now: builtins.bool = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["boots_remaining", b"boots_remaining", "lock_now", b"lock_now", "passphrase", b"passphrase", "valid_until_epoch", b"valid_until_epoch"]) -> None: ... + +global___LockdownAuth = LockdownAuth + @typing.final class HamParameters(google.protobuf.message.Message): """ @@ -977,3 +1078,227 @@ class KeyVerificationAdmin(google.protobuf.message.Message): def WhichOneof(self, oneof_group: typing.Literal["_security_number", b"_security_number"]) -> typing.Literal["security_number"] | None: ... global___KeyVerificationAdmin = KeyVerificationAdmin + +@typing.final +class SensorConfig(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SCD4X_CONFIG_FIELD_NUMBER: builtins.int + SEN5X_CONFIG_FIELD_NUMBER: builtins.int + SCD30_CONFIG_FIELD_NUMBER: builtins.int + SHTXX_CONFIG_FIELD_NUMBER: builtins.int + @property + def scd4x_config(self) -> global___SCD4X_config: + """ + SCD4X CO2 Sensor configuration + """ + + @property + def sen5x_config(self) -> global___SEN5X_config: + """ + SEN5X PM Sensor configuration + """ + + @property + def scd30_config(self) -> global___SCD30_config: + """ + SCD30 CO2 Sensor configuration + """ + + @property + def shtxx_config(self) -> global___SHTXX_config: + """ + SHTXX temperature and relative humidity sensor configuration + """ + + def __init__( + self, + *, + scd4x_config: global___SCD4X_config | None = ..., + sen5x_config: global___SEN5X_config | None = ..., + scd30_config: global___SCD30_config | None = ..., + shtxx_config: global___SHTXX_config | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["scd30_config", b"scd30_config", "scd4x_config", b"scd4x_config", "sen5x_config", b"sen5x_config", "shtxx_config", b"shtxx_config"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["scd30_config", b"scd30_config", "scd4x_config", b"scd4x_config", "sen5x_config", b"sen5x_config", "shtxx_config", b"shtxx_config"]) -> None: ... + +global___SensorConfig = SensorConfig + +@typing.final +class SCD4X_config(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SET_ASC_FIELD_NUMBER: builtins.int + SET_TARGET_CO2_CONC_FIELD_NUMBER: builtins.int + SET_TEMPERATURE_FIELD_NUMBER: builtins.int + SET_ALTITUDE_FIELD_NUMBER: builtins.int + SET_AMBIENT_PRESSURE_FIELD_NUMBER: builtins.int + FACTORY_RESET_FIELD_NUMBER: builtins.int + SET_POWER_MODE_FIELD_NUMBER: builtins.int + set_asc: builtins.bool + """ + Set Automatic self-calibration enabled + """ + set_target_co2_conc: builtins.int + """ + Recalibration target CO2 concentration in ppm (FRC or ASC) + """ + set_temperature: builtins.float + """ + Reference temperature in degC + """ + set_altitude: builtins.int + """ + Altitude of sensor in meters above sea level. 0 - 3000m (overrides ambient pressure) + """ + set_ambient_pressure: builtins.int + """ + Sensor ambient pressure in Pa. 70000 - 120000 Pa (overrides altitude) + """ + factory_reset: builtins.bool + """ + Perform a factory reset of the sensor + """ + set_power_mode: builtins.bool + """ + Power mode for sensor (true for low power, false for normal) + """ + def __init__( + self, + *, + set_asc: builtins.bool | None = ..., + set_target_co2_conc: builtins.int | None = ..., + set_temperature: builtins.float | None = ..., + set_altitude: builtins.int | None = ..., + set_ambient_pressure: builtins.int | None = ..., + factory_reset: builtins.bool | None = ..., + set_power_mode: builtins.bool | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_factory_reset", b"_factory_reset", "_set_altitude", b"_set_altitude", "_set_ambient_pressure", b"_set_ambient_pressure", "_set_asc", b"_set_asc", "_set_power_mode", b"_set_power_mode", "_set_target_co2_conc", b"_set_target_co2_conc", "_set_temperature", b"_set_temperature", "factory_reset", b"factory_reset", "set_altitude", b"set_altitude", "set_ambient_pressure", b"set_ambient_pressure", "set_asc", b"set_asc", "set_power_mode", b"set_power_mode", "set_target_co2_conc", b"set_target_co2_conc", "set_temperature", b"set_temperature"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_factory_reset", b"_factory_reset", "_set_altitude", b"_set_altitude", "_set_ambient_pressure", b"_set_ambient_pressure", "_set_asc", b"_set_asc", "_set_power_mode", b"_set_power_mode", "_set_target_co2_conc", b"_set_target_co2_conc", "_set_temperature", b"_set_temperature", "factory_reset", b"factory_reset", "set_altitude", b"set_altitude", "set_ambient_pressure", b"set_ambient_pressure", "set_asc", b"set_asc", "set_power_mode", b"set_power_mode", "set_target_co2_conc", b"set_target_co2_conc", "set_temperature", b"set_temperature"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_factory_reset", b"_factory_reset"]) -> typing.Literal["factory_reset"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_set_altitude", b"_set_altitude"]) -> typing.Literal["set_altitude"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_set_ambient_pressure", b"_set_ambient_pressure"]) -> typing.Literal["set_ambient_pressure"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_set_asc", b"_set_asc"]) -> typing.Literal["set_asc"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_set_power_mode", b"_set_power_mode"]) -> typing.Literal["set_power_mode"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_set_target_co2_conc", b"_set_target_co2_conc"]) -> typing.Literal["set_target_co2_conc"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_set_temperature", b"_set_temperature"]) -> typing.Literal["set_temperature"] | None: ... + +global___SCD4X_config = SCD4X_config + +@typing.final +class SEN5X_config(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SET_TEMPERATURE_FIELD_NUMBER: builtins.int + SET_ONE_SHOT_MODE_FIELD_NUMBER: builtins.int + set_temperature: builtins.float + """ + Reference temperature in degC + """ + set_one_shot_mode: builtins.bool + """ + One-shot mode (true for low power - one-shot mode, false for normal - continuous mode) + """ + def __init__( + self, + *, + set_temperature: builtins.float | None = ..., + set_one_shot_mode: builtins.bool | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_set_one_shot_mode", b"_set_one_shot_mode", "_set_temperature", b"_set_temperature", "set_one_shot_mode", b"set_one_shot_mode", "set_temperature", b"set_temperature"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_set_one_shot_mode", b"_set_one_shot_mode", "_set_temperature", b"_set_temperature", "set_one_shot_mode", b"set_one_shot_mode", "set_temperature", b"set_temperature"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_set_one_shot_mode", b"_set_one_shot_mode"]) -> typing.Literal["set_one_shot_mode"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_set_temperature", b"_set_temperature"]) -> typing.Literal["set_temperature"] | None: ... + +global___SEN5X_config = SEN5X_config + +@typing.final +class SCD30_config(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SET_ASC_FIELD_NUMBER: builtins.int + SET_TARGET_CO2_CONC_FIELD_NUMBER: builtins.int + SET_TEMPERATURE_FIELD_NUMBER: builtins.int + SET_ALTITUDE_FIELD_NUMBER: builtins.int + SET_MEASUREMENT_INTERVAL_FIELD_NUMBER: builtins.int + SOFT_RESET_FIELD_NUMBER: builtins.int + set_asc: builtins.bool + """ + Set Automatic self-calibration enabled + """ + set_target_co2_conc: builtins.int + """ + Recalibration target CO2 concentration in ppm (FRC or ASC) + """ + set_temperature: builtins.float + """ + Reference temperature in degC + """ + set_altitude: builtins.int + """ + Altitude of sensor in meters above sea level. 0 - 3000m (overrides ambient pressure) + """ + set_measurement_interval: builtins.int + """ + Power mode for sensor (true for low power, false for normal) + """ + soft_reset: builtins.bool + """ + Perform a factory reset of the sensor + """ + def __init__( + self, + *, + set_asc: builtins.bool | None = ..., + set_target_co2_conc: builtins.int | None = ..., + set_temperature: builtins.float | None = ..., + set_altitude: builtins.int | None = ..., + set_measurement_interval: builtins.int | None = ..., + soft_reset: builtins.bool | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_set_altitude", b"_set_altitude", "_set_asc", b"_set_asc", "_set_measurement_interval", b"_set_measurement_interval", "_set_target_co2_conc", b"_set_target_co2_conc", "_set_temperature", b"_set_temperature", "_soft_reset", b"_soft_reset", "set_altitude", b"set_altitude", "set_asc", b"set_asc", "set_measurement_interval", b"set_measurement_interval", "set_target_co2_conc", b"set_target_co2_conc", "set_temperature", b"set_temperature", "soft_reset", b"soft_reset"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_set_altitude", b"_set_altitude", "_set_asc", b"_set_asc", "_set_measurement_interval", b"_set_measurement_interval", "_set_target_co2_conc", b"_set_target_co2_conc", "_set_temperature", b"_set_temperature", "_soft_reset", b"_soft_reset", "set_altitude", b"set_altitude", "set_asc", b"set_asc", "set_measurement_interval", b"set_measurement_interval", "set_target_co2_conc", b"set_target_co2_conc", "set_temperature", b"set_temperature", "soft_reset", b"soft_reset"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_set_altitude", b"_set_altitude"]) -> typing.Literal["set_altitude"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_set_asc", b"_set_asc"]) -> typing.Literal["set_asc"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_set_measurement_interval", b"_set_measurement_interval"]) -> typing.Literal["set_measurement_interval"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_set_target_co2_conc", b"_set_target_co2_conc"]) -> typing.Literal["set_target_co2_conc"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_set_temperature", b"_set_temperature"]) -> typing.Literal["set_temperature"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_soft_reset", b"_soft_reset"]) -> typing.Literal["soft_reset"] | None: ... + +global___SCD30_config = SCD30_config + +@typing.final +class SHTXX_config(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SET_ACCURACY_FIELD_NUMBER: builtins.int + set_accuracy: builtins.int + """ + Accuracy mode (0 = low, 1 = medium, 2 = high) + """ + def __init__( + self, + *, + set_accuracy: builtins.int | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_set_accuracy", b"_set_accuracy", "set_accuracy", b"set_accuracy"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_set_accuracy", b"_set_accuracy", "set_accuracy", b"set_accuracy"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_set_accuracy", b"_set_accuracy"]) -> typing.Literal["set_accuracy"] | None: ... + +global___SHTXX_config = SHTXX_config diff --git a/meshtastic/protobuf/apponly_pb2.py b/meshtastic/protobuf/apponly_pb2.py index 70e04e8..9f5d99f 100644 --- a/meshtastic/protobuf/apponly_pb2.py +++ b/meshtastic/protobuf/apponly_pb2.py @@ -13,9 +13,10 @@ _sym_db = _symbol_database.Default() from meshtastic.protobuf import channel_pb2 as meshtastic_dot_protobuf_dot_channel__pb2 from meshtastic.protobuf import config_pb2 as meshtastic_dot_protobuf_dot_config__pb2 +from meshtastic.protobuf import nanopb_pb2 as meshtastic_dot_protobuf_dot_nanopb__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!meshtastic/protobuf/apponly.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\"\x81\x01\n\nChannelSet\x12\x36\n\x08settings\x18\x01 \x03(\x0b\x32$.meshtastic.protobuf.ChannelSettings\x12;\n\x0blora_config\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfigBc\n\x14org.meshtastic.protoB\rAppOnlyProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!meshtastic/protobuf/apponly.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a meshtastic/protobuf/nanopb.proto\"\x88\x01\n\nChannelSet\x12=\n\x08settings\x18\x01 \x03(\x0b\x32$.meshtastic.protobuf.ChannelSettingsB\x05\x92?\x02\x10\x08\x12;\n\x0blora_config\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfigBc\n\x14org.meshtastic.protoB\rAppOnlyProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -23,6 +24,8 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.apponly if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\rAppOnlyProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _globals['_CHANNELSET']._serialized_start=128 - _globals['_CHANNELSET']._serialized_end=257 + _CHANNELSET.fields_by_name['settings']._options = None + _CHANNELSET.fields_by_name['settings']._serialized_options = b'\222?\002\020\010' + _globals['_CHANNELSET']._serialized_start=162 + _globals['_CHANNELSET']._serialized_end=298 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/atak_pb2.py b/meshtastic/protobuf/atak_pb2.py index b0fee1a..7f6edb5 100644 --- a/meshtastic/protobuf/atak_pb2.py +++ b/meshtastic/protobuf/atak_pb2.py @@ -11,9 +11,10 @@ from google.protobuf.internal import builder as _builder _sym_db = _symbol_database.Default() +from meshtastic.protobuf import nanopb_pb2 as meshtastic_dot_protobuf_dot_nanopb__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/atak.proto\x12\x13meshtastic.protobuf\"\xa5\x02\n\tTAKPacket\x12\x15\n\ris_compressed\x18\x01 \x01(\x08\x12-\n\x07\x63ontact\x18\x02 \x01(\x0b\x32\x1c.meshtastic.protobuf.Contact\x12)\n\x05group\x18\x03 \x01(\x0b\x32\x1a.meshtastic.protobuf.Group\x12+\n\x06status\x18\x04 \x01(\x0b\x32\x1b.meshtastic.protobuf.Status\x12\'\n\x03pli\x18\x05 \x01(\x0b\x32\x18.meshtastic.protobuf.PLIH\x00\x12,\n\x04\x63hat\x18\x06 \x01(\x0b\x32\x1c.meshtastic.protobuf.GeoChatH\x00\x12\x10\n\x06\x64\x65tail\x18\x07 \x01(\x0cH\x00\x42\x11\n\x0fpayload_variant\"\\\n\x07GeoChat\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0f\n\x02to\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x18\n\x0bto_callsign\x18\x03 \x01(\tH\x01\x88\x01\x01\x42\x05\n\x03_toB\x0e\n\x0c_to_callsign\"_\n\x05Group\x12-\n\x04role\x18\x01 \x01(\x0e\x32\x1f.meshtastic.protobuf.MemberRole\x12\'\n\x04team\x18\x02 \x01(\x0e\x32\x19.meshtastic.protobuf.Team\"\x19\n\x06Status\x12\x0f\n\x07\x62\x61ttery\x18\x01 \x01(\r\"4\n\x07\x43ontact\x12\x10\n\x08\x63\x61llsign\x18\x01 \x01(\t\x12\x17\n\x0f\x64\x65vice_callsign\x18\x02 \x01(\t\"_\n\x03PLI\x12\x12\n\nlatitude_i\x18\x01 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x02 \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x03 \x01(\x05\x12\r\n\x05speed\x18\x04 \x01(\r\x12\x0e\n\x06\x63ourse\x18\x05 \x01(\r*\xc0\x01\n\x04Team\x12\x14\n\x10Unspecifed_Color\x10\x00\x12\t\n\x05White\x10\x01\x12\n\n\x06Yellow\x10\x02\x12\n\n\x06Orange\x10\x03\x12\x0b\n\x07Magenta\x10\x04\x12\x07\n\x03Red\x10\x05\x12\n\n\x06Maroon\x10\x06\x12\n\n\x06Purple\x10\x07\x12\r\n\tDark_Blue\x10\x08\x12\x08\n\x04\x42lue\x10\t\x12\x08\n\x04\x43yan\x10\n\x12\x08\n\x04Teal\x10\x0b\x12\t\n\x05Green\x10\x0c\x12\x0e\n\nDark_Green\x10\r\x12\t\n\x05\x42rown\x10\x0e*\x7f\n\nMemberRole\x12\x0e\n\nUnspecifed\x10\x00\x12\x0e\n\nTeamMember\x10\x01\x12\x0c\n\x08TeamLead\x10\x02\x12\x06\n\x02HQ\x10\x03\x12\n\n\x06Sniper\x10\x04\x12\t\n\x05Medic\x10\x05\x12\x13\n\x0f\x46orwardObserver\x10\x06\x12\x07\n\x03RTO\x10\x07\x12\x06\n\x02K9\x10\x08\x42`\n\x14org.meshtastic.protoB\nATAKProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/atak.proto\x12\x13meshtastic.protobuf\x1a meshtastic/protobuf/nanopb.proto\"\xad\x02\n\tTAKPacket\x12\x15\n\ris_compressed\x18\x01 \x01(\x08\x12-\n\x07\x63ontact\x18\x02 \x01(\x0b\x32\x1c.meshtastic.protobuf.Contact\x12)\n\x05group\x18\x03 \x01(\x0b\x32\x1a.meshtastic.protobuf.Group\x12+\n\x06status\x18\x04 \x01(\x0b\x32\x1b.meshtastic.protobuf.Status\x12\'\n\x03pli\x18\x05 \x01(\x0b\x32\x18.meshtastic.protobuf.PLIH\x00\x12,\n\x04\x63hat\x18\x06 \x01(\x0b\x32\x1c.meshtastic.protobuf.GeoChatH\x00\x12\x18\n\x06\x64\x65tail\x18\x07 \x01(\x0c\x42\x06\x92?\x03\x08\xdc\x01H\x00\x42\x11\n\x0fpayload_variant\"\x9a\x03\n\x07GeoChat\x12\x17\n\x07message\x18\x01 \x01(\tB\x06\x92?\x03\x08\xc8\x01\x12\x16\n\x02to\x18\x02 \x01(\tB\x05\x92?\x02\x08xH\x00\x88\x01\x01\x12\x1f\n\x0bto_callsign\x18\x03 \x01(\tB\x05\x92?\x02\x08xH\x01\x88\x01\x01\x12\x1e\n\x0freceipt_for_uid\x18\x04 \x01(\tB\x05\x92?\x02\x08\x30\x12>\n\x0creceipt_type\x18\x05 \x01(\x0e\x32(.meshtastic.protobuf.GeoChat.ReceiptType\x12\x11\n\x04lang\x18\x06 \x01(\tH\x02\x88\x01\x01\x12\x14\n\x07room_id\x18\x07 \x01(\tH\x03\x88\x01\x01\x12\x1d\n\x10voice_profile_id\x18\x08 \x01(\tH\x04\x88\x01\x01\"T\n\x0bReceiptType\x12\x14\n\x10ReceiptType_None\x10\x00\x12\x19\n\x15ReceiptType_Delivered\x10\x01\x12\x14\n\x10ReceiptType_Read\x10\x02\x42\x05\n\x03_toB\x0e\n\x0c_to_callsignB\x07\n\x05_langB\n\n\x08_room_idB\x13\n\x11_voice_profile_id\"_\n\x05Group\x12-\n\x04role\x18\x01 \x01(\x0e\x32\x1f.meshtastic.protobuf.MemberRole\x12\'\n\x04team\x18\x02 \x01(\x0e\x32\x19.meshtastic.protobuf.Team\" \n\x06Status\x12\x16\n\x07\x62\x61ttery\x18\x01 \x01(\rB\x05\x92?\x02\x38\x08\"B\n\x07\x43ontact\x12\x17\n\x08\x63\x61llsign\x18\x01 \x01(\tB\x05\x92?\x02\x08x\x12\x1e\n\x0f\x64\x65vice_callsign\x18\x02 \x01(\tB\x05\x92?\x02\x08x\"f\n\x03PLI\x12\x12\n\nlatitude_i\x18\x01 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x02 \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x03 \x01(\x05\x12\r\n\x05speed\x18\x04 \x01(\r\x12\x15\n\x06\x63ourse\x18\x05 \x01(\rB\x05\x92?\x02\x38\x10\"\xe1\x01\n\rAircraftTrack\x12\x13\n\x04icao\x18\x01 \x01(\tB\x05\x92?\x02\x08\x08\x12\x1b\n\x0cregistration\x18\x02 \x01(\tB\x05\x92?\x02\x08\x10\x12\x15\n\x06\x66light\x18\x03 \x01(\tB\x05\x92?\x02\x08\x10\x12\x1c\n\raircraft_type\x18\x04 \x01(\tB\x05\x92?\x02\x08\x08\x12\x15\n\x06squawk\x18\x05 \x01(\rB\x05\x92?\x02\x38\x10\x12\x17\n\x08\x63\x61tegory\x18\x06 \x01(\tB\x05\x92?\x02\x08\x04\x12\x10\n\x08rssi_x10\x18\x07 \x01(\x11\x12\x0b\n\x03gps\x18\x08 \x01(\x08\x12\x1a\n\x0b\x63ot_host_id\x18\t \x01(\tB\x05\x92?\x02\x08@\"E\n\x0b\x43otGeoPoint\x12\x1a\n\x0blat_delta_i\x18\x01 \x01(\x11\x42\x05\x92?\x02\x38 \x12\x1a\n\x0blon_delta_i\x18\x02 \x01(\x11\x42\x05\x92?\x02\x38 \"\xb8\x07\n\nDrawnShape\x12\x32\n\x04kind\x18\x01 \x01(\x0e\x32$.meshtastic.protobuf.DrawnShape.Kind\x12\x38\n\x05style\x18\x02 \x01(\x0e\x32).meshtastic.protobuf.DrawnShape.StyleMode\x12\x17\n\x08major_cm\x18\x03 \x01(\rB\x05\x92?\x02\x38 \x12\x17\n\x08minor_cm\x18\x04 \x01(\rB\x05\x92?\x02\x38 \x12\x18\n\tangle_deg\x18\x05 \x01(\rB\x05\x92?\x02\x38\x10\x12/\n\x0cstroke_color\x18\x06 \x01(\x0e\x32\x19.meshtastic.protobuf.Team\x12\x13\n\x0bstroke_argb\x18\x07 \x01(\x07\x12 \n\x11stroke_weight_x10\x18\x08 \x01(\rB\x05\x92?\x02\x38\x10\x12-\n\nfill_color\x18\t \x01(\x0e\x32\x19.meshtastic.protobuf.Team\x12\x11\n\tfill_argb\x18\n \x01(\x07\x12\x11\n\tlabels_on\x18\x0b \x01(\x08\x12\x19\n\x11vertex_lat_deltas\x18\x12 \x03(\x11\x12\x19\n\x11vertex_lon_deltas\x18\x13 \x03(\x11\x12\x11\n\ttruncated\x18\r \x01(\x08\x12#\n\x14\x62ullseye_distance_dm\x18\x0e \x01(\rB\x05\x92?\x02\x38 \x12#\n\x14\x62ullseye_bearing_ref\x18\x0f \x01(\rB\x05\x92?\x02\x38\x08\x12\x1d\n\x0e\x62ullseye_flags\x18\x10 \x01(\rB\x05\x92?\x02\x38\x08\x12\x1f\n\x10\x62ullseye_uid_ref\x18\x11 \x01(\tB\x05\x92?\x02\x08\x30\"\xe2\x01\n\x04Kind\x12\x14\n\x10Kind_Unspecified\x10\x00\x12\x0f\n\x0bKind_Circle\x10\x01\x12\x12\n\x0eKind_Rectangle\x10\x02\x12\x11\n\rKind_Freeform\x10\x03\x12\x15\n\x11Kind_Telestration\x10\x04\x12\x10\n\x0cKind_Polygon\x10\x05\x12\x16\n\x12Kind_RangingCircle\x10\x06\x12\x11\n\rKind_Bullseye\x10\x07\x12\x10\n\x0cKind_Ellipse\x10\x08\x12\x12\n\x0eKind_Vehicle2D\x10\t\x12\x12\n\x0eKind_Vehicle3D\x10\n\"u\n\tStyleMode\x12\x19\n\x15StyleMode_Unspecified\x10\x00\x12\x18\n\x14StyleMode_StrokeOnly\x10\x01\x12\x16\n\x12StyleMode_FillOnly\x10\x02\x12\x1b\n\x17StyleMode_StrokeAndFill\x10\x03J\x04\x08\x0c\x10\r\"\x93\x04\n\x06Marker\x12.\n\x04kind\x18\x01 \x01(\x0e\x32 .meshtastic.protobuf.Marker.Kind\x12(\n\x05\x63olor\x18\x02 \x01(\x0e\x32\x19.meshtastic.protobuf.Team\x12\x12\n\ncolor_argb\x18\x03 \x01(\x07\x12\x11\n\treadiness\x18\x04 \x01(\x08\x12\x19\n\nparent_uid\x18\x05 \x01(\tB\x05\x92?\x02\x08\x30\x12\x1a\n\x0bparent_type\x18\x06 \x01(\tB\x05\x92?\x02\x08\x18\x12\x1e\n\x0fparent_callsign\x18\x07 \x01(\tB\x05\x92?\x02\x08\x18\x12\x16\n\x07iconset\x18\x08 \x01(\tB\x05\x92?\x02\x08P\"\x98\x02\n\x04Kind\x12\x14\n\x10Kind_Unspecified\x10\x00\x12\r\n\tKind_Spot\x10\x01\x12\x11\n\rKind_Waypoint\x10\x02\x12\x13\n\x0fKind_Checkpoint\x10\x03\x12\x15\n\x11Kind_SelfPosition\x10\x04\x12\x13\n\x0fKind_Symbol2525\x10\x05\x12\x10\n\x0cKind_SpotMap\x10\x06\x12\x13\n\x0fKind_CustomIcon\x10\x07\x12\x12\n\x0eKind_GoToPoint\x10\x08\x12\x15\n\x11Kind_InitialPoint\x10\t\x12\x15\n\x11Kind_ContactPoint\x10\n\x12\x18\n\x14Kind_ObservationPost\x10\x0b\x12\x14\n\x10Kind_ImageMarker\x10\x0c\"\xfc\x01\n\x0fRangeAndBearing\x12\x30\n\x06\x61nchor\x18\x01 \x01(\x0b\x32 .meshtastic.protobuf.CotGeoPoint\x12\x19\n\nanchor_uid\x18\x02 \x01(\tB\x05\x92?\x02\x08\x30\x12\x17\n\x08range_cm\x18\x03 \x01(\rB\x05\x92?\x02\x38 \x12\x1b\n\x0c\x62\x65\x61ring_cdeg\x18\x04 \x01(\rB\x05\x92?\x02\x38\x10\x12/\n\x0cstroke_color\x18\x05 \x01(\x0e\x32\x19.meshtastic.protobuf.Team\x12\x13\n\x0bstroke_argb\x18\x06 \x01(\x07\x12 \n\x11stroke_weight_x10\x18\x07 \x01(\rB\x05\x92?\x02\x38\x10\"\xd2\x04\n\x05Route\x12\x31\n\x06method\x18\x01 \x01(\x0e\x32!.meshtastic.protobuf.Route.Method\x12\x37\n\tdirection\x18\x02 \x01(\x0e\x32$.meshtastic.protobuf.Route.Direction\x12\x15\n\x06prefix\x18\x03 \x01(\tB\x05\x92?\x02\x08\x08\x12 \n\x11stroke_weight_x10\x18\x04 \x01(\rB\x05\x92?\x02\x38\x10\x12\x35\n\x05links\x18\x05 \x03(\x0b\x32\x1f.meshtastic.protobuf.Route.LinkB\x05\x92?\x02\x10\x10\x12\x11\n\ttruncated\x18\x06 \x01(\x08\x1a~\n\x04Link\x12/\n\x05point\x18\x01 \x01(\x0b\x32 .meshtastic.protobuf.CotGeoPoint\x12\x12\n\x03uid\x18\x02 \x01(\tB\x05\x92?\x02\x08\x30\x12\x17\n\x08\x63\x61llsign\x18\x03 \x01(\tB\x05\x92?\x02\x08\x10\x12\x18\n\tlink_type\x18\x04 \x01(\rB\x05\x92?\x02\x38\x08\"\x87\x01\n\x06Method\x12\x16\n\x12Method_Unspecified\x10\x00\x12\x12\n\x0eMethod_Driving\x10\x01\x12\x12\n\x0eMethod_Walking\x10\x02\x12\x11\n\rMethod_Flying\x10\x03\x12\x13\n\x0fMethod_Swimming\x10\x04\x12\x15\n\x11Method_Watercraft\x10\x05\"P\n\tDirection\x12\x19\n\x15\x44irection_Unspecified\x10\x00\x12\x13\n\x0f\x44irection_Infil\x10\x01\x12\x13\n\x0f\x44irection_Exfil\x10\x02\"\xce\x0b\n\rCasevacReport\x12\x41\n\nprecedence\x18\x01 \x01(\x0e\x32-.meshtastic.protobuf.CasevacReport.Precedence\x12\x1e\n\x0f\x65quipment_flags\x18\x02 \x01(\rB\x05\x92?\x02\x38\x08\x12\x1e\n\x0flitter_patients\x18\x03 \x01(\rB\x05\x92?\x02\x38\x08\x12\"\n\x13\x61mbulatory_patients\x18\x04 \x01(\rB\x05\x92?\x02\x38\x08\x12=\n\x08security\x18\x05 \x01(\x0e\x32+.meshtastic.protobuf.CasevacReport.Security\x12\x42\n\x0bhlz_marking\x18\x06 \x01(\x0e\x32-.meshtastic.protobuf.CasevacReport.HlzMarking\x12\x1a\n\x0bzone_marker\x18\x07 \x01(\tB\x05\x92?\x02\x08\x10\x12\x1a\n\x0bus_military\x18\x08 \x01(\rB\x05\x92?\x02\x38\x08\x12\x1a\n\x0bus_civilian\x18\t \x01(\rB\x05\x92?\x02\x38\x08\x12\x1e\n\x0fnon_us_military\x18\n \x01(\rB\x05\x92?\x02\x38\x08\x12\x1e\n\x0fnon_us_civilian\x18\x0b \x01(\rB\x05\x92?\x02\x38\x08\x12\x12\n\x03\x65pw\x18\x0c \x01(\rB\x05\x92?\x02\x38\x08\x12\x14\n\x05\x63hild\x18\r \x01(\rB\x05\x92?\x02\x38\x08\x12\x1c\n\rterrain_flags\x18\x0e \x01(\rB\x05\x92?\x02\x38\x08\x12\x18\n\tfrequency\x18\x0f \x01(\tB\x05\x92?\x02\x08\x10\x12\r\n\x05title\x18\x10 \x01(\t\x12\x17\n\x0fmedline_remarks\x18\x11 \x01(\t\x12\x14\n\x0curgent_count\x18\x12 \x01(\r\x12\x1d\n\x15urgent_surgical_count\x18\x13 \x01(\r\x12\x16\n\x0epriority_count\x18\x14 \x01(\r\x12\x15\n\rroutine_count\x18\x15 \x01(\r\x12\x19\n\x11\x63onvenience_count\x18\x16 \x01(\r\x12\x18\n\x10\x65quipment_detail\x18\x17 \x01(\t\x12\x1c\n\x14zone_protected_coord\x18\x18 \x01(\t\x12\x19\n\x11terrain_slope_dir\x18\x19 \x01(\t\x12\x1c\n\x14terrain_other_detail\x18\x1a \x01(\t\x12\x11\n\tmarked_by\x18\x1b \x01(\t\x12\x11\n\tobstacles\x18\x1c \x01(\t\x12\x16\n\x0ewinds_are_from\x18\x1d \x01(\t\x12\x12\n\nfriendlies\x18\x1e \x01(\t\x12\r\n\x05\x65nemy\x18\x1f \x01(\t\x12\x13\n\x0bhlz_remarks\x18 \x01(\t\x12.\n\x05zmist\x18! \x03(\x0b\x32\x1f.meshtastic.protobuf.ZMistEntry\"\xab\x01\n\nPrecedence\x12\x1a\n\x16Precedence_Unspecified\x10\x00\x12\x15\n\x11Precedence_Urgent\x10\x01\x12\x1d\n\x19Precedence_UrgentSurgical\x10\x02\x12\x17\n\x13Precedence_Priority\x10\x03\x12\x16\n\x12Precedence_Routine\x10\x04\x12\x1a\n\x16Precedence_Convenience\x10\x05\"\x9b\x01\n\nHlzMarking\x12\x1a\n\x16HlzMarking_Unspecified\x10\x00\x12\x15\n\x11HlzMarking_Panels\x10\x01\x12\x19\n\x15HlzMarking_PyroSignal\x10\x02\x12\x14\n\x10HlzMarking_Smoke\x10\x03\x12\x13\n\x0fHlzMarking_None\x10\x04\x12\x14\n\x10HlzMarking_Other\x10\x05\"\x92\x01\n\x08Security\x12\x18\n\x14Security_Unspecified\x10\x00\x12\x14\n\x10Security_NoEnemy\x10\x01\x12\x1a\n\x16Security_PossibleEnemy\x10\x02\x12\x18\n\x14Security_EnemyInArea\x10\x03\x12 \n\x1cSecurity_EnemyInArmedContact\x10\x04\"R\n\nZMistEntry\x12\r\n\x05title\x18\x01 \x01(\t\x12\t\n\x01z\x18\x02 \x01(\t\x12\t\n\x01m\x18\x03 \x01(\t\x12\t\n\x01i\x18\x04 \x01(\t\x12\t\n\x01s\x18\x05 \x01(\t\x12\t\n\x01t\x18\x06 \x01(\t\"\xa4\x02\n\x0e\x45mergencyAlert\x12\x36\n\x04type\x18\x01 \x01(\x0e\x32(.meshtastic.protobuf.EmergencyAlert.Type\x12\x1c\n\rauthoring_uid\x18\x02 \x01(\tB\x05\x92?\x02\x08\x30\x12#\n\x14\x63\x61ncel_reference_uid\x18\x03 \x01(\tB\x05\x92?\x02\x08\x30\"\x96\x01\n\x04Type\x12\x14\n\x10Type_Unspecified\x10\x00\x12\x11\n\rType_Alert911\x10\x01\x12\x14\n\x10Type_RingTheBell\x10\x02\x12\x12\n\x0eType_InContact\x10\x03\x12\x19\n\x15Type_GeoFenceBreached\x10\x04\x12\x0f\n\x0bType_Custom\x10\x05\x12\x0f\n\x0bType_Cancel\x10\x06\"\xf4\x03\n\x0bTaskRequest\x12\x18\n\ttask_type\x18\x01 \x01(\tB\x05\x92?\x02\x08\x0c\x12\x19\n\ntarget_uid\x18\x02 \x01(\tB\x05\x92?\x02\x08 \x12\x1b\n\x0c\x61ssignee_uid\x18\x03 \x01(\tB\x05\x92?\x02\x08 \x12;\n\x08priority\x18\x04 \x01(\x0e\x32).meshtastic.protobuf.TaskRequest.Priority\x12\x37\n\x06status\x18\x05 \x01(\x0e\x32\'.meshtastic.protobuf.TaskRequest.Status\x12\x13\n\x04note\x18\x06 \x01(\tB\x05\x92?\x02\x08\x30\"u\n\x08Priority\x12\x18\n\x14Priority_Unspecified\x10\x00\x12\x10\n\x0cPriority_Low\x10\x01\x12\x13\n\x0fPriority_Normal\x10\x02\x12\x11\n\rPriority_High\x10\x03\x12\x15\n\x11Priority_Critical\x10\x04\"\x90\x01\n\x06Status\x12\x16\n\x12Status_Unspecified\x10\x00\x12\x12\n\x0eStatus_Pending\x10\x01\x12\x17\n\x13Status_Acknowledged\x10\x02\x12\x15\n\x11Status_InProgress\x10\x03\x12\x14\n\x10Status_Completed\x10\x04\x12\x14\n\x10Status_Cancelled\x10\x05\"`\n\x0eTAKEnvironment\x12\x19\n\x11temperature_c_x10\x18\x01 \x01(\x11\x12\x1a\n\x12wind_direction_deg\x18\x02 \x01(\r\x12\x17\n\x0fwind_speed_cm_s\x18\x03 \x01(\r\"\x96\x03\n\tSensorFov\x12\x37\n\x04type\x18\x01 \x01(\x0e\x32).meshtastic.protobuf.SensorFov.SensorType\x12\x13\n\x0b\x61zimuth_deg\x18\x02 \x01(\r\x12\x14\n\x07range_m\x18\x03 \x01(\rH\x00\x88\x01\x01\x12\x1a\n\x12\x66ov_horizontal_deg\x18\x04 \x01(\r\x12\x18\n\x10\x66ov_vertical_deg\x18\x05 \x01(\r\x12\x15\n\relevation_deg\x18\x06 \x01(\x11\x12\x10\n\x08roll_deg\x18\x07 \x01(\x11\x12\r\n\x05model\x18\x08 \x01(\t\"\xaa\x01\n\nSensorType\x12\x1a\n\x16SensorType_Unspecified\x10\x00\x12\x15\n\x11SensorType_Camera\x10\x01\x12\x16\n\x12SensorType_Thermal\x10\x02\x12\x14\n\x10SensorType_Laser\x10\x03\x12\x12\n\x0eSensorType_Nvg\x10\x04\x12\x11\n\rSensorType_Rf\x10\x05\x12\x14\n\x10SensorType_Other\x10\x06\x42\n\n\x08_range_m\"U\n\x0eTakTalkMessage\x12\x0c\n\x04text\x18\x01 \x01(\t\x12\x13\n\x0b\x63hatroom_id\x18\x02 \x01(\t\x12\x0c\n\x04lang\x18\x03 \x01(\t\x12\x12\n\nfrom_voice\x18\x04 \x01(\x08\"h\n\x0fTakTalkRoomData\x12\x1b\n\x0fsender_callsign\x18\x01 \x01(\tB\x02\x18\x01\x12\x0f\n\x07room_id\x18\x02 \x01(\t\x12\x11\n\troom_name\x18\x03 \x01(\t\x12\x14\n\x0cparticipants\x18\x04 \x03(\t\"\x1e\n\x05Marti\x12\x15\n\rdest_callsign\x18\x01 \x03(\t\"\xb0\x0c\n\x0bTAKPacketV2\x12\x31\n\x0b\x63ot_type_id\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.CotType\x12(\n\x03how\x18\x02 \x01(\x0e\x32\x1b.meshtastic.protobuf.CotHow\x12\x17\n\x08\x63\x61llsign\x18\x03 \x01(\tB\x05\x92?\x02\x08x\x12\'\n\x04team\x18\x04 \x01(\x0e\x32\x19.meshtastic.protobuf.Team\x12-\n\x04role\x18\x05 \x01(\x0e\x32\x1f.meshtastic.protobuf.MemberRole\x12\x12\n\nlatitude_i\x18\x06 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x07 \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x08 \x01(\x11\x12\r\n\x05speed\x18\t \x01(\r\x12\x15\n\x06\x63ourse\x18\n \x01(\rB\x05\x92?\x02\x38\x10\x12\x16\n\x07\x62\x61ttery\x18\x0b \x01(\rB\x05\x92?\x02\x38\x08\x12\x34\n\x07geo_src\x18\x0c \x01(\x0e\x32#.meshtastic.protobuf.GeoPointSource\x12\x34\n\x07\x61lt_src\x18\r \x01(\x0e\x32#.meshtastic.protobuf.GeoPointSource\x12\x12\n\x03uid\x18\x0e \x01(\tB\x05\x92?\x02\x08\x30\x12\x1e\n\x0f\x64\x65vice_callsign\x18\x0f \x01(\tB\x05\x92?\x02\x08x\x12\x1c\n\rstale_seconds\x18\x10 \x01(\rB\x05\x92?\x02\x38\x10\x12\x1a\n\x0btak_version\x18\x11 \x01(\tB\x05\x92?\x02\x08@\x12\x19\n\ntak_device\x18\x12 \x01(\tB\x05\x92?\x02\x08 \x12\x1b\n\x0ctak_platform\x18\x13 \x01(\tB\x05\x92?\x02\x08 \x12\x15\n\x06tak_os\x18\x14 \x01(\tB\x05\x92?\x02\x08\x10\x12\x17\n\x08\x65ndpoint\x18\x15 \x01(\tB\x05\x92?\x02\x08 \x12\x14\n\x05phone\x18\x16 \x01(\tB\x05\x92?\x02\x08\x14\x12\x1b\n\x0c\x63ot_type_str\x18\x17 \x01(\tB\x05\x92?\x02\x08 \x12\x0f\n\x07remarks\x18\x18 \x01(\t\x12=\n\x0b\x65nvironment\x18\x19 \x01(\x0b\x32#.meshtastic.protobuf.TAKEnvironmentH\x01\x88\x01\x01\x12\x37\n\nsensor_fov\x18\x1a \x01(\x0b\x32\x1e.meshtastic.protobuf.SensorFovH\x02\x88\x01\x01\x12.\n\x05marti\x18\x1d \x01(\x0b\x32\x1a.meshtastic.protobuf.MartiH\x03\x88\x01\x01\x12,\n\x04\x63hat\x18\x1f \x01(\x0b\x32\x1c.meshtastic.protobuf.GeoChatH\x00\x12\x36\n\x08\x61ircraft\x18 \x01(\x0b\x32\".meshtastic.protobuf.AircraftTrackH\x00\x12\x1c\n\nraw_detail\x18! \x01(\x0c\x42\x06\x92?\x03\x08\xdc\x01H\x00\x12\x30\n\x05shape\x18\" \x01(\x0b\x32\x1f.meshtastic.protobuf.DrawnShapeH\x00\x12-\n\x06marker\x18# \x01(\x0b\x32\x1b.meshtastic.protobuf.MarkerH\x00\x12\x33\n\x03rab\x18$ \x01(\x0b\x32$.meshtastic.protobuf.RangeAndBearingH\x00\x12+\n\x05route\x18% \x01(\x0b\x32\x1a.meshtastic.protobuf.RouteH\x00\x12\x35\n\x07\x63\x61sevac\x18& \x01(\x0b\x32\".meshtastic.protobuf.CasevacReportH\x00\x12\x38\n\temergency\x18\' \x01(\x0b\x32#.meshtastic.protobuf.EmergencyAlertH\x00\x12\x30\n\x04task\x18( \x01(\x0b\x32 .meshtastic.protobuf.TaskRequestH\x00\x12\x36\n\x07taktalk\x18) \x01(\x0b\x32#.meshtastic.protobuf.TakTalkMessageH\x00\x12<\n\x0ctaktalk_room\x18* \x01(\x0b\x32$.meshtastic.protobuf.TakTalkRoomDataH\x00\x42\x11\n\x0fpayload_variantB\x0e\n\x0c_environmentB\r\n\x0b_sensor_fovB\x08\n\x06_martiJ\x04\x08\x1b\x10\x1cJ\x04\x08\x1c\x10\x1dJ\x04\x08\x1e\x10\x1f*\xc0\x01\n\x04Team\x12\x14\n\x10Unspecifed_Color\x10\x00\x12\t\n\x05White\x10\x01\x12\n\n\x06Yellow\x10\x02\x12\n\n\x06Orange\x10\x03\x12\x0b\n\x07Magenta\x10\x04\x12\x07\n\x03Red\x10\x05\x12\n\n\x06Maroon\x10\x06\x12\n\n\x06Purple\x10\x07\x12\r\n\tDark_Blue\x10\x08\x12\x08\n\x04\x42lue\x10\t\x12\x08\n\x04\x43yan\x10\n\x12\x08\n\x04Teal\x10\x0b\x12\t\n\x05Green\x10\x0c\x12\x0e\n\nDark_Green\x10\r\x12\t\n\x05\x42rown\x10\x0e*\x7f\n\nMemberRole\x12\x0e\n\nUnspecifed\x10\x00\x12\x0e\n\nTeamMember\x10\x01\x12\x0c\n\x08TeamLead\x10\x02\x12\x06\n\x02HQ\x10\x03\x12\n\n\x06Sniper\x10\x04\x12\t\n\x05Medic\x10\x05\x12\x13\n\x0f\x46orwardObserver\x10\x06\x12\x07\n\x03RTO\x10\x07\x12\x06\n\x02K9\x10\x08*\x96\x01\n\x06\x43otHow\x12\x16\n\x12\x43otHow_Unspecified\x10\x00\x12\x0e\n\nCotHow_h_e\x10\x01\x12\x0e\n\nCotHow_m_g\x10\x02\x12\x14\n\x10\x43otHow_h_g_i_g_o\x10\x03\x12\x0e\n\nCotHow_m_r\x10\x04\x12\x0e\n\nCotHow_m_f\x10\x05\x12\x0e\n\nCotHow_m_p\x10\x06\x12\x0e\n\nCotHow_m_s\x10\x07*\x83\x17\n\x07\x43otType\x12\x11\n\rCotType_Other\x10\x00\x12\x15\n\x11\x43otType_a_f_G_U_C\x10\x01\x12\x17\n\x13\x43otType_a_f_G_U_C_I\x10\x02\x12\x15\n\x11\x43otType_a_n_A_C_F\x10\x03\x12\x15\n\x11\x43otType_a_n_A_C_H\x10\x04\x12\x13\n\x0f\x43otType_a_n_A_C\x10\x05\x12\x15\n\x11\x43otType_a_f_A_M_H\x10\x06\x12\x13\n\x0f\x43otType_a_f_A_M\x10\x07\x12\x17\n\x13\x43otType_a_f_A_M_F_F\x10\x08\x12\x17\n\x13\x43otType_a_f_A_M_H_A\x10\t\x12\x19\n\x15\x43otType_a_f_A_M_H_U_M\x10\n\x12\x17\n\x13\x43otType_a_h_A_M_F_F\x10\x0b\x12\x17\n\x13\x43otType_a_h_A_M_H_A\x10\x0c\x12\x13\n\x0f\x43otType_a_u_A_C\x10\r\x12\x13\n\x0f\x43otType_t_x_d_d\x10\x0e\x12\x17\n\x13\x43otType_a_f_G_E_S_E\x10\x0f\x12\x17\n\x13\x43otType_a_f_G_E_V_C\x10\x10\x12\x11\n\rCotType_a_f_S\x10\x11\x12\x15\n\x11\x43otType_a_f_A_M_F\x10\x12\x12\x19\n\x15\x43otType_a_f_A_M_F_C_H\x10\x13\x12\x19\n\x15\x43otType_a_f_A_M_F_U_L\x10\x14\x12\x17\n\x13\x43otType_a_f_A_M_F_L\x10\x15\x12\x17\n\x13\x43otType_a_f_A_M_F_P\x10\x16\x12\x15\n\x11\x43otType_a_f_A_C_H\x10\x17\x12\x17\n\x13\x43otType_a_n_A_M_F_Q\x10\x18\x12\x11\n\rCotType_b_t_f\x10\x19\x12\x15\n\x11\x43otType_b_r_f_h_c\x10\x1a\x12\x15\n\x11\x43otType_b_a_o_pan\x10\x1b\x12\x15\n\x11\x43otType_b_a_o_opn\x10\x1c\x12\x15\n\x11\x43otType_b_a_o_can\x10\x1d\x12\x15\n\x11\x43otType_b_a_o_tbl\x10\x1e\x12\x11\n\rCotType_b_a_g\x10\x1f\x12\x11\n\rCotType_a_f_G\x10 \x12\x13\n\x0f\x43otType_a_f_G_U\x10!\x12\x11\n\rCotType_a_h_G\x10\"\x12\x11\n\rCotType_a_u_G\x10#\x12\x11\n\rCotType_a_n_G\x10$\x12\x11\n\rCotType_b_m_r\x10%\x12\x13\n\x0f\x43otType_b_m_p_w\x10&\x12\x17\n\x13\x43otType_b_m_p_s_p_i\x10\'\x12\x11\n\rCotType_u_d_f\x10(\x12\x11\n\rCotType_u_d_r\x10)\x12\x13\n\x0f\x43otType_u_d_c_c\x10*\x12\x12\n\x0e\x43otType_u_rb_a\x10+\x12\x11\n\rCotType_a_h_A\x10,\x12\x11\n\rCotType_a_u_A\x10-\x12\x17\n\x13\x43otType_a_f_A_M_H_Q\x10.\x12\x15\n\x11\x43otType_a_f_A_C_F\x10/\x12\x13\n\x0f\x43otType_a_f_A_C\x10\x30\x12\x15\n\x11\x43otType_a_f_A_C_L\x10\x31\x12\x11\n\rCotType_a_f_A\x10\x32\x12\x17\n\x13\x43otType_a_f_A_M_H_C\x10\x33\x12\x17\n\x13\x43otType_a_n_A_M_F_F\x10\x34\x12\x15\n\x11\x43otType_a_u_A_C_F\x10\x35\x12\x1b\n\x17\x43otType_a_f_G_U_C_F_T_A\x10\x36\x12\x19\n\x15\x43otType_a_f_G_U_C_V_S\x10\x37\x12\x19\n\x15\x43otType_a_f_G_U_C_R_X\x10\x38\x12\x19\n\x15\x43otType_a_f_G_U_C_I_Z\x10\x39\x12\x1b\n\x17\x43otType_a_f_G_U_C_E_C_W\x10:\x12\x19\n\x15\x43otType_a_f_G_U_C_I_L\x10;\x12\x19\n\x15\x43otType_a_f_G_U_C_R_O\x10<\x12\x19\n\x15\x43otType_a_f_G_U_C_R_V\x10=\x12\x15\n\x11\x43otType_a_f_G_U_H\x10>\x12\x1b\n\x17\x43otType_a_f_G_U_U_M_S_E\x10?\x12\x19\n\x15\x43otType_a_f_G_U_S_M_C\x10@\x12\x15\n\x11\x43otType_a_f_G_E_S\x10\x41\x12\x13\n\x0f\x43otType_a_f_G_E\x10\x42\x12\x19\n\x15\x43otType_a_f_G_E_V_C_U\x10\x43\x12\x1a\n\x16\x43otType_a_f_G_E_V_C_ps\x10\x44\x12\x15\n\x11\x43otType_a_u_G_E_V\x10\x45\x12\x17\n\x13\x43otType_a_f_S_N_N_R\x10\x46\x12\x13\n\x0f\x43otType_a_f_F_B\x10G\x12\x19\n\x15\x43otType_b_m_p_s_p_loc\x10H\x12\x11\n\rCotType_b_i_v\x10I\x12\x13\n\x0f\x43otType_b_f_t_r\x10J\x12\x13\n\x0f\x43otType_b_f_t_a\x10K\x12\x13\n\x0f\x43otType_u_d_f_m\x10L\x12\x11\n\rCotType_u_d_p\x10M\x12\x15\n\x11\x43otType_b_m_p_s_m\x10N\x12\x13\n\x0f\x43otType_b_m_p_c\x10O\x12\x15\n\x11\x43otType_u_r_b_c_c\x10P\x12\x1a\n\x16\x43otType_u_r_b_bullseye\x10Q\x12\x17\n\x13\x43otType_a_f_G_E_V_A\x10R\x12\x11\n\rCotType_a_n_A\x10S\x12\x17\n\x13\x43otType_a_u_G_U_C_F\x10T\x12\x17\n\x13\x43otType_a_n_G_U_C_F\x10U\x12\x17\n\x13\x43otType_a_h_G_U_C_F\x10V\x12\x17\n\x13\x43otType_a_f_G_U_C_F\x10W\x12\x13\n\x0f\x43otType_a_u_G_I\x10X\x12\x13\n\x0f\x43otType_a_n_G_I\x10Y\x12\x13\n\x0f\x43otType_a_h_G_I\x10Z\x12\x13\n\x0f\x43otType_a_f_G_I\x10[\x12\x17\n\x13\x43otType_a_u_G_E_X_M\x10\\\x12\x17\n\x13\x43otType_a_n_G_E_X_M\x10]\x12\x17\n\x13\x43otType_a_h_G_E_X_M\x10^\x12\x17\n\x13\x43otType_a_f_G_E_X_M\x10_\x12\x11\n\rCotType_a_u_S\x10`\x12\x11\n\rCotType_a_n_S\x10\x61\x12\x11\n\rCotType_a_h_S\x10\x62\x12\x19\n\x15\x43otType_a_u_G_U_C_I_d\x10\x63\x12\x19\n\x15\x43otType_a_n_G_U_C_I_d\x10\x64\x12\x19\n\x15\x43otType_a_h_G_U_C_I_d\x10\x65\x12\x19\n\x15\x43otType_a_f_G_U_C_I_d\x10\x66\x12\x19\n\x15\x43otType_a_u_G_E_V_A_T\x10g\x12\x19\n\x15\x43otType_a_n_G_E_V_A_T\x10h\x12\x19\n\x15\x43otType_a_h_G_E_V_A_T\x10i\x12\x19\n\x15\x43otType_a_f_G_E_V_A_T\x10j\x12\x17\n\x13\x43otType_a_u_G_U_C_I\x10k\x12\x17\n\x13\x43otType_a_n_G_U_C_I\x10l\x12\x17\n\x13\x43otType_a_h_G_U_C_I\x10m\x12\x15\n\x11\x43otType_a_n_G_E_V\x10n\x12\x15\n\x11\x43otType_a_h_G_E_V\x10o\x12\x15\n\x11\x43otType_a_f_G_E_V\x10p\x12\x18\n\x14\x43otType_b_m_p_w_GOTO\x10q\x12\x16\n\x12\x43otType_b_m_p_c_ip\x10r\x12\x16\n\x12\x43otType_b_m_p_c_cp\x10s\x12\x18\n\x14\x43otType_b_m_p_s_p_op\x10t\x12\x11\n\rCotType_u_d_v\x10u\x12\x13\n\x0f\x43otType_u_d_v_m\x10v\x12\x13\n\x0f\x43otType_u_d_c_e\x10w\x12\x13\n\x0f\x43otType_b_i_x_i\x10x\x12\x13\n\x0f\x43otType_b_t_f_d\x10y\x12\x13\n\x0f\x43otType_b_t_f_r\x10z\x12\x13\n\x0f\x43otType_b_a_o_c\x10{\x12\x0f\n\x0b\x43otType_t_s\x10|\x12\x11\n\rCotType_m_t_t\x10}\x12\r\n\tCotType_y\x10~*}\n\x0eGeoPointSource\x12\x1e\n\x1aGeoPointSource_Unspecified\x10\x00\x12\x16\n\x12GeoPointSource_GPS\x10\x01\x12\x17\n\x13GeoPointSource_USER\x10\x02\x12\x1a\n\x16GeoPointSource_NETWORK\x10\x03\x42`\n\x14org.meshtastic.protoB\nATAKProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -21,20 +22,232 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.atak_pb if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\nATAKProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _globals['_TEAM']._serialized_start=721 - _globals['_TEAM']._serialized_end=913 - _globals['_MEMBERROLE']._serialized_start=915 - _globals['_MEMBERROLE']._serialized_end=1042 - _globals['_TAKPACKET']._serialized_start=56 - _globals['_TAKPACKET']._serialized_end=349 - _globals['_GEOCHAT']._serialized_start=351 - _globals['_GEOCHAT']._serialized_end=443 - _globals['_GROUP']._serialized_start=445 - _globals['_GROUP']._serialized_end=540 - _globals['_STATUS']._serialized_start=542 - _globals['_STATUS']._serialized_end=567 - _globals['_CONTACT']._serialized_start=569 - _globals['_CONTACT']._serialized_end=621 - _globals['_PLI']._serialized_start=623 - _globals['_PLI']._serialized_end=718 + _TAKPACKET.fields_by_name['detail']._options = None + _TAKPACKET.fields_by_name['detail']._serialized_options = b'\222?\003\010\334\001' + _GEOCHAT.fields_by_name['message']._options = None + _GEOCHAT.fields_by_name['message']._serialized_options = b'\222?\003\010\310\001' + _GEOCHAT.fields_by_name['to']._options = None + _GEOCHAT.fields_by_name['to']._serialized_options = b'\222?\002\010x' + _GEOCHAT.fields_by_name['to_callsign']._options = None + _GEOCHAT.fields_by_name['to_callsign']._serialized_options = b'\222?\002\010x' + _GEOCHAT.fields_by_name['receipt_for_uid']._options = None + _GEOCHAT.fields_by_name['receipt_for_uid']._serialized_options = b'\222?\002\0100' + _STATUS.fields_by_name['battery']._options = None + _STATUS.fields_by_name['battery']._serialized_options = b'\222?\0028\010' + _CONTACT.fields_by_name['callsign']._options = None + _CONTACT.fields_by_name['callsign']._serialized_options = b'\222?\002\010x' + _CONTACT.fields_by_name['device_callsign']._options = None + _CONTACT.fields_by_name['device_callsign']._serialized_options = b'\222?\002\010x' + _PLI.fields_by_name['course']._options = None + _PLI.fields_by_name['course']._serialized_options = b'\222?\0028\020' + _AIRCRAFTTRACK.fields_by_name['icao']._options = None + _AIRCRAFTTRACK.fields_by_name['icao']._serialized_options = b'\222?\002\010\010' + _AIRCRAFTTRACK.fields_by_name['registration']._options = None + _AIRCRAFTTRACK.fields_by_name['registration']._serialized_options = b'\222?\002\010\020' + _AIRCRAFTTRACK.fields_by_name['flight']._options = None + _AIRCRAFTTRACK.fields_by_name['flight']._serialized_options = b'\222?\002\010\020' + _AIRCRAFTTRACK.fields_by_name['aircraft_type']._options = None + _AIRCRAFTTRACK.fields_by_name['aircraft_type']._serialized_options = b'\222?\002\010\010' + _AIRCRAFTTRACK.fields_by_name['squawk']._options = None + _AIRCRAFTTRACK.fields_by_name['squawk']._serialized_options = b'\222?\0028\020' + _AIRCRAFTTRACK.fields_by_name['category']._options = None + _AIRCRAFTTRACK.fields_by_name['category']._serialized_options = b'\222?\002\010\004' + _AIRCRAFTTRACK.fields_by_name['cot_host_id']._options = None + _AIRCRAFTTRACK.fields_by_name['cot_host_id']._serialized_options = b'\222?\002\010@' + _COTGEOPOINT.fields_by_name['lat_delta_i']._options = None + _COTGEOPOINT.fields_by_name['lat_delta_i']._serialized_options = b'\222?\0028 ' + _COTGEOPOINT.fields_by_name['lon_delta_i']._options = None + _COTGEOPOINT.fields_by_name['lon_delta_i']._serialized_options = b'\222?\0028 ' + _DRAWNSHAPE.fields_by_name['major_cm']._options = None + _DRAWNSHAPE.fields_by_name['major_cm']._serialized_options = b'\222?\0028 ' + _DRAWNSHAPE.fields_by_name['minor_cm']._options = None + _DRAWNSHAPE.fields_by_name['minor_cm']._serialized_options = b'\222?\0028 ' + _DRAWNSHAPE.fields_by_name['angle_deg']._options = None + _DRAWNSHAPE.fields_by_name['angle_deg']._serialized_options = b'\222?\0028\020' + _DRAWNSHAPE.fields_by_name['stroke_weight_x10']._options = None + _DRAWNSHAPE.fields_by_name['stroke_weight_x10']._serialized_options = b'\222?\0028\020' + _DRAWNSHAPE.fields_by_name['bullseye_distance_dm']._options = None + _DRAWNSHAPE.fields_by_name['bullseye_distance_dm']._serialized_options = b'\222?\0028 ' + _DRAWNSHAPE.fields_by_name['bullseye_bearing_ref']._options = None + _DRAWNSHAPE.fields_by_name['bullseye_bearing_ref']._serialized_options = b'\222?\0028\010' + _DRAWNSHAPE.fields_by_name['bullseye_flags']._options = None + _DRAWNSHAPE.fields_by_name['bullseye_flags']._serialized_options = b'\222?\0028\010' + _DRAWNSHAPE.fields_by_name['bullseye_uid_ref']._options = None + _DRAWNSHAPE.fields_by_name['bullseye_uid_ref']._serialized_options = b'\222?\002\0100' + _MARKER.fields_by_name['parent_uid']._options = None + _MARKER.fields_by_name['parent_uid']._serialized_options = b'\222?\002\0100' + _MARKER.fields_by_name['parent_type']._options = None + _MARKER.fields_by_name['parent_type']._serialized_options = b'\222?\002\010\030' + _MARKER.fields_by_name['parent_callsign']._options = None + _MARKER.fields_by_name['parent_callsign']._serialized_options = b'\222?\002\010\030' + _MARKER.fields_by_name['iconset']._options = None + _MARKER.fields_by_name['iconset']._serialized_options = b'\222?\002\010P' + _RANGEANDBEARING.fields_by_name['anchor_uid']._options = None + _RANGEANDBEARING.fields_by_name['anchor_uid']._serialized_options = b'\222?\002\0100' + _RANGEANDBEARING.fields_by_name['range_cm']._options = None + _RANGEANDBEARING.fields_by_name['range_cm']._serialized_options = b'\222?\0028 ' + _RANGEANDBEARING.fields_by_name['bearing_cdeg']._options = None + _RANGEANDBEARING.fields_by_name['bearing_cdeg']._serialized_options = b'\222?\0028\020' + _RANGEANDBEARING.fields_by_name['stroke_weight_x10']._options = None + _RANGEANDBEARING.fields_by_name['stroke_weight_x10']._serialized_options = b'\222?\0028\020' + _ROUTE_LINK.fields_by_name['uid']._options = None + _ROUTE_LINK.fields_by_name['uid']._serialized_options = b'\222?\002\0100' + _ROUTE_LINK.fields_by_name['callsign']._options = None + _ROUTE_LINK.fields_by_name['callsign']._serialized_options = b'\222?\002\010\020' + _ROUTE_LINK.fields_by_name['link_type']._options = None + _ROUTE_LINK.fields_by_name['link_type']._serialized_options = b'\222?\0028\010' + _ROUTE.fields_by_name['prefix']._options = None + _ROUTE.fields_by_name['prefix']._serialized_options = b'\222?\002\010\010' + _ROUTE.fields_by_name['stroke_weight_x10']._options = None + _ROUTE.fields_by_name['stroke_weight_x10']._serialized_options = b'\222?\0028\020' + _ROUTE.fields_by_name['links']._options = None + _ROUTE.fields_by_name['links']._serialized_options = b'\222?\002\020\020' + _CASEVACREPORT.fields_by_name['equipment_flags']._options = None + _CASEVACREPORT.fields_by_name['equipment_flags']._serialized_options = b'\222?\0028\010' + _CASEVACREPORT.fields_by_name['litter_patients']._options = None + _CASEVACREPORT.fields_by_name['litter_patients']._serialized_options = b'\222?\0028\010' + _CASEVACREPORT.fields_by_name['ambulatory_patients']._options = None + _CASEVACREPORT.fields_by_name['ambulatory_patients']._serialized_options = b'\222?\0028\010' + _CASEVACREPORT.fields_by_name['zone_marker']._options = None + _CASEVACREPORT.fields_by_name['zone_marker']._serialized_options = b'\222?\002\010\020' + _CASEVACREPORT.fields_by_name['us_military']._options = None + _CASEVACREPORT.fields_by_name['us_military']._serialized_options = b'\222?\0028\010' + _CASEVACREPORT.fields_by_name['us_civilian']._options = None + _CASEVACREPORT.fields_by_name['us_civilian']._serialized_options = b'\222?\0028\010' + _CASEVACREPORT.fields_by_name['non_us_military']._options = None + _CASEVACREPORT.fields_by_name['non_us_military']._serialized_options = b'\222?\0028\010' + _CASEVACREPORT.fields_by_name['non_us_civilian']._options = None + _CASEVACREPORT.fields_by_name['non_us_civilian']._serialized_options = b'\222?\0028\010' + _CASEVACREPORT.fields_by_name['epw']._options = None + _CASEVACREPORT.fields_by_name['epw']._serialized_options = b'\222?\0028\010' + _CASEVACREPORT.fields_by_name['child']._options = None + _CASEVACREPORT.fields_by_name['child']._serialized_options = b'\222?\0028\010' + _CASEVACREPORT.fields_by_name['terrain_flags']._options = None + _CASEVACREPORT.fields_by_name['terrain_flags']._serialized_options = b'\222?\0028\010' + _CASEVACREPORT.fields_by_name['frequency']._options = None + _CASEVACREPORT.fields_by_name['frequency']._serialized_options = b'\222?\002\010\020' + _EMERGENCYALERT.fields_by_name['authoring_uid']._options = None + _EMERGENCYALERT.fields_by_name['authoring_uid']._serialized_options = b'\222?\002\0100' + _EMERGENCYALERT.fields_by_name['cancel_reference_uid']._options = None + _EMERGENCYALERT.fields_by_name['cancel_reference_uid']._serialized_options = b'\222?\002\0100' + _TASKREQUEST.fields_by_name['task_type']._options = None + _TASKREQUEST.fields_by_name['task_type']._serialized_options = b'\222?\002\010\014' + _TASKREQUEST.fields_by_name['target_uid']._options = None + _TASKREQUEST.fields_by_name['target_uid']._serialized_options = b'\222?\002\010 ' + _TASKREQUEST.fields_by_name['assignee_uid']._options = None + _TASKREQUEST.fields_by_name['assignee_uid']._serialized_options = b'\222?\002\010 ' + _TASKREQUEST.fields_by_name['note']._options = None + _TASKREQUEST.fields_by_name['note']._serialized_options = b'\222?\002\0100' + _TAKTALKROOMDATA.fields_by_name['sender_callsign']._options = None + _TAKTALKROOMDATA.fields_by_name['sender_callsign']._serialized_options = b'\030\001' + _TAKPACKETV2.fields_by_name['callsign']._options = None + _TAKPACKETV2.fields_by_name['callsign']._serialized_options = b'\222?\002\010x' + _TAKPACKETV2.fields_by_name['course']._options = None + _TAKPACKETV2.fields_by_name['course']._serialized_options = b'\222?\0028\020' + _TAKPACKETV2.fields_by_name['battery']._options = None + _TAKPACKETV2.fields_by_name['battery']._serialized_options = b'\222?\0028\010' + _TAKPACKETV2.fields_by_name['uid']._options = None + _TAKPACKETV2.fields_by_name['uid']._serialized_options = b'\222?\002\0100' + _TAKPACKETV2.fields_by_name['device_callsign']._options = None + _TAKPACKETV2.fields_by_name['device_callsign']._serialized_options = b'\222?\002\010x' + _TAKPACKETV2.fields_by_name['stale_seconds']._options = None + _TAKPACKETV2.fields_by_name['stale_seconds']._serialized_options = b'\222?\0028\020' + _TAKPACKETV2.fields_by_name['tak_version']._options = None + _TAKPACKETV2.fields_by_name['tak_version']._serialized_options = b'\222?\002\010@' + _TAKPACKETV2.fields_by_name['tak_device']._options = None + _TAKPACKETV2.fields_by_name['tak_device']._serialized_options = b'\222?\002\010 ' + _TAKPACKETV2.fields_by_name['tak_platform']._options = None + _TAKPACKETV2.fields_by_name['tak_platform']._serialized_options = b'\222?\002\010 ' + _TAKPACKETV2.fields_by_name['tak_os']._options = None + _TAKPACKETV2.fields_by_name['tak_os']._serialized_options = b'\222?\002\010\020' + _TAKPACKETV2.fields_by_name['endpoint']._options = None + _TAKPACKETV2.fields_by_name['endpoint']._serialized_options = b'\222?\002\010 ' + _TAKPACKETV2.fields_by_name['phone']._options = None + _TAKPACKETV2.fields_by_name['phone']._serialized_options = b'\222?\002\010\024' + _TAKPACKETV2.fields_by_name['cot_type_str']._options = None + _TAKPACKETV2.fields_by_name['cot_type_str']._serialized_options = b'\222?\002\010 ' + _TAKPACKETV2.fields_by_name['raw_detail']._options = None + _TAKPACKETV2.fields_by_name['raw_detail']._serialized_options = b'\222?\003\010\334\001' + _globals['_TEAM']._serialized_start=8440 + _globals['_TEAM']._serialized_end=8632 + _globals['_MEMBERROLE']._serialized_start=8634 + _globals['_MEMBERROLE']._serialized_end=8761 + _globals['_COTHOW']._serialized_start=8764 + _globals['_COTHOW']._serialized_end=8914 + _globals['_COTTYPE']._serialized_start=8917 + _globals['_COTTYPE']._serialized_end=11864 + _globals['_GEOPOINTSOURCE']._serialized_start=11866 + _globals['_GEOPOINTSOURCE']._serialized_end=11991 + _globals['_TAKPACKET']._serialized_start=90 + _globals['_TAKPACKET']._serialized_end=391 + _globals['_GEOCHAT']._serialized_start=394 + _globals['_GEOCHAT']._serialized_end=804 + _globals['_GEOCHAT_RECEIPTTYPE']._serialized_start=655 + _globals['_GEOCHAT_RECEIPTTYPE']._serialized_end=739 + _globals['_GROUP']._serialized_start=806 + _globals['_GROUP']._serialized_end=901 + _globals['_STATUS']._serialized_start=903 + _globals['_STATUS']._serialized_end=935 + _globals['_CONTACT']._serialized_start=937 + _globals['_CONTACT']._serialized_end=1003 + _globals['_PLI']._serialized_start=1005 + _globals['_PLI']._serialized_end=1107 + _globals['_AIRCRAFTTRACK']._serialized_start=1110 + _globals['_AIRCRAFTTRACK']._serialized_end=1335 + _globals['_COTGEOPOINT']._serialized_start=1337 + _globals['_COTGEOPOINT']._serialized_end=1406 + _globals['_DRAWNSHAPE']._serialized_start=1409 + _globals['_DRAWNSHAPE']._serialized_end=2361 + _globals['_DRAWNSHAPE_KIND']._serialized_start=2010 + _globals['_DRAWNSHAPE_KIND']._serialized_end=2236 + _globals['_DRAWNSHAPE_STYLEMODE']._serialized_start=2238 + _globals['_DRAWNSHAPE_STYLEMODE']._serialized_end=2355 + _globals['_MARKER']._serialized_start=2364 + _globals['_MARKER']._serialized_end=2895 + _globals['_MARKER_KIND']._serialized_start=2615 + _globals['_MARKER_KIND']._serialized_end=2895 + _globals['_RANGEANDBEARING']._serialized_start=2898 + _globals['_RANGEANDBEARING']._serialized_end=3150 + _globals['_ROUTE']._serialized_start=3153 + _globals['_ROUTE']._serialized_end=3747 + _globals['_ROUTE_LINK']._serialized_start=3401 + _globals['_ROUTE_LINK']._serialized_end=3527 + _globals['_ROUTE_METHOD']._serialized_start=3530 + _globals['_ROUTE_METHOD']._serialized_end=3665 + _globals['_ROUTE_DIRECTION']._serialized_start=3667 + _globals['_ROUTE_DIRECTION']._serialized_end=3747 + _globals['_CASEVACREPORT']._serialized_start=3750 + _globals['_CASEVACREPORT']._serialized_end=5236 + _globals['_CASEVACREPORT_PRECEDENCE']._serialized_start=4758 + _globals['_CASEVACREPORT_PRECEDENCE']._serialized_end=4929 + _globals['_CASEVACREPORT_HLZMARKING']._serialized_start=4932 + _globals['_CASEVACREPORT_HLZMARKING']._serialized_end=5087 + _globals['_CASEVACREPORT_SECURITY']._serialized_start=5090 + _globals['_CASEVACREPORT_SECURITY']._serialized_end=5236 + _globals['_ZMISTENTRY']._serialized_start=5238 + _globals['_ZMISTENTRY']._serialized_end=5320 + _globals['_EMERGENCYALERT']._serialized_start=5323 + _globals['_EMERGENCYALERT']._serialized_end=5615 + _globals['_EMERGENCYALERT_TYPE']._serialized_start=5465 + _globals['_EMERGENCYALERT_TYPE']._serialized_end=5615 + _globals['_TASKREQUEST']._serialized_start=5618 + _globals['_TASKREQUEST']._serialized_end=6118 + _globals['_TASKREQUEST_PRIORITY']._serialized_start=5854 + _globals['_TASKREQUEST_PRIORITY']._serialized_end=5971 + _globals['_TASKREQUEST_STATUS']._serialized_start=5974 + _globals['_TASKREQUEST_STATUS']._serialized_end=6118 + _globals['_TAKENVIRONMENT']._serialized_start=6120 + _globals['_TAKENVIRONMENT']._serialized_end=6216 + _globals['_SENSORFOV']._serialized_start=6219 + _globals['_SENSORFOV']._serialized_end=6625 + _globals['_SENSORFOV_SENSORTYPE']._serialized_start=6443 + _globals['_SENSORFOV_SENSORTYPE']._serialized_end=6613 + _globals['_TAKTALKMESSAGE']._serialized_start=6627 + _globals['_TAKTALKMESSAGE']._serialized_end=6712 + _globals['_TAKTALKROOMDATA']._serialized_start=6714 + _globals['_TAKTALKROOMDATA']._serialized_end=6818 + _globals['_MARTI']._serialized_start=6820 + _globals['_MARTI']._serialized_end=6850 + _globals['_TAKPACKETV2']._serialized_start=6853 + _globals['_TAKPACKETV2']._serialized_end=8437 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/atak_pb2.pyi b/meshtastic/protobuf/atak_pb2.pyi index 9bcd584..6fab863 100644 --- a/meshtastic/protobuf/atak_pb2.pyi +++ b/meshtastic/protobuf/atak_pb2.pyi @@ -4,7 +4,9 @@ isort:skip_file trunk-ignore(buf-lint/PACKAGE_DIRECTORY_MATCH)""" import builtins +import collections.abc import google.protobuf.descriptor +import google.protobuf.internal.containers import google.protobuf.internal.enum_type_wrapper import google.protobuf.message import sys @@ -234,6 +236,1157 @@ Doggo """ global___MemberRole = MemberRole +class _CotHow: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _CotHowEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_CotHow.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + CotHow_Unspecified: _CotHow.ValueType # 0 + """ + Unspecified + """ + CotHow_h_e: _CotHow.ValueType # 1 + """ + Human entered + """ + CotHow_m_g: _CotHow.ValueType # 2 + """ + Machine generated + """ + CotHow_h_g_i_g_o: _CotHow.ValueType # 3 + """ + Human GPS/INS derived + """ + CotHow_m_r: _CotHow.ValueType # 4 + """ + Machine relayed (imported from another system/gateway) + """ + CotHow_m_f: _CotHow.ValueType # 5 + """ + Machine fused (corroborated from multiple sources) + """ + CotHow_m_p: _CotHow.ValueType # 6 + """ + Machine predicted + """ + CotHow_m_s: _CotHow.ValueType # 7 + """ + Machine simulated + """ + +class CotHow(_CotHow, metaclass=_CotHowEnumTypeWrapper): + """ + CoT how field values. + Represents how the coordinates were generated. + """ + +CotHow_Unspecified: CotHow.ValueType # 0 +""" +Unspecified +""" +CotHow_h_e: CotHow.ValueType # 1 +""" +Human entered +""" +CotHow_m_g: CotHow.ValueType # 2 +""" +Machine generated +""" +CotHow_h_g_i_g_o: CotHow.ValueType # 3 +""" +Human GPS/INS derived +""" +CotHow_m_r: CotHow.ValueType # 4 +""" +Machine relayed (imported from another system/gateway) +""" +CotHow_m_f: CotHow.ValueType # 5 +""" +Machine fused (corroborated from multiple sources) +""" +CotHow_m_p: CotHow.ValueType # 6 +""" +Machine predicted +""" +CotHow_m_s: CotHow.ValueType # 7 +""" +Machine simulated +""" +global___CotHow = CotHow + +class _CotType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _CotTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_CotType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + CotType_Other: _CotType.ValueType # 0 + """ + Unknown or unmapped type, use cot_type_str + """ + CotType_a_f_G_U_C: _CotType.ValueType # 1 + """ + a-f-G-U-C: Friendly ground unit combat + """ + CotType_a_f_G_U_C_I: _CotType.ValueType # 2 + """ + a-f-G-U-C-I: Friendly ground unit combat infantry + """ + CotType_a_n_A_C_F: _CotType.ValueType # 3 + """ + a-n-A-C-F: Neutral aircraft civilian fixed-wing + """ + CotType_a_n_A_C_H: _CotType.ValueType # 4 + """ + a-n-A-C-H: Neutral aircraft civilian helicopter + """ + CotType_a_n_A_C: _CotType.ValueType # 5 + """ + a-n-A-C: Neutral aircraft civilian + """ + CotType_a_f_A_M_H: _CotType.ValueType # 6 + """ + a-f-A-M-H: Friendly aircraft military helicopter + """ + CotType_a_f_A_M: _CotType.ValueType # 7 + """ + a-f-A-M: Friendly aircraft military + """ + CotType_a_f_A_M_F_F: _CotType.ValueType # 8 + """ + a-f-A-M-F-F: Friendly aircraft military fixed-wing fighter + """ + CotType_a_f_A_M_H_A: _CotType.ValueType # 9 + """ + a-f-A-M-H-A: Friendly aircraft military helicopter attack + """ + CotType_a_f_A_M_H_U_M: _CotType.ValueType # 10 + """ + a-f-A-M-H-U-M: Friendly aircraft military helicopter utility medium + """ + CotType_a_h_A_M_F_F: _CotType.ValueType # 11 + """ + a-h-A-M-F-F: Hostile aircraft military fixed-wing fighter + """ + CotType_a_h_A_M_H_A: _CotType.ValueType # 12 + """ + a-h-A-M-H-A: Hostile aircraft military helicopter attack + """ + CotType_a_u_A_C: _CotType.ValueType # 13 + """ + a-u-A-C: Unknown aircraft civilian + """ + CotType_t_x_d_d: _CotType.ValueType # 14 + """ + t-x-d-d: Tasking delete/disconnect + """ + CotType_a_f_G_E_S_E: _CotType.ValueType # 15 + """ + a-f-G-E-S-E: Friendly ground equipment sensor + """ + CotType_a_f_G_E_V_C: _CotType.ValueType # 16 + """ + a-f-G-E-V-C: Friendly ground equipment vehicle + """ + CotType_a_f_S: _CotType.ValueType # 17 + """ + a-f-S: Friendly sea + """ + CotType_a_f_A_M_F: _CotType.ValueType # 18 + """ + a-f-A-M-F: Friendly aircraft military fixed-wing + """ + CotType_a_f_A_M_F_C_H: _CotType.ValueType # 19 + """ + a-f-A-M-F-C-H: Friendly aircraft military fixed-wing cargo heavy + """ + CotType_a_f_A_M_F_U_L: _CotType.ValueType # 20 + """ + a-f-A-M-F-U-L: Friendly aircraft military fixed-wing utility light + """ + CotType_a_f_A_M_F_L: _CotType.ValueType # 21 + """ + a-f-A-M-F-L: Friendly aircraft military fixed-wing liaison + """ + CotType_a_f_A_M_F_P: _CotType.ValueType # 22 + """ + a-f-A-M-F-P: Friendly aircraft military fixed-wing patrol + """ + CotType_a_f_A_C_H: _CotType.ValueType # 23 + """ + a-f-A-C-H: Friendly aircraft civilian helicopter + """ + CotType_a_n_A_M_F_Q: _CotType.ValueType # 24 + """ + a-n-A-M-F-Q: Neutral aircraft military fixed-wing drone + """ + CotType_b_t_f: _CotType.ValueType # 25 + """--- Chat / messaging --- + + + b-t-f: GeoChat message + """ + CotType_b_r_f_h_c: _CotType.ValueType # 26 + """--- CASEVAC / MEDEVAC --- + + + b-r-f-h-c: CASEVAC/MEDEVAC report + """ + CotType_b_a_o_pan: _CotType.ValueType # 27 + """--- Alerts --- + + + b-a-o-pan: Ring the bell / alert all + """ + CotType_b_a_o_opn: _CotType.ValueType # 28 + """ + b-a-o-opn: Troops in contact + """ + CotType_b_a_o_can: _CotType.ValueType # 29 + """ + b-a-o-can: Cancel alert + """ + CotType_b_a_o_tbl: _CotType.ValueType # 30 + """ + b-a-o-tbl: 911 alert + """ + CotType_b_a_g: _CotType.ValueType # 31 + """ + b-a-g: Geofence breach alert + """ + CotType_a_f_G: _CotType.ValueType # 32 + """--- Generic ground atoms (simplified affiliation types) --- + + + a-f-G: Friendly ground (generic) + """ + CotType_a_f_G_U: _CotType.ValueType # 33 + """ + a-f-G-U: Friendly ground unit (generic) + """ + CotType_a_h_G: _CotType.ValueType # 34 + """ + a-h-G: Hostile ground (generic) + """ + CotType_a_u_G: _CotType.ValueType # 35 + """ + a-u-G: Unknown ground (generic) + """ + CotType_a_n_G: _CotType.ValueType # 36 + """ + a-n-G: Neutral ground (generic) + """ + CotType_b_m_r: _CotType.ValueType # 37 + """--- Routes and waypoints --- + + + b-m-r: Route + """ + CotType_b_m_p_w: _CotType.ValueType # 38 + """ + b-m-p-w: Route waypoint + """ + CotType_b_m_p_s_p_i: _CotType.ValueType # 39 + """ + b-m-p-s-p-i: Self-position marker + """ + CotType_u_d_f: _CotType.ValueType # 40 + """--- Drawing / tactical graphics --- + + + u-d-f: Freeform shape (line/polygon) + """ + CotType_u_d_r: _CotType.ValueType # 41 + """ + u-d-r: Rectangle + """ + CotType_u_d_c_c: _CotType.ValueType # 42 + """ + u-d-c-c: Circle + """ + CotType_u_rb_a: _CotType.ValueType # 43 + """ + u-rb-a: Range/bearing line + """ + CotType_a_h_A: _CotType.ValueType # 44 + """--- Additional hostile/unknown aircraft --- + + + a-h-A: Hostile aircraft (generic) + """ + CotType_a_u_A: _CotType.ValueType # 45 + """ + a-u-A: Unknown aircraft (generic) + """ + CotType_a_f_A_M_H_Q: _CotType.ValueType # 46 + """ + a-f-A-M-H-Q: Friendly aircraft military helicopter observation + """ + CotType_a_f_A_C_F: _CotType.ValueType # 47 + """Friendly aircraft civilian + + + a-f-A-C-F: Friendly aircraft civilian fixed-wing + """ + CotType_a_f_A_C: _CotType.ValueType # 48 + """ + a-f-A-C: Friendly aircraft civilian (generic) + """ + CotType_a_f_A_C_L: _CotType.ValueType # 49 + """ + a-f-A-C-L: Friendly aircraft civilian lighter-than-air + """ + CotType_a_f_A: _CotType.ValueType # 50 + """ + a-f-A: Friendly aircraft (generic) + """ + CotType_a_f_A_M_H_C: _CotType.ValueType # 51 + """Friendly aircraft military helicopter variants + + + a-f-A-M-H-C: Friendly aircraft military helicopter cargo + """ + CotType_a_n_A_M_F_F: _CotType.ValueType # 52 + """Neutral aircraft military + + + a-n-A-M-F-F: Neutral aircraft military fixed-wing fighter + """ + CotType_a_u_A_C_F: _CotType.ValueType # 53 + """Unknown aircraft civilian + + + a-u-A-C-F: Unknown aircraft civilian fixed-wing + """ + CotType_a_f_G_U_C_F_T_A: _CotType.ValueType # 54 + """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_V_S: _CotType.ValueType # 55 + """ + a-f-G-U-C-V-S: Friendly ground unit combat vehicle support + """ + CotType_a_f_G_U_C_R_X: _CotType.ValueType # 56 + """ + a-f-G-U-C-R-X: Friendly ground unit combat reconnaissance exploitation + """ + CotType_a_f_G_U_C_I_Z: _CotType.ValueType # 57 + """ + a-f-G-U-C-I-Z: Friendly ground unit combat infantry mechanized + """ + CotType_a_f_G_U_C_E_C_W: _CotType.ValueType # 58 + """ + a-f-G-U-C-E-C-W: Friendly ground unit combat engineer construction wheeled + """ + CotType_a_f_G_U_C_I_L: _CotType.ValueType # 59 + """ + a-f-G-U-C-I-L: Friendly ground unit combat infantry light + """ + CotType_a_f_G_U_C_R_O: _CotType.ValueType # 60 + """ + a-f-G-U-C-R-O: Friendly ground unit combat reconnaissance other + """ + CotType_a_f_G_U_C_R_V: _CotType.ValueType # 61 + """ + a-f-G-U-C-R-V: Friendly ground unit combat reconnaissance cavalry + """ + CotType_a_f_G_U_H: _CotType.ValueType # 62 + """ + a-f-G-U-H: Friendly ground unit headquarters + """ + CotType_a_f_G_U_U_M_S_E: _CotType.ValueType # 63 + """ + a-f-G-U-U-M-S-E: Friendly ground unit support medical surgical evacuation + """ + CotType_a_f_G_U_S_M_C: _CotType.ValueType # 64 + """ + a-f-G-U-S-M-C: Friendly ground unit support maintenance collection + """ + CotType_a_f_G_E_S: _CotType.ValueType # 65 + """Friendly ground equipment + + + a-f-G-E-S: Friendly ground equipment sensor (generic) + """ + CotType_a_f_G_E: _CotType.ValueType # 66 + """ + a-f-G-E: Friendly ground equipment (generic) + """ + CotType_a_f_G_E_V_C_U: _CotType.ValueType # 67 + """ + a-f-G-E-V-C-U: Friendly ground equipment vehicle utility + """ + CotType_a_f_G_E_V_C_ps: _CotType.ValueType # 68 + """ + a-f-G-E-V-C-ps: Friendly ground equipment vehicle public safety + """ + CotType_a_u_G_E_V: _CotType.ValueType # 69 + """Unknown ground + + + a-u-G-E-V: Unknown ground equipment vehicle + """ + CotType_a_f_S_N_N_R: _CotType.ValueType # 70 + """Sea + + + a-f-S-N-N-R: Friendly sea surface non-naval rescue + """ + CotType_a_f_F_B: _CotType.ValueType # 71 + """Friendly force (non-domain-specific) + + + a-f-F-B: Friendly force boundary + """ + CotType_b_m_p_s_p_loc: _CotType.ValueType # 72 + """Bits / data messages + + + b-m-p-s-p-loc: Self-position location marker + """ + CotType_b_i_v: _CotType.ValueType # 73 + """ + b-i-v: Imagery/video + """ + CotType_b_f_t_r: _CotType.ValueType # 74 + """ + b-f-t-r: File transfer request + """ + CotType_b_f_t_a: _CotType.ValueType # 75 + """ + b-f-t-a: File transfer acknowledgment + """ + CotType_u_d_f_m: _CotType.ValueType # 76 + """--- 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_p: _CotType.ValueType # 77 + """ + u-d-p: Closed polygon. Geometry carried via DrawnShape.vertices, + implicitly closed (receiver duplicates first vertex as needed). + """ + CotType_b_m_p_s_m: _CotType.ValueType # 78 + """--- Additional markers --- + + + b-m-p-s-m: Spot map marker (colored dot at a point of interest). + """ + CotType_b_m_p_c: _CotType.ValueType # 79 + """ + b-m-p-c: Checkpoint (intermediate route control point). + """ + CotType_u_r_b_c_c: _CotType.ValueType # 80 + """--- Ranging tools --- + + + u-r-b-c-c: Ranging circle (range rings centered on the event point). + """ + CotType_u_r_b_bullseye: _CotType.ValueType # 81 + """ + u-r-b-bullseye: Bullseye with configurable range rings and bearing + reference (magnetic / true / grid). + """ + CotType_a_f_G_E_V_A: _CotType.ValueType # 82 + """--- PLI self-reporting (1) ------------------------------------------ + + + a-f-G-E-V-A: Friendly armored vehicle, user-selectable self PLI. + """ + CotType_a_n_A: _CotType.ValueType # 83 + """--- 2525 quick-drop: basic affiliation gaps ------------------------- + + + a-n-A: Neutral aircraft (friendly/hostile/unknown already present). + """ + CotType_a_u_G_U_C_F: _CotType.ValueType # 84 + """--- 2525 quick-drop: artillery (4) ----------------------------------""" + CotType_a_n_G_U_C_F: _CotType.ValueType # 85 + CotType_a_h_G_U_C_F: _CotType.ValueType # 86 + CotType_a_f_G_U_C_F: _CotType.ValueType # 87 + CotType_a_u_G_I: _CotType.ValueType # 88 + """--- 2525 quick-drop: building (4) -----------------------------------""" + CotType_a_n_G_I: _CotType.ValueType # 89 + CotType_a_h_G_I: _CotType.ValueType # 90 + CotType_a_f_G_I: _CotType.ValueType # 91 + CotType_a_u_G_E_X_M: _CotType.ValueType # 92 + """--- 2525 quick-drop: mine (4) ---------------------------------------""" + CotType_a_n_G_E_X_M: _CotType.ValueType # 93 + CotType_a_h_G_E_X_M: _CotType.ValueType # 94 + CotType_a_f_G_E_X_M: _CotType.ValueType # 95 + CotType_a_u_S: _CotType.ValueType # 96 + """--- 2525 quick-drop: ship (3; a-f-S already at 17) ------------------""" + CotType_a_n_S: _CotType.ValueType # 97 + CotType_a_h_S: _CotType.ValueType # 98 + CotType_a_u_G_U_C_I_d: _CotType.ValueType # 99 + """--- 2525 quick-drop: sniper (4) -------------------------------------""" + CotType_a_n_G_U_C_I_d: _CotType.ValueType # 100 + CotType_a_h_G_U_C_I_d: _CotType.ValueType # 101 + CotType_a_f_G_U_C_I_d: _CotType.ValueType # 102 + CotType_a_u_G_E_V_A_T: _CotType.ValueType # 103 + """--- 2525 quick-drop: tank (4) ---------------------------------------""" + CotType_a_n_G_E_V_A_T: _CotType.ValueType # 104 + CotType_a_h_G_E_V_A_T: _CotType.ValueType # 105 + CotType_a_f_G_E_V_A_T: _CotType.ValueType # 106 + CotType_a_u_G_U_C_I: _CotType.ValueType # 107 + """--- 2525 quick-drop: troops (3; a-f-G-U-C-I already at 2) -----------""" + CotType_a_n_G_U_C_I: _CotType.ValueType # 108 + CotType_a_h_G_U_C_I: _CotType.ValueType # 109 + CotType_a_n_G_E_V: _CotType.ValueType # 110 + """--- 2525 quick-drop: generic vehicle (3; a-u-G-E-V already at 69) ---""" + CotType_a_h_G_E_V: _CotType.ValueType # 111 + CotType_a_f_G_E_V: _CotType.ValueType # 112 + CotType_b_m_p_w_GOTO: _CotType.ValueType # 113 + """--- Mission-specific points (4) ------------------------------------- + + + b-m-p-w-GOTO: Go To / bloodhound navigation target. + """ + CotType_b_m_p_c_ip: _CotType.ValueType # 114 + """ + b-m-p-c-ip: Initial point (mission planning). + """ + CotType_b_m_p_c_cp: _CotType.ValueType # 115 + """ + b-m-p-c-cp: Contact point (mission planning). + """ + CotType_b_m_p_s_p_op: _CotType.ValueType # 116 + """ + b-m-p-s-p-op: Observation post. + """ + CotType_u_d_v: _CotType.ValueType # 117 + """--- Vehicle drawings (2) -------------------------------------------- + + + u-d-v: 2D vehicle outline drawn on the map. + """ + CotType_u_d_v_m: _CotType.ValueType # 118 + """ + u-d-v-m: 3D vehicle model reference. + """ + CotType_u_d_c_e: _CotType.ValueType # 119 + """--- Drawing shapes (1) ---------------------------------------------- + + + u-d-c-e: Non-circular ellipse (circle with distinct major/minor axes). + """ + CotType_b_i_x_i: _CotType.ValueType # 120 + """--- 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_t_f_d: _CotType.ValueType # 121 + """--- 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_r: _CotType.ValueType # 122 + """ + b-t-f-r: GeoChat read receipt. Same wire slot as b-t-f-d. + """ + CotType_b_a_o_c: _CotType.ValueType # 123 + """--- Custom emergency (1) -------------------------------------------- + + + b-a-o-c: Custom / generic emergency beacon. + """ + CotType_t_s: _CotType.ValueType # 124 + """--- Tasking (1) ----------------------------------------------------- + + + t-s: Task / engage request. Structured payload carried via the new + TaskRequest typed variant. + """ + CotType_m_t_t: _CotType.ValueType # 125 + """-- TAKTALK plugin shapes -- + CoT types unique to the TAKTALK ATAK plugin. Note `y-` has a literal + trailing dash and no second atom — that's the wire format ATAK emits + for TAKTALK room broadcasts. The CotType enum encodes the literal + string verbatim (CotType_y -> "y-") so receivers reconstruct the + original event type byte-for-byte without consulting cot_type_str. + + + m-t-t: TAKTALK voice/text chat message. Payload carried via the + TakTalkMessage typed variant (text, chatroom_id, lang, from_voice). + """ + CotType_y: _CotType.ValueType # 126 + """ + y-: TAKTALK room/membership broadcast. Payload carried via the + TakTalkRoomData typed variant (sender_callsign, room_id, room_name, + participants). The CoT type literally has a trailing dash and no + second atom — not a typo. + """ + +class CotType(_CotType, metaclass=_CotTypeEnumTypeWrapper): + """ + 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. + """ + +CotType_Other: CotType.ValueType # 0 +""" +Unknown or unmapped type, use cot_type_str +""" +CotType_a_f_G_U_C: CotType.ValueType # 1 +""" +a-f-G-U-C: Friendly ground unit combat +""" +CotType_a_f_G_U_C_I: CotType.ValueType # 2 +""" +a-f-G-U-C-I: Friendly ground unit combat infantry +""" +CotType_a_n_A_C_F: CotType.ValueType # 3 +""" +a-n-A-C-F: Neutral aircraft civilian fixed-wing +""" +CotType_a_n_A_C_H: CotType.ValueType # 4 +""" +a-n-A-C-H: Neutral aircraft civilian helicopter +""" +CotType_a_n_A_C: CotType.ValueType # 5 +""" +a-n-A-C: Neutral aircraft civilian +""" +CotType_a_f_A_M_H: CotType.ValueType # 6 +""" +a-f-A-M-H: Friendly aircraft military helicopter +""" +CotType_a_f_A_M: CotType.ValueType # 7 +""" +a-f-A-M: Friendly aircraft military +""" +CotType_a_f_A_M_F_F: CotType.ValueType # 8 +""" +a-f-A-M-F-F: Friendly aircraft military fixed-wing fighter +""" +CotType_a_f_A_M_H_A: CotType.ValueType # 9 +""" +a-f-A-M-H-A: Friendly aircraft military helicopter attack +""" +CotType_a_f_A_M_H_U_M: CotType.ValueType # 10 +""" +a-f-A-M-H-U-M: Friendly aircraft military helicopter utility medium +""" +CotType_a_h_A_M_F_F: CotType.ValueType # 11 +""" +a-h-A-M-F-F: Hostile aircraft military fixed-wing fighter +""" +CotType_a_h_A_M_H_A: CotType.ValueType # 12 +""" +a-h-A-M-H-A: Hostile aircraft military helicopter attack +""" +CotType_a_u_A_C: CotType.ValueType # 13 +""" +a-u-A-C: Unknown aircraft civilian +""" +CotType_t_x_d_d: CotType.ValueType # 14 +""" +t-x-d-d: Tasking delete/disconnect +""" +CotType_a_f_G_E_S_E: CotType.ValueType # 15 +""" +a-f-G-E-S-E: Friendly ground equipment sensor +""" +CotType_a_f_G_E_V_C: CotType.ValueType # 16 +""" +a-f-G-E-V-C: Friendly ground equipment vehicle +""" +CotType_a_f_S: CotType.ValueType # 17 +""" +a-f-S: Friendly sea +""" +CotType_a_f_A_M_F: CotType.ValueType # 18 +""" +a-f-A-M-F: Friendly aircraft military fixed-wing +""" +CotType_a_f_A_M_F_C_H: CotType.ValueType # 19 +""" +a-f-A-M-F-C-H: Friendly aircraft military fixed-wing cargo heavy +""" +CotType_a_f_A_M_F_U_L: CotType.ValueType # 20 +""" +a-f-A-M-F-U-L: Friendly aircraft military fixed-wing utility light +""" +CotType_a_f_A_M_F_L: CotType.ValueType # 21 +""" +a-f-A-M-F-L: Friendly aircraft military fixed-wing liaison +""" +CotType_a_f_A_M_F_P: CotType.ValueType # 22 +""" +a-f-A-M-F-P: Friendly aircraft military fixed-wing patrol +""" +CotType_a_f_A_C_H: CotType.ValueType # 23 +""" +a-f-A-C-H: Friendly aircraft civilian helicopter +""" +CotType_a_n_A_M_F_Q: CotType.ValueType # 24 +""" +a-n-A-M-F-Q: Neutral aircraft military fixed-wing drone +""" +CotType_b_t_f: CotType.ValueType # 25 +"""--- Chat / messaging --- + + +b-t-f: GeoChat message +""" +CotType_b_r_f_h_c: CotType.ValueType # 26 +"""--- CASEVAC / MEDEVAC --- + + +b-r-f-h-c: CASEVAC/MEDEVAC report +""" +CotType_b_a_o_pan: CotType.ValueType # 27 +"""--- Alerts --- + + +b-a-o-pan: Ring the bell / alert all +""" +CotType_b_a_o_opn: CotType.ValueType # 28 +""" +b-a-o-opn: Troops in contact +""" +CotType_b_a_o_can: CotType.ValueType # 29 +""" +b-a-o-can: Cancel alert +""" +CotType_b_a_o_tbl: CotType.ValueType # 30 +""" +b-a-o-tbl: 911 alert +""" +CotType_b_a_g: CotType.ValueType # 31 +""" +b-a-g: Geofence breach alert +""" +CotType_a_f_G: CotType.ValueType # 32 +"""--- Generic ground atoms (simplified affiliation types) --- + + +a-f-G: Friendly ground (generic) +""" +CotType_a_f_G_U: CotType.ValueType # 33 +""" +a-f-G-U: Friendly ground unit (generic) +""" +CotType_a_h_G: CotType.ValueType # 34 +""" +a-h-G: Hostile ground (generic) +""" +CotType_a_u_G: CotType.ValueType # 35 +""" +a-u-G: Unknown ground (generic) +""" +CotType_a_n_G: CotType.ValueType # 36 +""" +a-n-G: Neutral ground (generic) +""" +CotType_b_m_r: CotType.ValueType # 37 +"""--- Routes and waypoints --- + + +b-m-r: Route +""" +CotType_b_m_p_w: CotType.ValueType # 38 +""" +b-m-p-w: Route waypoint +""" +CotType_b_m_p_s_p_i: CotType.ValueType # 39 +""" +b-m-p-s-p-i: Self-position marker +""" +CotType_u_d_f: CotType.ValueType # 40 +"""--- Drawing / tactical graphics --- + + +u-d-f: Freeform shape (line/polygon) +""" +CotType_u_d_r: CotType.ValueType # 41 +""" +u-d-r: Rectangle +""" +CotType_u_d_c_c: CotType.ValueType # 42 +""" +u-d-c-c: Circle +""" +CotType_u_rb_a: CotType.ValueType # 43 +""" +u-rb-a: Range/bearing line +""" +CotType_a_h_A: CotType.ValueType # 44 +"""--- Additional hostile/unknown aircraft --- + + +a-h-A: Hostile aircraft (generic) +""" +CotType_a_u_A: CotType.ValueType # 45 +""" +a-u-A: Unknown aircraft (generic) +""" +CotType_a_f_A_M_H_Q: CotType.ValueType # 46 +""" +a-f-A-M-H-Q: Friendly aircraft military helicopter observation +""" +CotType_a_f_A_C_F: CotType.ValueType # 47 +"""Friendly aircraft civilian + + +a-f-A-C-F: Friendly aircraft civilian fixed-wing +""" +CotType_a_f_A_C: CotType.ValueType # 48 +""" +a-f-A-C: Friendly aircraft civilian (generic) +""" +CotType_a_f_A_C_L: CotType.ValueType # 49 +""" +a-f-A-C-L: Friendly aircraft civilian lighter-than-air +""" +CotType_a_f_A: CotType.ValueType # 50 +""" +a-f-A: Friendly aircraft (generic) +""" +CotType_a_f_A_M_H_C: CotType.ValueType # 51 +"""Friendly aircraft military helicopter variants + + +a-f-A-M-H-C: Friendly aircraft military helicopter cargo +""" +CotType_a_n_A_M_F_F: CotType.ValueType # 52 +"""Neutral aircraft military + + +a-n-A-M-F-F: Neutral aircraft military fixed-wing fighter +""" +CotType_a_u_A_C_F: CotType.ValueType # 53 +"""Unknown aircraft civilian + + +a-u-A-C-F: Unknown aircraft civilian fixed-wing +""" +CotType_a_f_G_U_C_F_T_A: CotType.ValueType # 54 +"""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_V_S: CotType.ValueType # 55 +""" +a-f-G-U-C-V-S: Friendly ground unit combat vehicle support +""" +CotType_a_f_G_U_C_R_X: CotType.ValueType # 56 +""" +a-f-G-U-C-R-X: Friendly ground unit combat reconnaissance exploitation +""" +CotType_a_f_G_U_C_I_Z: CotType.ValueType # 57 +""" +a-f-G-U-C-I-Z: Friendly ground unit combat infantry mechanized +""" +CotType_a_f_G_U_C_E_C_W: CotType.ValueType # 58 +""" +a-f-G-U-C-E-C-W: Friendly ground unit combat engineer construction wheeled +""" +CotType_a_f_G_U_C_I_L: CotType.ValueType # 59 +""" +a-f-G-U-C-I-L: Friendly ground unit combat infantry light +""" +CotType_a_f_G_U_C_R_O: CotType.ValueType # 60 +""" +a-f-G-U-C-R-O: Friendly ground unit combat reconnaissance other +""" +CotType_a_f_G_U_C_R_V: CotType.ValueType # 61 +""" +a-f-G-U-C-R-V: Friendly ground unit combat reconnaissance cavalry +""" +CotType_a_f_G_U_H: CotType.ValueType # 62 +""" +a-f-G-U-H: Friendly ground unit headquarters +""" +CotType_a_f_G_U_U_M_S_E: CotType.ValueType # 63 +""" +a-f-G-U-U-M-S-E: Friendly ground unit support medical surgical evacuation +""" +CotType_a_f_G_U_S_M_C: CotType.ValueType # 64 +""" +a-f-G-U-S-M-C: Friendly ground unit support maintenance collection +""" +CotType_a_f_G_E_S: CotType.ValueType # 65 +"""Friendly ground equipment + + +a-f-G-E-S: Friendly ground equipment sensor (generic) +""" +CotType_a_f_G_E: CotType.ValueType # 66 +""" +a-f-G-E: Friendly ground equipment (generic) +""" +CotType_a_f_G_E_V_C_U: CotType.ValueType # 67 +""" +a-f-G-E-V-C-U: Friendly ground equipment vehicle utility +""" +CotType_a_f_G_E_V_C_ps: CotType.ValueType # 68 +""" +a-f-G-E-V-C-ps: Friendly ground equipment vehicle public safety +""" +CotType_a_u_G_E_V: CotType.ValueType # 69 +"""Unknown ground + + +a-u-G-E-V: Unknown ground equipment vehicle +""" +CotType_a_f_S_N_N_R: CotType.ValueType # 70 +"""Sea + + +a-f-S-N-N-R: Friendly sea surface non-naval rescue +""" +CotType_a_f_F_B: CotType.ValueType # 71 +"""Friendly force (non-domain-specific) + + +a-f-F-B: Friendly force boundary +""" +CotType_b_m_p_s_p_loc: CotType.ValueType # 72 +"""Bits / data messages + + +b-m-p-s-p-loc: Self-position location marker +""" +CotType_b_i_v: CotType.ValueType # 73 +""" +b-i-v: Imagery/video +""" +CotType_b_f_t_r: CotType.ValueType # 74 +""" +b-f-t-r: File transfer request +""" +CotType_b_f_t_a: CotType.ValueType # 75 +""" +b-f-t-a: File transfer acknowledgment +""" +CotType_u_d_f_m: CotType.ValueType # 76 +"""--- 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_p: CotType.ValueType # 77 +""" +u-d-p: Closed polygon. Geometry carried via DrawnShape.vertices, +implicitly closed (receiver duplicates first vertex as needed). +""" +CotType_b_m_p_s_m: CotType.ValueType # 78 +"""--- Additional markers --- + + +b-m-p-s-m: Spot map marker (colored dot at a point of interest). +""" +CotType_b_m_p_c: CotType.ValueType # 79 +""" +b-m-p-c: Checkpoint (intermediate route control point). +""" +CotType_u_r_b_c_c: CotType.ValueType # 80 +"""--- Ranging tools --- + + +u-r-b-c-c: Ranging circle (range rings centered on the event point). +""" +CotType_u_r_b_bullseye: CotType.ValueType # 81 +""" +u-r-b-bullseye: Bullseye with configurable range rings and bearing +reference (magnetic / true / grid). +""" +CotType_a_f_G_E_V_A: CotType.ValueType # 82 +"""--- PLI self-reporting (1) ------------------------------------------ + + +a-f-G-E-V-A: Friendly armored vehicle, user-selectable self PLI. +""" +CotType_a_n_A: CotType.ValueType # 83 +"""--- 2525 quick-drop: basic affiliation gaps ------------------------- + + +a-n-A: Neutral aircraft (friendly/hostile/unknown already present). +""" +CotType_a_u_G_U_C_F: CotType.ValueType # 84 +"""--- 2525 quick-drop: artillery (4) ----------------------------------""" +CotType_a_n_G_U_C_F: CotType.ValueType # 85 +CotType_a_h_G_U_C_F: CotType.ValueType # 86 +CotType_a_f_G_U_C_F: CotType.ValueType # 87 +CotType_a_u_G_I: CotType.ValueType # 88 +"""--- 2525 quick-drop: building (4) -----------------------------------""" +CotType_a_n_G_I: CotType.ValueType # 89 +CotType_a_h_G_I: CotType.ValueType # 90 +CotType_a_f_G_I: CotType.ValueType # 91 +CotType_a_u_G_E_X_M: CotType.ValueType # 92 +"""--- 2525 quick-drop: mine (4) ---------------------------------------""" +CotType_a_n_G_E_X_M: CotType.ValueType # 93 +CotType_a_h_G_E_X_M: CotType.ValueType # 94 +CotType_a_f_G_E_X_M: CotType.ValueType # 95 +CotType_a_u_S: CotType.ValueType # 96 +"""--- 2525 quick-drop: ship (3; a-f-S already at 17) ------------------""" +CotType_a_n_S: CotType.ValueType # 97 +CotType_a_h_S: CotType.ValueType # 98 +CotType_a_u_G_U_C_I_d: CotType.ValueType # 99 +"""--- 2525 quick-drop: sniper (4) -------------------------------------""" +CotType_a_n_G_U_C_I_d: CotType.ValueType # 100 +CotType_a_h_G_U_C_I_d: CotType.ValueType # 101 +CotType_a_f_G_U_C_I_d: CotType.ValueType # 102 +CotType_a_u_G_E_V_A_T: CotType.ValueType # 103 +"""--- 2525 quick-drop: tank (4) ---------------------------------------""" +CotType_a_n_G_E_V_A_T: CotType.ValueType # 104 +CotType_a_h_G_E_V_A_T: CotType.ValueType # 105 +CotType_a_f_G_E_V_A_T: CotType.ValueType # 106 +CotType_a_u_G_U_C_I: CotType.ValueType # 107 +"""--- 2525 quick-drop: troops (3; a-f-G-U-C-I already at 2) -----------""" +CotType_a_n_G_U_C_I: CotType.ValueType # 108 +CotType_a_h_G_U_C_I: CotType.ValueType # 109 +CotType_a_n_G_E_V: CotType.ValueType # 110 +"""--- 2525 quick-drop: generic vehicle (3; a-u-G-E-V already at 69) ---""" +CotType_a_h_G_E_V: CotType.ValueType # 111 +CotType_a_f_G_E_V: CotType.ValueType # 112 +CotType_b_m_p_w_GOTO: CotType.ValueType # 113 +"""--- Mission-specific points (4) ------------------------------------- + + +b-m-p-w-GOTO: Go To / bloodhound navigation target. +""" +CotType_b_m_p_c_ip: CotType.ValueType # 114 +""" +b-m-p-c-ip: Initial point (mission planning). +""" +CotType_b_m_p_c_cp: CotType.ValueType # 115 +""" +b-m-p-c-cp: Contact point (mission planning). +""" +CotType_b_m_p_s_p_op: CotType.ValueType # 116 +""" +b-m-p-s-p-op: Observation post. +""" +CotType_u_d_v: CotType.ValueType # 117 +"""--- Vehicle drawings (2) -------------------------------------------- + + +u-d-v: 2D vehicle outline drawn on the map. +""" +CotType_u_d_v_m: CotType.ValueType # 118 +""" +u-d-v-m: 3D vehicle model reference. +""" +CotType_u_d_c_e: CotType.ValueType # 119 +"""--- Drawing shapes (1) ---------------------------------------------- + + +u-d-c-e: Non-circular ellipse (circle with distinct major/minor axes). +""" +CotType_b_i_x_i: CotType.ValueType # 120 +"""--- 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_t_f_d: CotType.ValueType # 121 +"""--- 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_r: CotType.ValueType # 122 +""" +b-t-f-r: GeoChat read receipt. Same wire slot as b-t-f-d. +""" +CotType_b_a_o_c: CotType.ValueType # 123 +"""--- Custom emergency (1) -------------------------------------------- + + +b-a-o-c: Custom / generic emergency beacon. +""" +CotType_t_s: CotType.ValueType # 124 +"""--- Tasking (1) ----------------------------------------------------- + + +t-s: Task / engage request. Structured payload carried via the new +TaskRequest typed variant. +""" +CotType_m_t_t: CotType.ValueType # 125 +"""-- TAKTALK plugin shapes -- +CoT types unique to the TAKTALK ATAK plugin. Note `y-` has a literal +trailing dash and no second atom — that's the wire format ATAK emits +for TAKTALK room broadcasts. The CotType enum encodes the literal +string verbatim (CotType_y -> "y-") so receivers reconstruct the +original event type byte-for-byte without consulting cot_type_str. + + +m-t-t: TAKTALK voice/text chat message. Payload carried via the +TakTalkMessage typed variant (text, chatroom_id, lang, from_voice). +""" +CotType_y: CotType.ValueType # 126 +""" +y-: TAKTALK room/membership broadcast. Payload carried via the +TakTalkRoomData typed variant (sender_callsign, room_id, room_name, +participants). The CoT type literally has a trailing dash and no +second atom — not a typo. +""" +global___CotType = CotType + +class _GeoPointSource: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _GeoPointSourceEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_GeoPointSource.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + GeoPointSource_Unspecified: _GeoPointSource.ValueType # 0 + """ + Unspecified + """ + GeoPointSource_GPS: _GeoPointSource.ValueType # 1 + """ + GPS derived + """ + GeoPointSource_USER: _GeoPointSource.ValueType # 2 + """ + User entered + """ + GeoPointSource_NETWORK: _GeoPointSource.ValueType # 3 + """ + Network/external + """ + +class GeoPointSource(_GeoPointSource, metaclass=_GeoPointSourceEnumTypeWrapper): + """ + Geopoint and altitude source + """ + +GeoPointSource_Unspecified: GeoPointSource.ValueType # 0 +""" +Unspecified +""" +GeoPointSource_GPS: GeoPointSource.ValueType # 1 +""" +GPS derived +""" +GeoPointSource_USER: GeoPointSource.ValueType # 2 +""" +User entered +""" +GeoPointSource_NETWORK: GeoPointSource.ValueType # 3 +""" +Network/external +""" +global___GeoPointSource = GeoPointSource + @typing.final class TAKPacket(google.protobuf.message.Message): """ @@ -313,12 +1466,47 @@ class GeoChat(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor + class _ReceiptType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _ReceiptTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[GeoChat._ReceiptType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + ReceiptType_None: GeoChat._ReceiptType.ValueType # 0 + """normal chat message""" + ReceiptType_Delivered: GeoChat._ReceiptType.ValueType # 1 + """b-t-f-d delivered receipt""" + ReceiptType_Read: GeoChat._ReceiptType.ValueType # 2 + """b-t-f-r read receipt""" + + class ReceiptType(_ReceiptType, metaclass=_ReceiptTypeEnumTypeWrapper): + """ + 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. + """ + + ReceiptType_None: GeoChat.ReceiptType.ValueType # 0 + """normal chat message""" + ReceiptType_Delivered: GeoChat.ReceiptType.ValueType # 1 + """b-t-f-d delivered receipt""" + ReceiptType_Read: GeoChat.ReceiptType.ValueType # 2 + """b-t-f-r read receipt""" + MESSAGE_FIELD_NUMBER: builtins.int TO_FIELD_NUMBER: builtins.int TO_CALLSIGN_FIELD_NUMBER: builtins.int + RECEIPT_FOR_UID_FIELD_NUMBER: builtins.int + RECEIPT_TYPE_FIELD_NUMBER: builtins.int + LANG_FIELD_NUMBER: builtins.int + ROOM_ID_FIELD_NUMBER: builtins.int + VOICE_PROFILE_ID_FIELD_NUMBER: builtins.int message: builtins.str """ - The text message + The text message. Empty for receipts. """ to: builtins.str """ @@ -328,19 +1516,75 @@ class GeoChat(google.protobuf.message.Message): """ Callsign of the recipient for the message """ + receipt_for_uid: builtins.str + """ + 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. + """ + receipt_type: global___GeoChat.ReceiptType.ValueType + """ + Receipt kind discriminator. See ReceiptType doc. Default ReceiptType_None + means this is a regular chat message, not a receipt. + """ + lang: builtins.str + """ + --- TAKTALK-flavored b-t-f extensions --- + + Set when the ATAK TAKTALK plugin originates the chat, so the message + carries the room/language metadata TAKTALK uses to thread its UI. + These fields are absent / empty for non-TAKTALK CoT chat, so the wire + cost is paid only when TAKTALK is actually involved. + + Wire shape in source XML (inside /): + English - lang + UUID - room_id + X - voice_profile_id + - empty marker; encoded as + present-but-empty string + + + BCP-47-ish language tag or human-readable name (e.g. "en", "English") + that the originator's TAKTALK plugin recorded for the message. + """ + room_id: builtins.str + """ + TAKTALK chatroom UUID (e.g. "30b2755c-c547-44ef-a0cc-cdbd8a15616f") that + the receiver's TAKTALK plugin uses to thread the message under the + right room. Resolved to a friendly name via TakTalkRoomData broadcasts. + """ + voice_profile_id: builtins.str + """ + TAKTALK voice profile pointer. Often empty in practice (the empty + marker `` still signals TAKTALK origination), so + receivers should treat empty-but-present as the equivalent of the + marker rather than a missing field. + """ def __init__( self, *, message: builtins.str = ..., to: builtins.str | None = ..., to_callsign: builtins.str | None = ..., + receipt_for_uid: builtins.str = ..., + receipt_type: global___GeoChat.ReceiptType.ValueType = ..., + lang: builtins.str | None = ..., + room_id: builtins.str | None = ..., + voice_profile_id: builtins.str | None = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["_to", b"_to", "_to_callsign", b"_to_callsign", "to", b"to", "to_callsign", b"to_callsign"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["_to", b"_to", "_to_callsign", b"_to_callsign", "message", b"message", "to", b"to", "to_callsign", b"to_callsign"]) -> None: ... + def HasField(self, field_name: typing.Literal["_lang", b"_lang", "_room_id", b"_room_id", "_to", b"_to", "_to_callsign", b"_to_callsign", "_voice_profile_id", b"_voice_profile_id", "lang", b"lang", "room_id", b"room_id", "to", b"to", "to_callsign", b"to_callsign", "voice_profile_id", b"voice_profile_id"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_lang", b"_lang", "_room_id", b"_room_id", "_to", b"_to", "_to_callsign", b"_to_callsign", "_voice_profile_id", b"_voice_profile_id", "lang", b"lang", "message", b"message", "receipt_for_uid", b"receipt_for_uid", "receipt_type", b"receipt_type", "room_id", b"room_id", "to", b"to", "to_callsign", b"to_callsign", "voice_profile_id", b"voice_profile_id"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_lang", b"_lang"]) -> typing.Literal["lang"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_room_id", b"_room_id"]) -> typing.Literal["room_id"] | None: ... @typing.overload def WhichOneof(self, oneof_group: typing.Literal["_to", b"_to"]) -> typing.Literal["to"] | None: ... @typing.overload def WhichOneof(self, oneof_group: typing.Literal["_to_callsign", b"_to_callsign"]) -> typing.Literal["to_callsign"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_voice_profile_id", b"_voice_profile_id"]) -> typing.Literal["voice_profile_id"] | None: ... global___GeoChat = GeoChat @@ -475,3 +1719,2133 @@ class PLI(google.protobuf.message.Message): def ClearField(self, field_name: typing.Literal["altitude", b"altitude", "course", b"course", "latitude_i", b"latitude_i", "longitude_i", b"longitude_i", "speed", b"speed"]) -> None: ... global___PLI = PLI + +@typing.final +class AircraftTrack(google.protobuf.message.Message): + """ + Aircraft track information from ADS-B or military air tracking. + Covers the majority of observed real-world CoT traffic. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ICAO_FIELD_NUMBER: builtins.int + REGISTRATION_FIELD_NUMBER: builtins.int + FLIGHT_FIELD_NUMBER: builtins.int + AIRCRAFT_TYPE_FIELD_NUMBER: builtins.int + SQUAWK_FIELD_NUMBER: builtins.int + CATEGORY_FIELD_NUMBER: builtins.int + RSSI_X10_FIELD_NUMBER: builtins.int + GPS_FIELD_NUMBER: builtins.int + COT_HOST_ID_FIELD_NUMBER: builtins.int + icao: builtins.str + """ + ICAO hex identifier (e.g. "AD237C") + """ + registration: builtins.str + """ + Aircraft registration (e.g. "N946AK") + """ + flight: builtins.str + """ + Flight number/callsign (e.g. "ASA864") + """ + aircraft_type: builtins.str + """ + ICAO aircraft type designator (e.g. "B39M") + """ + squawk: builtins.int + """ + Transponder squawk code (0-7777 octal) + """ + category: builtins.str + """ + ADS-B emitter category (e.g. "A3") + """ + rssi_x10: builtins.int + """ + Received signal strength * 10 (e.g. -194 for -19.4 dBm) + """ + gps: builtins.bool + """ + Whether receiver has GPS fix + """ + cot_host_id: builtins.str + """ + CoT host ID for source attribution + """ + def __init__( + self, + *, + icao: builtins.str = ..., + registration: builtins.str = ..., + flight: builtins.str = ..., + aircraft_type: builtins.str = ..., + squawk: builtins.int = ..., + category: builtins.str = ..., + rssi_x10: builtins.int = ..., + gps: builtins.bool = ..., + cot_host_id: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["aircraft_type", b"aircraft_type", "category", b"category", "cot_host_id", b"cot_host_id", "flight", b"flight", "gps", b"gps", "icao", b"icao", "registration", b"registration", "rssi_x10", b"rssi_x10", "squawk", b"squawk"]) -> None: ... + +global___AircraftTrack = AircraftTrack + +@typing.final +class CotGeoPoint(google.protobuf.message.Message): + """ + 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. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + LAT_DELTA_I_FIELD_NUMBER: builtins.int + LON_DELTA_I_FIELD_NUMBER: builtins.int + lat_delta_i: builtins.int + """ + Latitude delta from TAKPacketV2.latitude_i, in 1e-7 degree units. + Add to the enclosing event's latitude_i to recover the absolute latitude. + """ + lon_delta_i: builtins.int + """ + Longitude delta from TAKPacketV2.longitude_i, in 1e-7 degree units. + """ + def __init__( + self, + *, + lat_delta_i: builtins.int = ..., + lon_delta_i: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["lat_delta_i", b"lat_delta_i", "lon_delta_i", b"lon_delta_i"]) -> None: ... + +global___CotGeoPoint = CotGeoPoint + +@typing.final +class DrawnShape(google.protobuf.message.Message): + """ + 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. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _Kind: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _KindEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[DrawnShape._Kind.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + Kind_Unspecified: DrawnShape._Kind.ValueType # 0 + """ + Unspecified (do not use on the wire) + """ + Kind_Circle: DrawnShape._Kind.ValueType # 1 + """ + u-d-c-c: User-drawn circle (uses major/minor/angle, anchor = event point) + """ + Kind_Rectangle: DrawnShape._Kind.ValueType # 2 + """ + u-d-r: User-drawn rectangle (uses vertices = 4 corners) + """ + Kind_Freeform: DrawnShape._Kind.ValueType # 3 + """ + u-d-f: User-drawn polyline (uses vertices, not closed) + """ + Kind_Telestration: DrawnShape._Kind.ValueType # 4 + """ + u-d-f-m: Freehand telestration / annotation (uses vertices, may be truncated) + """ + Kind_Polygon: DrawnShape._Kind.ValueType # 5 + """ + u-d-p: Closed polygon (uses vertices, implicitly closed) + """ + Kind_RangingCircle: DrawnShape._Kind.ValueType # 6 + """ + u-r-b-c-c: Ranging circle (major/minor/angle, stroke + optional fill) + """ + Kind_Bullseye: DrawnShape._Kind.ValueType # 7 + """ + u-r-b-bullseye: Bullseye ring with range rings and bearing reference + """ + Kind_Ellipse: DrawnShape._Kind.ValueType # 8 + """ + 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_Vehicle2D: DrawnShape._Kind.ValueType # 9 + """ + u-d-v: 2D vehicle outline drawn on the map. Vertices carry the + outline polygon; receivers draw it as a filled polygon. + """ + Kind_Vehicle3D: DrawnShape._Kind.ValueType # 10 + """ + u-d-v-m: 3D vehicle model reference. Same vertex polygon as + Kind_Vehicle2D; receivers that support 3D rendering extrude it. + """ + + class Kind(_Kind, metaclass=_KindEnumTypeWrapper): + """ + Shape kind discriminator. Drives receiver rendering and also controls + which optional fields below are meaningful. + """ + + Kind_Unspecified: DrawnShape.Kind.ValueType # 0 + """ + Unspecified (do not use on the wire) + """ + Kind_Circle: DrawnShape.Kind.ValueType # 1 + """ + u-d-c-c: User-drawn circle (uses major/minor/angle, anchor = event point) + """ + Kind_Rectangle: DrawnShape.Kind.ValueType # 2 + """ + u-d-r: User-drawn rectangle (uses vertices = 4 corners) + """ + Kind_Freeform: DrawnShape.Kind.ValueType # 3 + """ + u-d-f: User-drawn polyline (uses vertices, not closed) + """ + Kind_Telestration: DrawnShape.Kind.ValueType # 4 + """ + u-d-f-m: Freehand telestration / annotation (uses vertices, may be truncated) + """ + Kind_Polygon: DrawnShape.Kind.ValueType # 5 + """ + u-d-p: Closed polygon (uses vertices, implicitly closed) + """ + Kind_RangingCircle: DrawnShape.Kind.ValueType # 6 + """ + u-r-b-c-c: Ranging circle (major/minor/angle, stroke + optional fill) + """ + Kind_Bullseye: DrawnShape.Kind.ValueType # 7 + """ + u-r-b-bullseye: Bullseye ring with range rings and bearing reference + """ + Kind_Ellipse: DrawnShape.Kind.ValueType # 8 + """ + 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_Vehicle2D: DrawnShape.Kind.ValueType # 9 + """ + u-d-v: 2D vehicle outline drawn on the map. Vertices carry the + outline polygon; receivers draw it as a filled polygon. + """ + Kind_Vehicle3D: DrawnShape.Kind.ValueType # 10 + """ + u-d-v-m: 3D vehicle model reference. Same vertex polygon as + Kind_Vehicle2D; receivers that support 3D rendering extrude it. + """ + + class _StyleMode: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _StyleModeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[DrawnShape._StyleMode.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + StyleMode_Unspecified: DrawnShape._StyleMode.ValueType # 0 + """ + Unspecified — receiver infers from which color fields are non-zero. + """ + StyleMode_StrokeOnly: DrawnShape._StyleMode.ValueType # 1 + """ + Stroke only. No in the source XML. Used for polylines, + ranging lines, bullseye rings. + """ + StyleMode_FillOnly: DrawnShape._StyleMode.ValueType # 2 + """ + Fill only. No in the source XML. Rare but valid in + ATAK (solid region with no outline). + """ + StyleMode_StrokeAndFill: DrawnShape._StyleMode.ValueType # 3 + """ + Both stroke and fill present. Closed shapes: circle, rectangle, + polygon, ranging circle. + """ + + class StyleMode(_StyleMode, metaclass=_StyleModeEnumTypeWrapper): + """ + 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. + """ + + StyleMode_Unspecified: DrawnShape.StyleMode.ValueType # 0 + """ + Unspecified — receiver infers from which color fields are non-zero. + """ + StyleMode_StrokeOnly: DrawnShape.StyleMode.ValueType # 1 + """ + Stroke only. No in the source XML. Used for polylines, + ranging lines, bullseye rings. + """ + StyleMode_FillOnly: DrawnShape.StyleMode.ValueType # 2 + """ + Fill only. No in the source XML. Rare but valid in + ATAK (solid region with no outline). + """ + StyleMode_StrokeAndFill: DrawnShape.StyleMode.ValueType # 3 + """ + Both stroke and fill present. Closed shapes: circle, rectangle, + polygon, ranging circle. + """ + + KIND_FIELD_NUMBER: builtins.int + STYLE_FIELD_NUMBER: builtins.int + MAJOR_CM_FIELD_NUMBER: builtins.int + MINOR_CM_FIELD_NUMBER: builtins.int + ANGLE_DEG_FIELD_NUMBER: builtins.int + STROKE_COLOR_FIELD_NUMBER: builtins.int + STROKE_ARGB_FIELD_NUMBER: builtins.int + STROKE_WEIGHT_X10_FIELD_NUMBER: builtins.int + FILL_COLOR_FIELD_NUMBER: builtins.int + FILL_ARGB_FIELD_NUMBER: builtins.int + LABELS_ON_FIELD_NUMBER: builtins.int + VERTEX_LAT_DELTAS_FIELD_NUMBER: builtins.int + VERTEX_LON_DELTAS_FIELD_NUMBER: builtins.int + TRUNCATED_FIELD_NUMBER: builtins.int + BULLSEYE_DISTANCE_DM_FIELD_NUMBER: builtins.int + BULLSEYE_BEARING_REF_FIELD_NUMBER: builtins.int + BULLSEYE_FLAGS_FIELD_NUMBER: builtins.int + BULLSEYE_UID_REF_FIELD_NUMBER: builtins.int + kind: global___DrawnShape.Kind.ValueType + """ + Shape kind (circle, rectangle, freeform, etc.) + """ + style: global___DrawnShape.StyleMode.ValueType + """ + Explicit stroke/fill/both discriminator. See StyleMode doc. + """ + major_cm: builtins.int + """ + Ellipse major radius in centimeters. 0 for non-ellipse kinds. + """ + minor_cm: builtins.int + """ + Ellipse minor radius in centimeters. 0 for non-ellipse kinds. + """ + angle_deg: builtins.int + """ + 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. + """ + stroke_color: global___Team.ValueType + """ + 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. + """ + stroke_argb: builtins.int + """ + 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. + """ + stroke_weight_x10: builtins.int + """ + Stroke weight in tenths of a unit (e.g. 30 = 3.0). Typical ATAK + range 10..60. + """ + fill_color: global___Team.ValueType + """ + Fill color as a named palette entry. See stroke_color docs. + Valid only when style is FillOnly or StrokeAndFill. + """ + fill_argb: builtins.int + """ + Fill color exact ARGB fallback. See stroke_argb docs. + """ + labels_on: builtins.bool + """ + Whether labels are rendered on this shape. + """ + truncated: builtins.bool + """ + True if the sender truncated the vertex columns to fit the pool. + --- Bullseye-only fields. All ignored unless kind == Kind_Bullseye. --- + """ + bullseye_distance_dm: builtins.int + """ + Bullseye distance in meters * 10 (e.g. 3285 = 328.5 m). 0 = unset. + """ + bullseye_bearing_ref: builtins.int + """ + Bullseye bearing reference: 0 unset, 1 Magnetic, 2 True, 3 Grid. + """ + bullseye_flags: builtins.int + """ + Bullseye attribute bit flags: + bit 0: rangeRingVisible + bit 1: hasRangeRings + bit 2: edgeToCenter + bit 3: mils + """ + bullseye_uid_ref: builtins.str + """ + Bullseye reference UID (anchor marker). Empty = anchor is self. + """ + @property + def vertex_lat_deltas(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: ... + @property + def vertex_lon_deltas(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: ... + def __init__( + self, + *, + kind: global___DrawnShape.Kind.ValueType = ..., + style: global___DrawnShape.StyleMode.ValueType = ..., + major_cm: builtins.int = ..., + minor_cm: builtins.int = ..., + angle_deg: builtins.int = ..., + stroke_color: global___Team.ValueType = ..., + stroke_argb: builtins.int = ..., + stroke_weight_x10: builtins.int = ..., + fill_color: global___Team.ValueType = ..., + fill_argb: builtins.int = ..., + labels_on: builtins.bool = ..., + vertex_lat_deltas: collections.abc.Iterable[builtins.int] | None = ..., + vertex_lon_deltas: collections.abc.Iterable[builtins.int] | None = ..., + truncated: builtins.bool = ..., + bullseye_distance_dm: builtins.int = ..., + bullseye_bearing_ref: builtins.int = ..., + bullseye_flags: builtins.int = ..., + bullseye_uid_ref: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["angle_deg", b"angle_deg", "bullseye_bearing_ref", b"bullseye_bearing_ref", "bullseye_distance_dm", b"bullseye_distance_dm", "bullseye_flags", b"bullseye_flags", "bullseye_uid_ref", b"bullseye_uid_ref", "fill_argb", b"fill_argb", "fill_color", b"fill_color", "kind", b"kind", "labels_on", b"labels_on", "major_cm", b"major_cm", "minor_cm", b"minor_cm", "stroke_argb", b"stroke_argb", "stroke_color", b"stroke_color", "stroke_weight_x10", b"stroke_weight_x10", "style", b"style", "truncated", b"truncated", "vertex_lat_deltas", b"vertex_lat_deltas", "vertex_lon_deltas", b"vertex_lon_deltas"]) -> None: ... + +global___DrawnShape = DrawnShape + +@typing.final +class Marker(google.protobuf.message.Message): + """ + 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. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _Kind: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _KindEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Marker._Kind.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + Kind_Unspecified: Marker._Kind.ValueType # 0 + """ + Unspecified — fall back to TAKPacketV2.cot_type_id + """ + Kind_Spot: Marker._Kind.ValueType # 1 + """ + b-m-p-s-m: Spot map marker + """ + Kind_Waypoint: Marker._Kind.ValueType # 2 + """ + b-m-p-w: Route waypoint + """ + Kind_Checkpoint: Marker._Kind.ValueType # 3 + """ + b-m-p-c: Checkpoint + """ + Kind_SelfPosition: Marker._Kind.ValueType # 4 + """ + b-m-p-s-p-i / b-m-p-s-p-loc: Self-position marker + """ + Kind_Symbol2525: Marker._Kind.ValueType # 5 + """ + 2525B/C military symbol (iconsetpath = COT_MAPPING_2525B/...) + """ + Kind_SpotMap: Marker._Kind.ValueType # 6 + """ + COT_MAPPING_SPOTMAP icon (e.g. colored dot) + """ + Kind_CustomIcon: Marker._Kind.ValueType # 7 + """ + Custom icon set (UUID/GroupName/filename.png) + """ + Kind_GoToPoint: Marker._Kind.ValueType # 8 + """ + b-m-p-w-GOTO: Go To / bloodhound navigation waypoint. + """ + Kind_InitialPoint: Marker._Kind.ValueType # 9 + """ + b-m-p-c-ip: Initial point (mission planning control point). + """ + Kind_ContactPoint: Marker._Kind.ValueType # 10 + """ + b-m-p-c-cp: Contact point (mission planning control point). + """ + Kind_ObservationPost: Marker._Kind.ValueType # 11 + """ + b-m-p-s-p-op: Observation post. + """ + Kind_ImageMarker: Marker._Kind.ValueType # 12 + """ + 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. + """ + + class Kind(_Kind, metaclass=_KindEnumTypeWrapper): + """ + 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). + """ + + Kind_Unspecified: Marker.Kind.ValueType # 0 + """ + Unspecified — fall back to TAKPacketV2.cot_type_id + """ + Kind_Spot: Marker.Kind.ValueType # 1 + """ + b-m-p-s-m: Spot map marker + """ + Kind_Waypoint: Marker.Kind.ValueType # 2 + """ + b-m-p-w: Route waypoint + """ + Kind_Checkpoint: Marker.Kind.ValueType # 3 + """ + b-m-p-c: Checkpoint + """ + Kind_SelfPosition: Marker.Kind.ValueType # 4 + """ + b-m-p-s-p-i / b-m-p-s-p-loc: Self-position marker + """ + Kind_Symbol2525: Marker.Kind.ValueType # 5 + """ + 2525B/C military symbol (iconsetpath = COT_MAPPING_2525B/...) + """ + Kind_SpotMap: Marker.Kind.ValueType # 6 + """ + COT_MAPPING_SPOTMAP icon (e.g. colored dot) + """ + Kind_CustomIcon: Marker.Kind.ValueType # 7 + """ + Custom icon set (UUID/GroupName/filename.png) + """ + Kind_GoToPoint: Marker.Kind.ValueType # 8 + """ + b-m-p-w-GOTO: Go To / bloodhound navigation waypoint. + """ + Kind_InitialPoint: Marker.Kind.ValueType # 9 + """ + b-m-p-c-ip: Initial point (mission planning control point). + """ + Kind_ContactPoint: Marker.Kind.ValueType # 10 + """ + b-m-p-c-cp: Contact point (mission planning control point). + """ + Kind_ObservationPost: Marker.Kind.ValueType # 11 + """ + b-m-p-s-p-op: Observation post. + """ + Kind_ImageMarker: Marker.Kind.ValueType # 12 + """ + 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_FIELD_NUMBER: builtins.int + COLOR_FIELD_NUMBER: builtins.int + COLOR_ARGB_FIELD_NUMBER: builtins.int + READINESS_FIELD_NUMBER: builtins.int + PARENT_UID_FIELD_NUMBER: builtins.int + PARENT_TYPE_FIELD_NUMBER: builtins.int + PARENT_CALLSIGN_FIELD_NUMBER: builtins.int + ICONSET_FIELD_NUMBER: builtins.int + kind: global___Marker.Kind.ValueType + """ + Marker kind + """ + color: global___Team.ValueType + """ + Marker color as a named palette entry. If Unspecifed_Color, the exact + ARGB is in color_argb. + """ + color_argb: builtins.int + """ + Marker color exact ARGB bit pattern. Always populated on the wire. + """ + readiness: builtins.bool + """ + Status readiness flag (ATAK ). + """ + parent_uid: builtins.str + """ + Parent link UID (ATAK ). Empty = no parent. + For spot/waypoint markers this is typically the producing TAK user's UID. + """ + parent_type: builtins.str + """ + Parent CoT type (e.g. "a-f-G-U-C"). Usually the parent TAK user's type. + """ + parent_callsign: builtins.str + """ + Parent callsign (e.g. "HOPE"). + """ + iconset: builtins.str + """ + 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. + """ + def __init__( + self, + *, + kind: global___Marker.Kind.ValueType = ..., + color: global___Team.ValueType = ..., + color_argb: builtins.int = ..., + readiness: builtins.bool = ..., + parent_uid: builtins.str = ..., + parent_type: builtins.str = ..., + parent_callsign: builtins.str = ..., + iconset: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["color", b"color", "color_argb", b"color_argb", "iconset", b"iconset", "kind", b"kind", "parent_callsign", b"parent_callsign", "parent_type", b"parent_type", "parent_uid", b"parent_uid", "readiness", b"readiness"]) -> None: ... + +global___Marker = Marker + +@typing.final +class RangeAndBearing(google.protobuf.message.Message): + """ + 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. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ANCHOR_FIELD_NUMBER: builtins.int + ANCHOR_UID_FIELD_NUMBER: builtins.int + RANGE_CM_FIELD_NUMBER: builtins.int + BEARING_CDEG_FIELD_NUMBER: builtins.int + STROKE_COLOR_FIELD_NUMBER: builtins.int + STROKE_ARGB_FIELD_NUMBER: builtins.int + STROKE_WEIGHT_X10_FIELD_NUMBER: builtins.int + anchor_uid: builtins.str + """ + Anchor UID (from ). Empty = free-standing. + """ + range_cm: builtins.int + """ + Range in centimeters (value * 100). Range 0..4294 km. + """ + bearing_cdeg: builtins.int + """ + Bearing in degrees * 100 (0..36000). + """ + stroke_color: global___Team.ValueType + """ + Stroke color as a Team palette entry. See DrawnShape.stroke_color doc. + """ + stroke_argb: builtins.int + """ + Stroke color exact ARGB fallback. + """ + stroke_weight_x10: builtins.int + """ + Stroke weight * 10 (e.g. 30 = 3.0). + """ + @property + def anchor(self) -> global___CotGeoPoint: + """ + Target/anchor endpoint (delta-encoded from TAKPacketV2.latitude_i/longitude_i). + """ + + def __init__( + self, + *, + anchor: global___CotGeoPoint | None = ..., + anchor_uid: builtins.str = ..., + range_cm: builtins.int = ..., + bearing_cdeg: builtins.int = ..., + stroke_color: global___Team.ValueType = ..., + stroke_argb: builtins.int = ..., + stroke_weight_x10: builtins.int = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["anchor", b"anchor"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["anchor", b"anchor", "anchor_uid", b"anchor_uid", "bearing_cdeg", b"bearing_cdeg", "range_cm", b"range_cm", "stroke_argb", b"stroke_argb", "stroke_color", b"stroke_color", "stroke_weight_x10", b"stroke_weight_x10"]) -> None: ... + +global___RangeAndBearing = RangeAndBearing + +@typing.final +class Route(google.protobuf.message.Message): + """ + 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`. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _Method: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _MethodEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Route._Method.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + Method_Unspecified: Route._Method.ValueType # 0 + """ + Unspecified / unknown + """ + Method_Driving: Route._Method.ValueType # 1 + """ + Driving / vehicle + """ + Method_Walking: Route._Method.ValueType # 2 + """ + Walking / foot + """ + Method_Flying: Route._Method.ValueType # 3 + """ + Flying + """ + Method_Swimming: Route._Method.ValueType # 4 + """ + Swimming (individual) + """ + Method_Watercraft: Route._Method.ValueType # 5 + """ + Watercraft (boat) + """ + + class Method(_Method, metaclass=_MethodEnumTypeWrapper): + """ + Travel method for the route. + """ + + Method_Unspecified: Route.Method.ValueType # 0 + """ + Unspecified / unknown + """ + Method_Driving: Route.Method.ValueType # 1 + """ + Driving / vehicle + """ + Method_Walking: Route.Method.ValueType # 2 + """ + Walking / foot + """ + Method_Flying: Route.Method.ValueType # 3 + """ + Flying + """ + Method_Swimming: Route.Method.ValueType # 4 + """ + Swimming (individual) + """ + Method_Watercraft: Route.Method.ValueType # 5 + """ + Watercraft (boat) + """ + + class _Direction: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _DirectionEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Route._Direction.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + Direction_Unspecified: Route._Direction.ValueType # 0 + """ + Unspecified + """ + Direction_Infil: Route._Direction.ValueType # 1 + """ + Infiltration (ingress) + """ + Direction_Exfil: Route._Direction.ValueType # 2 + """ + Exfiltration (egress) + """ + + class Direction(_Direction, metaclass=_DirectionEnumTypeWrapper): + """ + Route direction (infil = ingress, exfil = egress). + """ + + Direction_Unspecified: Route.Direction.ValueType # 0 + """ + Unspecified + """ + Direction_Infil: Route.Direction.ValueType # 1 + """ + Infiltration (ingress) + """ + Direction_Exfil: Route.Direction.ValueType # 2 + """ + Exfiltration (egress) + """ + + @typing.final + class Link(google.protobuf.message.Message): + """ + Route waypoint or control point. Each link corresponds to one ATAK + entry inside the b-m-r event. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + POINT_FIELD_NUMBER: builtins.int + UID_FIELD_NUMBER: builtins.int + CALLSIGN_FIELD_NUMBER: builtins.int + LINK_TYPE_FIELD_NUMBER: builtins.int + uid: builtins.str + """ + Optional UID (empty = receiver derives). + """ + callsign: builtins.str + """ + Optional display callsign (e.g. "CP1"). Empty for unnamed control points. + """ + link_type: builtins.int + """ + Link role: 0 = waypoint (b-m-p-w), 1 = checkpoint (b-m-p-c). + """ + @property + def point(self) -> global___CotGeoPoint: + """ + Waypoint position (delta-encoded from TAKPacketV2.latitude_i/longitude_i). + """ + + def __init__( + self, + *, + point: global___CotGeoPoint | None = ..., + uid: builtins.str = ..., + callsign: builtins.str = ..., + link_type: builtins.int = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["point", b"point"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["callsign", b"callsign", "link_type", b"link_type", "point", b"point", "uid", b"uid"]) -> None: ... + + METHOD_FIELD_NUMBER: builtins.int + DIRECTION_FIELD_NUMBER: builtins.int + PREFIX_FIELD_NUMBER: builtins.int + STROKE_WEIGHT_X10_FIELD_NUMBER: builtins.int + LINKS_FIELD_NUMBER: builtins.int + TRUNCATED_FIELD_NUMBER: builtins.int + method: global___Route.Method.ValueType + """ + Travel method + """ + direction: global___Route.Direction.ValueType + """ + Direction (infil/exfil) + """ + prefix: builtins.str + """ + Waypoint name prefix (e.g. "CP"). + """ + stroke_weight_x10: builtins.int + """ + Stroke weight * 10 (e.g. 30 = 3.0). 0 = default. + """ + truncated: builtins.bool + """ + True if the sender truncated `links` to fit the pool. + """ + @property + def links(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Route.Link]: + """ + Ordered list of route control points. Capped at 16. + """ + + def __init__( + self, + *, + method: global___Route.Method.ValueType = ..., + direction: global___Route.Direction.ValueType = ..., + prefix: builtins.str = ..., + stroke_weight_x10: builtins.int = ..., + links: collections.abc.Iterable[global___Route.Link] | None = ..., + truncated: builtins.bool = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["direction", b"direction", "links", b"links", "method", b"method", "prefix", b"prefix", "stroke_weight_x10", b"stroke_weight_x10", "truncated", b"truncated"]) -> None: ... + +global___Route = Route + +@typing.final +class CasevacReport(google.protobuf.message.Message): + """ + 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. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _Precedence: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _PrecedenceEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[CasevacReport._Precedence.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + Precedence_Unspecified: CasevacReport._Precedence.ValueType # 0 + Precedence_Urgent: CasevacReport._Precedence.ValueType # 1 + """A - immediate, life-threatening""" + Precedence_UrgentSurgical: CasevacReport._Precedence.ValueType # 2 + """B - needs surgery""" + Precedence_Priority: CasevacReport._Precedence.ValueType # 3 + """C - within 4 hours""" + Precedence_Routine: CasevacReport._Precedence.ValueType # 4 + """D - within 24 hours""" + Precedence_Convenience: CasevacReport._Precedence.ValueType # 5 + """E - convenience""" + + class Precedence(_Precedence, metaclass=_PrecedenceEnumTypeWrapper): + """ + Line 3: precedence / urgency. + """ + + Precedence_Unspecified: CasevacReport.Precedence.ValueType # 0 + Precedence_Urgent: CasevacReport.Precedence.ValueType # 1 + """A - immediate, life-threatening""" + Precedence_UrgentSurgical: CasevacReport.Precedence.ValueType # 2 + """B - needs surgery""" + Precedence_Priority: CasevacReport.Precedence.ValueType # 3 + """C - within 4 hours""" + Precedence_Routine: CasevacReport.Precedence.ValueType # 4 + """D - within 24 hours""" + Precedence_Convenience: CasevacReport.Precedence.ValueType # 5 + """E - convenience""" + + class _HlzMarking: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _HlzMarkingEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[CasevacReport._HlzMarking.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + HlzMarking_Unspecified: CasevacReport._HlzMarking.ValueType # 0 + HlzMarking_Panels: CasevacReport._HlzMarking.ValueType # 1 + HlzMarking_PyroSignal: CasevacReport._HlzMarking.ValueType # 2 + HlzMarking_Smoke: CasevacReport._HlzMarking.ValueType # 3 + HlzMarking_None: CasevacReport._HlzMarking.ValueType # 4 + HlzMarking_Other: CasevacReport._HlzMarking.ValueType # 5 + + class HlzMarking(_HlzMarking, metaclass=_HlzMarkingEnumTypeWrapper): + """ + Line 7: HLZ marking method. + """ + + HlzMarking_Unspecified: CasevacReport.HlzMarking.ValueType # 0 + HlzMarking_Panels: CasevacReport.HlzMarking.ValueType # 1 + HlzMarking_PyroSignal: CasevacReport.HlzMarking.ValueType # 2 + HlzMarking_Smoke: CasevacReport.HlzMarking.ValueType # 3 + HlzMarking_None: CasevacReport.HlzMarking.ValueType # 4 + HlzMarking_Other: CasevacReport.HlzMarking.ValueType # 5 + + class _Security: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _SecurityEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[CasevacReport._Security.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + Security_Unspecified: CasevacReport._Security.ValueType # 0 + Security_NoEnemy: CasevacReport._Security.ValueType # 1 + """N - no enemy activity""" + Security_PossibleEnemy: CasevacReport._Security.ValueType # 2 + """P - possible enemy""" + Security_EnemyInArea: CasevacReport._Security.ValueType # 3 + """E - enemy, approach with caution""" + Security_EnemyInArmedContact: CasevacReport._Security.ValueType # 4 + """X - armed escort required""" + + class Security(_Security, metaclass=_SecurityEnumTypeWrapper): + """ + Line 6: security situation at the pickup zone. + """ + + Security_Unspecified: CasevacReport.Security.ValueType # 0 + Security_NoEnemy: CasevacReport.Security.ValueType # 1 + """N - no enemy activity""" + Security_PossibleEnemy: CasevacReport.Security.ValueType # 2 + """P - possible enemy""" + Security_EnemyInArea: CasevacReport.Security.ValueType # 3 + """E - enemy, approach with caution""" + Security_EnemyInArmedContact: CasevacReport.Security.ValueType # 4 + """X - armed escort required""" + + PRECEDENCE_FIELD_NUMBER: builtins.int + EQUIPMENT_FLAGS_FIELD_NUMBER: builtins.int + LITTER_PATIENTS_FIELD_NUMBER: builtins.int + AMBULATORY_PATIENTS_FIELD_NUMBER: builtins.int + SECURITY_FIELD_NUMBER: builtins.int + HLZ_MARKING_FIELD_NUMBER: builtins.int + ZONE_MARKER_FIELD_NUMBER: builtins.int + US_MILITARY_FIELD_NUMBER: builtins.int + US_CIVILIAN_FIELD_NUMBER: builtins.int + NON_US_MILITARY_FIELD_NUMBER: builtins.int + NON_US_CIVILIAN_FIELD_NUMBER: builtins.int + EPW_FIELD_NUMBER: builtins.int + CHILD_FIELD_NUMBER: builtins.int + TERRAIN_FLAGS_FIELD_NUMBER: builtins.int + FREQUENCY_FIELD_NUMBER: builtins.int + TITLE_FIELD_NUMBER: builtins.int + MEDLINE_REMARKS_FIELD_NUMBER: builtins.int + URGENT_COUNT_FIELD_NUMBER: builtins.int + URGENT_SURGICAL_COUNT_FIELD_NUMBER: builtins.int + PRIORITY_COUNT_FIELD_NUMBER: builtins.int + ROUTINE_COUNT_FIELD_NUMBER: builtins.int + CONVENIENCE_COUNT_FIELD_NUMBER: builtins.int + EQUIPMENT_DETAIL_FIELD_NUMBER: builtins.int + ZONE_PROTECTED_COORD_FIELD_NUMBER: builtins.int + TERRAIN_SLOPE_DIR_FIELD_NUMBER: builtins.int + TERRAIN_OTHER_DETAIL_FIELD_NUMBER: builtins.int + MARKED_BY_FIELD_NUMBER: builtins.int + OBSTACLES_FIELD_NUMBER: builtins.int + WINDS_ARE_FROM_FIELD_NUMBER: builtins.int + FRIENDLIES_FIELD_NUMBER: builtins.int + ENEMY_FIELD_NUMBER: builtins.int + HLZ_REMARKS_FIELD_NUMBER: builtins.int + ZMIST_FIELD_NUMBER: builtins.int + precedence: global___CasevacReport.Precedence.ValueType + """ + Line 3: precedence / urgency. + """ + equipment_flags: builtins.int + """ + Line 4: special equipment required, as a bitfield. + bit 0: none + bit 1: hoist + bit 2: extraction equipment + bit 3: ventilator + bit 4: blood + """ + litter_patients: builtins.int + """ + Line 5: number of litter (stretcher-bound) patients. + """ + ambulatory_patients: builtins.int + """ + Line 5: number of ambulatory (walking-wounded) patients. + """ + security: global___CasevacReport.Security.ValueType + """ + Line 6: security situation at the PZ. + """ + hlz_marking: global___CasevacReport.HlzMarking.ValueType + """ + Line 7: HLZ marking method. + """ + zone_marker: builtins.str + """ + Line 7 supplementary: short free-text describing the zone marker + (e.g. "Green smoke", "VS-17 panel west"). Capped tight in options. + """ + us_military: builtins.int + """--- Line 8: patient nationality counts ---""" + us_civilian: builtins.int + non_us_military: builtins.int + non_us_civilian: builtins.int + epw: builtins.int + child: builtins.int + terrain_flags: builtins.int + """ + 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 + """ + frequency: builtins.str + """ + Line 2: radio frequency / callsign metadata (e.g. "38.90 Mhz" or + "Victor 6"). Capped tight in options. + """ + title: builtins.str + """--- 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. + """ + medline_remarks: builtins.str + """ + 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. + """ + urgent_count: builtins.int + """ + 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. + """ + urgent_surgical_count: builtins.int + priority_count: builtins.int + routine_count: builtins.int + convenience_count: builtins.int + equipment_detail: builtins.str + """ + Line 4 supplementary: free-text description of non-standard equipment + (e.g. "Blood warmer"). Pairs with the `equipment_flags` bitfield. + """ + zone_protected_coord: builtins.str + """ + 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. + """ + terrain_slope_dir: builtins.str + """ + Line 9 supplementary: slope direction (e.g. "N", "NE", "SSW") when + `terrain_flags` bit 0 (slope) is set. + """ + terrain_other_detail: builtins.str + """ + 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. + """ + marked_by: builtins.str + """ + 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. + """ + obstacles: builtins.str + """--- 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"). + """ + winds_are_from: builtins.str + """ + Wind direction and speed (e.g. "270 at 12 kts"). + """ + friendlies: builtins.str + """ + Friendly forces posture near the pickup zone + (e.g. "Squad east of HLZ"). + """ + enemy: builtins.str + """ + Known or suspected enemy positions near the pickup zone + (e.g. "Possible enemy on south ridge"). + """ + hlz_remarks: builtins.str + """ + Free-text description of the HLZ itself + (e.g. "Primary HLZ is soccer field"). + """ + @property + def zmist(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ZMistEntry]: + """ + 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. + """ + + def __init__( + self, + *, + precedence: global___CasevacReport.Precedence.ValueType = ..., + equipment_flags: builtins.int = ..., + litter_patients: builtins.int = ..., + ambulatory_patients: builtins.int = ..., + security: global___CasevacReport.Security.ValueType = ..., + hlz_marking: global___CasevacReport.HlzMarking.ValueType = ..., + zone_marker: builtins.str = ..., + us_military: builtins.int = ..., + us_civilian: builtins.int = ..., + non_us_military: builtins.int = ..., + non_us_civilian: builtins.int = ..., + epw: builtins.int = ..., + child: builtins.int = ..., + terrain_flags: builtins.int = ..., + frequency: builtins.str = ..., + title: builtins.str = ..., + medline_remarks: builtins.str = ..., + urgent_count: builtins.int = ..., + urgent_surgical_count: builtins.int = ..., + priority_count: builtins.int = ..., + routine_count: builtins.int = ..., + convenience_count: builtins.int = ..., + equipment_detail: builtins.str = ..., + zone_protected_coord: builtins.str = ..., + terrain_slope_dir: builtins.str = ..., + terrain_other_detail: builtins.str = ..., + marked_by: builtins.str = ..., + obstacles: builtins.str = ..., + winds_are_from: builtins.str = ..., + friendlies: builtins.str = ..., + enemy: builtins.str = ..., + hlz_remarks: builtins.str = ..., + zmist: collections.abc.Iterable[global___ZMistEntry] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["ambulatory_patients", b"ambulatory_patients", "child", b"child", "convenience_count", b"convenience_count", "enemy", b"enemy", "epw", b"epw", "equipment_detail", b"equipment_detail", "equipment_flags", b"equipment_flags", "frequency", b"frequency", "friendlies", b"friendlies", "hlz_marking", b"hlz_marking", "hlz_remarks", b"hlz_remarks", "litter_patients", b"litter_patients", "marked_by", b"marked_by", "medline_remarks", b"medline_remarks", "non_us_civilian", b"non_us_civilian", "non_us_military", b"non_us_military", "obstacles", b"obstacles", "precedence", b"precedence", "priority_count", b"priority_count", "routine_count", b"routine_count", "security", b"security", "terrain_flags", b"terrain_flags", "terrain_other_detail", b"terrain_other_detail", "terrain_slope_dir", b"terrain_slope_dir", "title", b"title", "urgent_count", b"urgent_count", "urgent_surgical_count", b"urgent_surgical_count", "us_civilian", b"us_civilian", "us_military", b"us_military", "winds_are_from", b"winds_are_from", "zmist", b"zmist", "zone_marker", b"zone_marker", "zone_protected_coord", b"zone_protected_coord"]) -> None: ... + +global___CasevacReport = CasevacReport + +@typing.final +class ZMistEntry(google.protobuf.message.Message): + """ + 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. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TITLE_FIELD_NUMBER: builtins.int + Z_FIELD_NUMBER: builtins.int + M_FIELD_NUMBER: builtins.int + I_FIELD_NUMBER: builtins.int + S_FIELD_NUMBER: builtins.int + T_FIELD_NUMBER: builtins.int + title: builtins.str + """ + Patient identifier / sequence label (e.g. "ZMIST-1", "ZMIST-2"). + """ + z: builtins.str + """ + Zap number — unique patient tracking ID (often a terse code like + "Gunshot" or a serial). + """ + m: builtins.str + """ + Mechanism of injury (e.g. "Penetrating trauma", "Blast injury"). + """ + i: builtins.str + """ + Injuries observed (e.g. "Left thigh", "Concussion"). + """ + s: builtins.str + """ + Signs / vital stats (e.g. "Stable", "Priority", "BP 110/70"). + """ + t: builtins.str + """ + Treatment given (e.g. "Tourniquet 1810Z", "O2 administered"). + """ + def __init__( + self, + *, + title: builtins.str = ..., + z: builtins.str = ..., + m: builtins.str = ..., + i: builtins.str = ..., + s: builtins.str = ..., + t: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["i", b"i", "m", b"m", "s", b"s", "t", b"t", "title", b"title", "z", b"z"]) -> None: ... + +global___ZMistEntry = ZMistEntry + +@typing.final +class EmergencyAlert(google.protobuf.message.Message): + """ + 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. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _Type: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _TypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[EmergencyAlert._Type.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + Type_Unspecified: EmergencyAlert._Type.ValueType # 0 + Type_Alert911: EmergencyAlert._Type.ValueType # 1 + """b-a-o-tbl""" + Type_RingTheBell: EmergencyAlert._Type.ValueType # 2 + """b-a-o-pan""" + Type_InContact: EmergencyAlert._Type.ValueType # 3 + """b-a-o-opn""" + Type_GeoFenceBreached: EmergencyAlert._Type.ValueType # 4 + """b-a-g""" + Type_Custom: EmergencyAlert._Type.ValueType # 5 + """b-a-o-c""" + Type_Cancel: EmergencyAlert._Type.ValueType # 6 + """b-a-o-can""" + + class Type(_Type, metaclass=_TypeEnumTypeWrapper): ... + Type_Unspecified: EmergencyAlert.Type.ValueType # 0 + Type_Alert911: EmergencyAlert.Type.ValueType # 1 + """b-a-o-tbl""" + Type_RingTheBell: EmergencyAlert.Type.ValueType # 2 + """b-a-o-pan""" + Type_InContact: EmergencyAlert.Type.ValueType # 3 + """b-a-o-opn""" + Type_GeoFenceBreached: EmergencyAlert.Type.ValueType # 4 + """b-a-g""" + Type_Custom: EmergencyAlert.Type.ValueType # 5 + """b-a-o-c""" + Type_Cancel: EmergencyAlert.Type.ValueType # 6 + """b-a-o-can""" + + TYPE_FIELD_NUMBER: builtins.int + AUTHORING_UID_FIELD_NUMBER: builtins.int + CANCEL_REFERENCE_UID_FIELD_NUMBER: builtins.int + type: global___EmergencyAlert.Type.ValueType + """ + Alert discriminator. + """ + authoring_uid: builtins.str + """ + 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. + """ + cancel_reference_uid: builtins.str + """ + For Type_Cancel: the uid of the alert being cancelled. Empty for + non-cancel alert types. + """ + def __init__( + self, + *, + type: global___EmergencyAlert.Type.ValueType = ..., + authoring_uid: builtins.str = ..., + cancel_reference_uid: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["authoring_uid", b"authoring_uid", "cancel_reference_uid", b"cancel_reference_uid", "type", b"type"]) -> None: ... + +global___EmergencyAlert = EmergencyAlert + +@typing.final +class TaskRequest(google.protobuf.message.Message): + """ + 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. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _Priority: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _PriorityEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[TaskRequest._Priority.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + Priority_Unspecified: TaskRequest._Priority.ValueType # 0 + Priority_Low: TaskRequest._Priority.ValueType # 1 + Priority_Normal: TaskRequest._Priority.ValueType # 2 + Priority_High: TaskRequest._Priority.ValueType # 3 + Priority_Critical: TaskRequest._Priority.ValueType # 4 + + class Priority(_Priority, metaclass=_PriorityEnumTypeWrapper): ... + Priority_Unspecified: TaskRequest.Priority.ValueType # 0 + Priority_Low: TaskRequest.Priority.ValueType # 1 + Priority_Normal: TaskRequest.Priority.ValueType # 2 + Priority_High: TaskRequest.Priority.ValueType # 3 + Priority_Critical: TaskRequest.Priority.ValueType # 4 + + class _Status: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _StatusEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[TaskRequest._Status.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + Status_Unspecified: TaskRequest._Status.ValueType # 0 + Status_Pending: TaskRequest._Status.ValueType # 1 + """assigned, not yet acknowledged""" + Status_Acknowledged: TaskRequest._Status.ValueType # 2 + """assignee has seen it""" + Status_InProgress: TaskRequest._Status.ValueType # 3 + """assignee is working it""" + Status_Completed: TaskRequest._Status.ValueType # 4 + """task done""" + Status_Cancelled: TaskRequest._Status.ValueType # 5 + """cancelled before completion""" + + class Status(_Status, metaclass=_StatusEnumTypeWrapper): ... + Status_Unspecified: TaskRequest.Status.ValueType # 0 + Status_Pending: TaskRequest.Status.ValueType # 1 + """assigned, not yet acknowledged""" + Status_Acknowledged: TaskRequest.Status.ValueType # 2 + """assignee has seen it""" + Status_InProgress: TaskRequest.Status.ValueType # 3 + """assignee is working it""" + Status_Completed: TaskRequest.Status.ValueType # 4 + """task done""" + Status_Cancelled: TaskRequest.Status.ValueType # 5 + """cancelled before completion""" + + TASK_TYPE_FIELD_NUMBER: builtins.int + TARGET_UID_FIELD_NUMBER: builtins.int + ASSIGNEE_UID_FIELD_NUMBER: builtins.int + PRIORITY_FIELD_NUMBER: builtins.int + STATUS_FIELD_NUMBER: builtins.int + NOTE_FIELD_NUMBER: builtins.int + task_type: builtins.str + """ + 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. + """ + target_uid: builtins.str + """ + UID of the target / map item being tasked. + """ + assignee_uid: builtins.str + """ + UID of the assigned unit. Empty = unassigned / broadcast task. + """ + priority: global___TaskRequest.Priority.ValueType + status: global___TaskRequest.Status.ValueType + note: builtins.str + """ + Optional short note (reason, constraints, grid reference). Capped + tight in options to keep the worst-case under the LoRa MTU. + """ + def __init__( + self, + *, + task_type: builtins.str = ..., + target_uid: builtins.str = ..., + assignee_uid: builtins.str = ..., + priority: global___TaskRequest.Priority.ValueType = ..., + status: global___TaskRequest.Status.ValueType = ..., + note: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["assignee_uid", b"assignee_uid", "note", b"note", "priority", b"priority", "status", b"status", "target_uid", b"target_uid", "task_type", b"task_type"]) -> None: ... + +global___TaskRequest = TaskRequest + +@typing.final +class TAKEnvironment(google.protobuf.message.Message): + """ + 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#). + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TEMPERATURE_C_X10_FIELD_NUMBER: builtins.int + WIND_DIRECTION_DEG_FIELD_NUMBER: builtins.int + WIND_SPEED_CM_S_FIELD_NUMBER: builtins.int + temperature_c_x10: builtins.int + """ + 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. + """ + wind_direction_deg: builtins.int + """ + Wind direction in whole degrees, 0-359. "Direction FROM" per + meteorological convention (matches CoT / ATAK). + """ + wind_speed_cm_s: builtins.int + """ + Wind speed in cm/s. Matches the unit of TAKPacketV2.speed for + consistency. 1200 = 12.00 m/s = ~27 mph. + """ + def __init__( + self, + *, + temperature_c_x10: builtins.int = ..., + wind_direction_deg: builtins.int = ..., + wind_speed_cm_s: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["temperature_c_x10", b"temperature_c_x10", "wind_direction_deg", b"wind_direction_deg", "wind_speed_cm_s", b"wind_speed_cm_s"]) -> None: ... + +global___TAKEnvironment = TAKEnvironment + +@typing.final +class SensorFov(google.protobuf.message.Message): + """ + 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). + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _SensorType: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _SensorTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[SensorFov._SensorType.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + SensorType_Unspecified: SensorFov._SensorType.ValueType # 0 + SensorType_Camera: SensorFov._SensorType.ValueType # 1 + """daylight / general optical""" + SensorType_Thermal: SensorFov._SensorType.ValueType # 2 + """FLIR, thermal imager""" + SensorType_Laser: SensorFov._SensorType.ValueType # 3 + """rangefinder, LRF, designator""" + SensorType_Nvg: SensorFov._SensorType.ValueType # 4 + """night vision goggles""" + SensorType_Rf: SensorFov._SensorType.ValueType # 5 + """radio/radar direction-finding""" + SensorType_Other: SensorFov._SensorType.ValueType # 6 + + class SensorType(_SensorType, metaclass=_SensorTypeEnumTypeWrapper): + """ + 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. + """ + + SensorType_Unspecified: SensorFov.SensorType.ValueType # 0 + SensorType_Camera: SensorFov.SensorType.ValueType # 1 + """daylight / general optical""" + SensorType_Thermal: SensorFov.SensorType.ValueType # 2 + """FLIR, thermal imager""" + SensorType_Laser: SensorFov.SensorType.ValueType # 3 + """rangefinder, LRF, designator""" + SensorType_Nvg: SensorFov.SensorType.ValueType # 4 + """night vision goggles""" + SensorType_Rf: SensorFov.SensorType.ValueType # 5 + """radio/radar direction-finding""" + SensorType_Other: SensorFov.SensorType.ValueType # 6 + + TYPE_FIELD_NUMBER: builtins.int + AZIMUTH_DEG_FIELD_NUMBER: builtins.int + RANGE_M_FIELD_NUMBER: builtins.int + FOV_HORIZONTAL_DEG_FIELD_NUMBER: builtins.int + FOV_VERTICAL_DEG_FIELD_NUMBER: builtins.int + ELEVATION_DEG_FIELD_NUMBER: builtins.int + ROLL_DEG_FIELD_NUMBER: builtins.int + MODEL_FIELD_NUMBER: builtins.int + type: global___SensorFov.SensorType.ValueType + azimuth_deg: builtins.int + """ + 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. + """ + range_m: builtins.int + """ + Maximum range of the cone in meters. + Optional — if unset, receivers should use the ATAK-CIV default of 100m. + """ + fov_horizontal_deg: builtins.int + """ + Horizontal field of view in whole degrees (cone's angular width). + ATAK-CIV default is 45°. + """ + fov_vertical_deg: builtins.int + """ + Vertical field of view in whole degrees. ATAK-CIV default is 45°. + Optional — a value of 0 means "not set / use horizontal FOV". + """ + elevation_deg: builtins.int + """ + Elevation angle in whole degrees. Positive = up, negative = down. + Range -90 to +90. sint32 for varint efficiency on small negatives. + """ + roll_deg: builtins.int + """ + Roll (camera tilt) in whole degrees, -180 to +180. + Optional — use 0 if the sensor doesn't track roll. + """ + model: builtins.str + """ + Free-form device model identifier, e.g. "FLIR-Boson-640", "SEEK". + Optional — empty string means "unknown model" (ATAK-CIV default). + """ + def __init__( + self, + *, + type: global___SensorFov.SensorType.ValueType = ..., + azimuth_deg: builtins.int = ..., + range_m: builtins.int | None = ..., + fov_horizontal_deg: builtins.int = ..., + fov_vertical_deg: builtins.int = ..., + elevation_deg: builtins.int = ..., + roll_deg: builtins.int = ..., + model: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_range_m", b"_range_m", "range_m", b"range_m"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_range_m", b"_range_m", "azimuth_deg", b"azimuth_deg", "elevation_deg", b"elevation_deg", "fov_horizontal_deg", b"fov_horizontal_deg", "fov_vertical_deg", b"fov_vertical_deg", "model", b"model", "range_m", b"range_m", "roll_deg", b"roll_deg", "type", b"type"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["_range_m", b"_range_m"]) -> typing.Literal["range_m"] | None: ... + +global___SensorFov = SensorFov + +@typing.final +class TakTalkMessage(google.protobuf.message.Message): + """ + TAKTALK chat message payload (CoT type m-t-t). + + TAKTALK is an ATAK plugin for voice + text team messaging. The voice + audio stream goes over UDP/RTP and is NOT carried by the mesh — only + the text envelope (this message) is. `from_voice` marks messages sent + via push-to-talk speech-to-text so receivers can render a mic icon + next to the text. + + Wire shape inside /: + ... - mapped to TAKPacketV2.callsign + English - lang + ... - text + 1 - chatroom_id + - presence sets from_voice = true + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TEXT_FIELD_NUMBER: builtins.int + CHATROOM_ID_FIELD_NUMBER: builtins.int + LANG_FIELD_NUMBER: builtins.int + FROM_VOICE_FIELD_NUMBER: builtins.int + text: builtins.str + """ + The text body of the TAKTALK message (speech-to-text transcript when + from_voice = true, typed message otherwise). + """ + chatroom_id: builtins.str + """ + TAKTALK chatroom identifier. May be a short id like "1" for the + default room or a UUID like "30b2755c-c547-44ef-a0cc-cdbd8a15616f" + for custom rooms (resolved by TakTalkRoomData broadcasts). + Empty = broadcast room. + """ + lang: builtins.str + """ + BCP-47-ish language tag or human-readable name (e.g. "en", "English"). + Empty = unspecified. + """ + from_voice: builtins.bool + """ + True when the source CoT carried a marker, i.e. the message + originated as push-to-talk speech-to-text. Lets receivers show a mic + icon. Proto3 only encodes when true so empty payload cost is 0 bytes. + """ + def __init__( + self, + *, + text: builtins.str = ..., + chatroom_id: builtins.str = ..., + lang: builtins.str = ..., + from_voice: builtins.bool = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["chatroom_id", b"chatroom_id", "from_voice", b"from_voice", "lang", b"lang", "text", b"text"]) -> None: ... + +global___TakTalkMessage = TakTalkMessage + +@typing.final +class TakTalkRoomData(google.protobuf.message.Message): + """ + TAKTALK room/membership broadcast (CoT type y-). + + Announces a TAKTALK chatroom's friendly name and roster so peers can + resolve room UUIDs (used in TakTalkMessage.chatroom_id and + GeoChat.room_id) to a display name and participant list. Not a chat + message itself — these events are emitted by TAKTALK when rooms are + created or memberships change. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SENDER_CALLSIGN_FIELD_NUMBER: builtins.int + ROOM_ID_FIELD_NUMBER: builtins.int + ROOM_NAME_FIELD_NUMBER: builtins.int + PARTICIPANTS_FIELD_NUMBER: builtins.int + sender_callsign: builtins.str + """ + Callsign of the device broadcasting the room state (typically the + room owner / latest writer). + + DEPRECATED in v0.3.2: always equals TAKPacketV2.callsign, so the wire + byte was redundant. Builders stop emitting this field in v0.3.2; + parsers still read it for one release so v0.3.1-encoded packets decode + cleanly. To be removed entirely in v0.4.x. + """ + room_id: builtins.str + """ + Room UUID, matches TakTalkMessage.chatroom_id / GeoChat.room_id on + messages routed into this room. + """ + room_name: builtins.str + """ + Friendly display name for the room (e.g. "test", "Alpha Team"). + """ + @property + def participants(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """ + Member callsigns. Wire-encoded as repeated strings; the underlying + CoT carries them as a single A,B,C element + which parsers split / builders join on ','. + """ + + def __init__( + self, + *, + sender_callsign: builtins.str = ..., + room_id: builtins.str = ..., + room_name: builtins.str = ..., + participants: collections.abc.Iterable[builtins.str] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["participants", b"participants", "room_id", b"room_id", "room_name", b"room_name", "sender_callsign", b"sender_callsign"]) -> None: ... + +global___TakTalkRoomData = TakTalkRoomData + +@typing.final +class Marti(google.protobuf.message.Message): + """ + ATAK directed-routing recipient list (CoT ). + + Present when an event is addressed to specific TAK users rather than the + broadcast group. TAKTALK gates voice TTS on this element matching the + receiver's callsign; directed b-t-f chats use it for the same purpose. A + missing means "broadcast to all peers", which is the default for + PLI, alerts, drawings, and most situational-awareness events. + + Carried as repeated strings (not indexes into a per-packet table) because + the typical event has 1-2 destinations and table overhead would erase the + savings. Receivers that need the original XML element rebuild it from + dest_callsign on emit. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + DEST_CALLSIGN_FIELD_NUMBER: builtins.int + @property + def dest_callsign(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """ + Recipient callsigns. Order is preserved end-to-end so receivers can show + primary-vs-cc distinction the same way ATAK does. + + If dest_callsign is [TAKPacketV2.callsign] (self-addressed, unusual but + legal — e.g. ATAK echoing back to its own room), the builder still emits + the element so loopback shapes round-trip cleanly. + """ + + def __init__( + self, + *, + dest_callsign: collections.abc.Iterable[builtins.str] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["dest_callsign", b"dest_callsign"]) -> None: ... + +global___Marti = Marti + +@typing.final +class TAKPacketV2(google.protobuf.message.Message): + """ + 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. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + COT_TYPE_ID_FIELD_NUMBER: builtins.int + HOW_FIELD_NUMBER: builtins.int + CALLSIGN_FIELD_NUMBER: builtins.int + TEAM_FIELD_NUMBER: builtins.int + ROLE_FIELD_NUMBER: builtins.int + LATITUDE_I_FIELD_NUMBER: builtins.int + LONGITUDE_I_FIELD_NUMBER: builtins.int + ALTITUDE_FIELD_NUMBER: builtins.int + SPEED_FIELD_NUMBER: builtins.int + COURSE_FIELD_NUMBER: builtins.int + BATTERY_FIELD_NUMBER: builtins.int + GEO_SRC_FIELD_NUMBER: builtins.int + ALT_SRC_FIELD_NUMBER: builtins.int + UID_FIELD_NUMBER: builtins.int + DEVICE_CALLSIGN_FIELD_NUMBER: builtins.int + STALE_SECONDS_FIELD_NUMBER: builtins.int + TAK_VERSION_FIELD_NUMBER: builtins.int + TAK_DEVICE_FIELD_NUMBER: builtins.int + TAK_PLATFORM_FIELD_NUMBER: builtins.int + TAK_OS_FIELD_NUMBER: builtins.int + ENDPOINT_FIELD_NUMBER: builtins.int + PHONE_FIELD_NUMBER: builtins.int + COT_TYPE_STR_FIELD_NUMBER: builtins.int + REMARKS_FIELD_NUMBER: builtins.int + ENVIRONMENT_FIELD_NUMBER: builtins.int + SENSOR_FOV_FIELD_NUMBER: builtins.int + MARTI_FIELD_NUMBER: builtins.int + CHAT_FIELD_NUMBER: builtins.int + AIRCRAFT_FIELD_NUMBER: builtins.int + RAW_DETAIL_FIELD_NUMBER: builtins.int + SHAPE_FIELD_NUMBER: builtins.int + MARKER_FIELD_NUMBER: builtins.int + RAB_FIELD_NUMBER: builtins.int + ROUTE_FIELD_NUMBER: builtins.int + CASEVAC_FIELD_NUMBER: builtins.int + EMERGENCY_FIELD_NUMBER: builtins.int + TASK_FIELD_NUMBER: builtins.int + TAKTALK_FIELD_NUMBER: builtins.int + TAKTALK_ROOM_FIELD_NUMBER: builtins.int + cot_type_id: global___CotType.ValueType + """ + Well-known CoT event type enum. + Use CotType_Other with cot_type_str for unknown types. + """ + how: global___CotHow.ValueType + """ + How the coordinates were generated + """ + callsign: builtins.str + """ + Callsign + """ + team: global___Team.ValueType + """ + Team color assignment + """ + role: global___MemberRole.ValueType + """ + Role of the group member + """ + latitude_i: builtins.int + """ + Latitude, multiply by 1e-7 to get degrees in floating point + """ + longitude_i: builtins.int + """ + Longitude, multiply by 1e-7 to get degrees in floating point + """ + altitude: builtins.int + """ + Altitude in meters (HAE). ATAK's "no altitude" sentinel is hae=9999999.0. + + NOTE: an earlier v0.4.0 attempt made this `optional` to omit the 9999999 + sentinel from the wire, but measurement showed it was net-negative: the + zstd dictionary already compresses the literal 9999999 to ~nothing, while + proto3 `optional` forces a genuine 0 m HAE (common on routes/drawings that + carry hae="0.0" or omit hae → parsed as 0) to encode explicitly (+2 bytes), + which REGRESSED the worst-case route fixture. Kept as a plain field. + """ + speed: builtins.int + """ + Speed in cm/s + """ + course: builtins.int + """ + Course in degrees * 100 (0-36000) + """ + battery: builtins.int + """ + Battery level 0-100 + """ + geo_src: global___GeoPointSource.ValueType + """ + Geopoint source + """ + alt_src: global___GeoPointSource.ValueType + """ + Altitude source + """ + uid: builtins.str + """ + Device UID (UUID string or device ID like "ANDROID-xxxx") + """ + device_callsign: builtins.str + """ + Device callsign + """ + stale_seconds: builtins.int + """ + Stale time as seconds offset from event time + """ + tak_version: builtins.str + """ + TAK client version string + """ + tak_device: builtins.str + """ + TAK device model + """ + tak_platform: builtins.str + """ + TAK platform (ATAK-CIV, WebTAK, etc.) + """ + tak_os: builtins.str + """ + TAK OS version + """ + endpoint: builtins.str + """ + Connection endpoint + """ + phone: builtins.str + """ + Phone number + """ + cot_type_str: builtins.str + """ + CoT event type string, only populated when cot_type_id is CotType_Other + """ + remarks: builtins.str + """ + 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. + """ + raw_detail: builtins.bytes + """ + 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. + """ + @property + def environment(self) -> global___TAKEnvironment: + """--- 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. + """ + + @property + def sensor_fov(self) -> global___SensorFov: + """ + Sensor field-of-view cone (camera, FLIR, laser, etc.). From . + """ + + @property + def marti(self) -> global___Marti: + """ + Directed-routing recipient list (CoT ). + Empty / unset = broadcast to all peers (the default for situational-awareness + events). Populated for TAKTALK m-t-t, directed b-t-f DMs, and any other CoT + shape that ATAK addresses to specific recipients. TAKTALK gates voice TTS + playback on this element matching the receiver's callsign, so dropping it + silently breaks voice messaging end-to-end. + + See Marti. + """ + + @property + def chat(self) -> global___GeoChat: + """ + ATAK GeoChat message + """ + + @property + def aircraft(self) -> global___AircraftTrack: + """ + Aircraft track data (ADS-B, military air) + """ + + @property + def shape(self) -> global___DrawnShape: + """ + User-drawn tactical graphic: circle, rectangle, polygon, polyline, + telestration, ranging circle, or bullseye. See DrawnShape. + """ + + @property + def marker(self) -> global___Marker: + """ + Fixed point of interest: spot marker, waypoint, checkpoint, 2525 + symbol, or custom icon. See Marker. + """ + + @property + def rab(self) -> global___RangeAndBearing: + """ + Range and bearing measurement line. See RangeAndBearing. + """ + + @property + def route(self) -> global___Route: + """ + Named route with ordered waypoints and control points. See Route. + """ + + @property + def casevac(self) -> global___CasevacReport: + """ + 9-line MEDEVAC request. See CasevacReport. + """ + + @property + def emergency(self) -> global___EmergencyAlert: + """ + Emergency beacon / 911 alert. See EmergencyAlert. + """ + + @property + def task(self) -> global___TaskRequest: + """ + Task / engage request. See TaskRequest. + """ + + @property + def taktalk(self) -> global___TakTalkMessage: + """ + TAKTALK chat message (CoT type m-t-t). See TakTalkMessage. + Voice audio itself rides UDP/RTP outside the mesh; this carries the + text envelope plus a from_voice marker for receiver UX. + """ + + @property + def taktalk_room(self) -> global___TakTalkRoomData: + """ + TAKTALK room/membership broadcast (CoT type y-). See TakTalkRoomData. + Resolves room UUIDs (used in TakTalkMessage.chatroom_id and + GeoChat.room_id) to display name + roster on receivers. + """ + + def __init__( + self, + *, + cot_type_id: global___CotType.ValueType = ..., + how: global___CotHow.ValueType = ..., + callsign: builtins.str = ..., + team: global___Team.ValueType = ..., + role: global___MemberRole.ValueType = ..., + latitude_i: builtins.int = ..., + longitude_i: builtins.int = ..., + altitude: builtins.int = ..., + speed: builtins.int = ..., + course: builtins.int = ..., + battery: builtins.int = ..., + geo_src: global___GeoPointSource.ValueType = ..., + alt_src: global___GeoPointSource.ValueType = ..., + uid: builtins.str = ..., + device_callsign: builtins.str = ..., + stale_seconds: builtins.int = ..., + tak_version: builtins.str = ..., + tak_device: builtins.str = ..., + tak_platform: builtins.str = ..., + tak_os: builtins.str = ..., + endpoint: builtins.str = ..., + phone: builtins.str = ..., + cot_type_str: builtins.str = ..., + remarks: builtins.str = ..., + environment: global___TAKEnvironment | None = ..., + sensor_fov: global___SensorFov | None = ..., + marti: global___Marti | None = ..., + chat: global___GeoChat | None = ..., + aircraft: global___AircraftTrack | None = ..., + raw_detail: builtins.bytes = ..., + shape: global___DrawnShape | None = ..., + marker: global___Marker | None = ..., + rab: global___RangeAndBearing | None = ..., + route: global___Route | None = ..., + casevac: global___CasevacReport | None = ..., + emergency: global___EmergencyAlert | None = ..., + task: global___TaskRequest | None = ..., + taktalk: global___TakTalkMessage | None = ..., + taktalk_room: global___TakTalkRoomData | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_environment", b"_environment", "_marti", b"_marti", "_sensor_fov", b"_sensor_fov", "aircraft", b"aircraft", "casevac", b"casevac", "chat", b"chat", "emergency", b"emergency", "environment", b"environment", "marker", b"marker", "marti", b"marti", "payload_variant", b"payload_variant", "rab", b"rab", "raw_detail", b"raw_detail", "route", b"route", "sensor_fov", b"sensor_fov", "shape", b"shape", "taktalk", b"taktalk", "taktalk_room", b"taktalk_room", "task", b"task"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_environment", b"_environment", "_marti", b"_marti", "_sensor_fov", b"_sensor_fov", "aircraft", b"aircraft", "alt_src", b"alt_src", "altitude", b"altitude", "battery", b"battery", "callsign", b"callsign", "casevac", b"casevac", "chat", b"chat", "cot_type_id", b"cot_type_id", "cot_type_str", b"cot_type_str", "course", b"course", "device_callsign", b"device_callsign", "emergency", b"emergency", "endpoint", b"endpoint", "environment", b"environment", "geo_src", b"geo_src", "how", b"how", "latitude_i", b"latitude_i", "longitude_i", b"longitude_i", "marker", b"marker", "marti", b"marti", "payload_variant", b"payload_variant", "phone", b"phone", "rab", b"rab", "raw_detail", b"raw_detail", "remarks", b"remarks", "role", b"role", "route", b"route", "sensor_fov", b"sensor_fov", "shape", b"shape", "speed", b"speed", "stale_seconds", b"stale_seconds", "tak_device", b"tak_device", "tak_os", b"tak_os", "tak_platform", b"tak_platform", "tak_version", b"tak_version", "taktalk", b"taktalk", "taktalk_room", b"taktalk_room", "task", b"task", "team", b"team", "uid", b"uid"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_environment", b"_environment"]) -> typing.Literal["environment"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_marti", b"_marti"]) -> typing.Literal["marti"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_sensor_fov", b"_sensor_fov"]) -> typing.Literal["sensor_fov"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["chat", "aircraft", "raw_detail", "shape", "marker", "rab", "route", "casevac", "emergency", "task", "taktalk", "taktalk_room"] | None: ... + +global___TAKPacketV2 = TAKPacketV2 diff --git a/meshtastic/protobuf/cannedmessages_pb2.py b/meshtastic/protobuf/cannedmessages_pb2.py index 569fe14..d3e5a69 100644 --- a/meshtastic/protobuf/cannedmessages_pb2.py +++ b/meshtastic/protobuf/cannedmessages_pb2.py @@ -11,9 +11,10 @@ from google.protobuf.internal import builder as _builder _sym_db = _symbol_database.Default() +from meshtastic.protobuf import nanopb_pb2 as meshtastic_dot_protobuf_dot_nanopb__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n(meshtastic/protobuf/cannedmessages.proto\x12\x13meshtastic.protobuf\"-\n\x19\x43\x61nnedMessageModuleConfig\x12\x10\n\x08messages\x18\x01 \x01(\tBo\n\x14org.meshtastic.protoB\x19\x43\x61nnedMessageConfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n(meshtastic/protobuf/cannedmessages.proto\x12\x13meshtastic.protobuf\x1a meshtastic/protobuf/nanopb.proto\"5\n\x19\x43\x61nnedMessageModuleConfig\x12\x18\n\x08messages\x18\x01 \x01(\tB\x06\x92?\x03\x08\xc9\x01\x42o\n\x14org.meshtastic.protoB\x19\x43\x61nnedMessageConfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -21,6 +22,8 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.cannedm if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\031CannedMessageConfigProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _globals['_CANNEDMESSAGEMODULECONFIG']._serialized_start=65 - _globals['_CANNEDMESSAGEMODULECONFIG']._serialized_end=110 + _CANNEDMESSAGEMODULECONFIG.fields_by_name['messages']._options = None + _CANNEDMESSAGEMODULECONFIG.fields_by_name['messages']._serialized_options = b'\222?\003\010\311\001' + _globals['_CANNEDMESSAGEMODULECONFIG']._serialized_start=99 + _globals['_CANNEDMESSAGEMODULECONFIG']._serialized_end=152 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/channel_pb2.py b/meshtastic/protobuf/channel_pb2.py index 94a5f00..a2bc315 100644 --- a/meshtastic/protobuf/channel_pb2.py +++ b/meshtastic/protobuf/channel_pb2.py @@ -11,9 +11,10 @@ from google.protobuf.internal import builder as _builder _sym_db = _symbol_database.Default() +from meshtastic.protobuf import nanopb_pb2 as meshtastic_dot_protobuf_dot_nanopb__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!meshtastic/protobuf/channel.proto\x12\x13meshtastic.protobuf\"\xc1\x01\n\x0f\x43hannelSettings\x12\x17\n\x0b\x63hannel_num\x18\x01 \x01(\rB\x02\x18\x01\x12\x0b\n\x03psk\x18\x02 \x01(\x0c\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\n\n\x02id\x18\x04 \x01(\x07\x12\x16\n\x0euplink_enabled\x18\x05 \x01(\x08\x12\x18\n\x10\x64ownlink_enabled\x18\x06 \x01(\x08\x12<\n\x0fmodule_settings\x18\x07 \x01(\x0b\x32#.meshtastic.protobuf.ModuleSettings\">\n\x0eModuleSettings\x12\x1a\n\x12position_precision\x18\x01 \x01(\r\x12\x10\n\x08is_muted\x18\x02 \x01(\x08\"\xb3\x01\n\x07\x43hannel\x12\r\n\x05index\x18\x01 \x01(\x05\x12\x36\n\x08settings\x18\x02 \x01(\x0b\x32$.meshtastic.protobuf.ChannelSettings\x12/\n\x04role\x18\x03 \x01(\x0e\x32!.meshtastic.protobuf.Channel.Role\"0\n\x04Role\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07PRIMARY\x10\x01\x12\r\n\tSECONDARY\x10\x02\x42\x63\n\x14org.meshtastic.protoB\rChannelProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!meshtastic/protobuf/channel.proto\x12\x13meshtastic.protobuf\x1a meshtastic/protobuf/nanopb.proto\"\xcf\x01\n\x0f\x43hannelSettings\x12\x17\n\x0b\x63hannel_num\x18\x01 \x01(\rB\x02\x18\x01\x12\x12\n\x03psk\x18\x02 \x01(\x0c\x42\x05\x92?\x02\x08 \x12\x13\n\x04name\x18\x03 \x01(\tB\x05\x92?\x02\x08\x0c\x12\n\n\x02id\x18\x04 \x01(\x07\x12\x16\n\x0euplink_enabled\x18\x05 \x01(\x08\x12\x18\n\x10\x64ownlink_enabled\x18\x06 \x01(\x08\x12<\n\x0fmodule_settings\x18\x07 \x01(\x0b\x32#.meshtastic.protobuf.ModuleSettings\">\n\x0eModuleSettings\x12\x1a\n\x12position_precision\x18\x01 \x01(\r\x12\x10\n\x08is_muted\x18\x02 \x01(\x08\"\xba\x01\n\x07\x43hannel\x12\x14\n\x05index\x18\x01 \x01(\x05\x42\x05\x92?\x02\x38\x08\x12\x36\n\x08settings\x18\x02 \x01(\x0b\x32$.meshtastic.protobuf.ChannelSettings\x12/\n\x04role\x18\x03 \x01(\x0e\x32!.meshtastic.protobuf.Channel.Role\"0\n\x04Role\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07PRIMARY\x10\x01\x12\r\n\tSECONDARY\x10\x02\x42\x63\n\x14org.meshtastic.protoB\rChannelProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -23,12 +24,18 @@ if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\rChannelProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' _CHANNELSETTINGS.fields_by_name['channel_num']._options = None _CHANNELSETTINGS.fields_by_name['channel_num']._serialized_options = b'\030\001' - _globals['_CHANNELSETTINGS']._serialized_start=59 - _globals['_CHANNELSETTINGS']._serialized_end=252 - _globals['_MODULESETTINGS']._serialized_start=254 - _globals['_MODULESETTINGS']._serialized_end=316 - _globals['_CHANNEL']._serialized_start=319 - _globals['_CHANNEL']._serialized_end=498 - _globals['_CHANNEL_ROLE']._serialized_start=450 - _globals['_CHANNEL_ROLE']._serialized_end=498 + _CHANNELSETTINGS.fields_by_name['psk']._options = None + _CHANNELSETTINGS.fields_by_name['psk']._serialized_options = b'\222?\002\010 ' + _CHANNELSETTINGS.fields_by_name['name']._options = None + _CHANNELSETTINGS.fields_by_name['name']._serialized_options = b'\222?\002\010\014' + _CHANNEL.fields_by_name['index']._options = None + _CHANNEL.fields_by_name['index']._serialized_options = b'\222?\0028\010' + _globals['_CHANNELSETTINGS']._serialized_start=93 + _globals['_CHANNELSETTINGS']._serialized_end=300 + _globals['_MODULESETTINGS']._serialized_start=302 + _globals['_MODULESETTINGS']._serialized_end=364 + _globals['_CHANNEL']._serialized_start=367 + _globals['_CHANNEL']._serialized_end=553 + _globals['_CHANNEL_ROLE']._serialized_start=505 + _globals['_CHANNEL_ROLE']._serialized_end=553 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/clientonly_pb2.py b/meshtastic/protobuf/clientonly_pb2.py index 7245538..cc68e42 100644 --- a/meshtastic/protobuf/clientonly_pb2.py +++ b/meshtastic/protobuf/clientonly_pb2.py @@ -13,9 +13,10 @@ _sym_db = _symbol_database.Default() from meshtastic.protobuf import localonly_pb2 as meshtastic_dot_protobuf_dot_localonly__pb2 from meshtastic.protobuf import mesh_pb2 as meshtastic_dot_protobuf_dot_mesh__pb2 +from meshtastic.protobuf import nanopb_pb2 as meshtastic_dot_protobuf_dot_nanopb__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$meshtastic/protobuf/clientonly.proto\x12\x13meshtastic.protobuf\x1a#meshtastic/protobuf/localonly.proto\x1a\x1emeshtastic/protobuf/mesh.proto\"\xc4\x03\n\rDeviceProfile\x12\x16\n\tlong_name\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x17\n\nshort_name\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x18\n\x0b\x63hannel_url\x18\x03 \x01(\tH\x02\x88\x01\x01\x12\x35\n\x06\x63onfig\x18\x04 \x01(\x0b\x32 .meshtastic.protobuf.LocalConfigH\x03\x88\x01\x01\x12\x42\n\rmodule_config\x18\x05 \x01(\x0b\x32&.meshtastic.protobuf.LocalModuleConfigH\x04\x88\x01\x01\x12:\n\x0e\x66ixed_position\x18\x06 \x01(\x0b\x32\x1d.meshtastic.protobuf.PositionH\x05\x88\x01\x01\x12\x15\n\x08ringtone\x18\x07 \x01(\tH\x06\x88\x01\x01\x12\x1c\n\x0f\x63\x61nned_messages\x18\x08 \x01(\tH\x07\x88\x01\x01\x42\x0c\n\n_long_nameB\r\n\x0b_short_nameB\x0e\n\x0c_channel_urlB\t\n\x07_configB\x10\n\x0e_module_configB\x11\n\x0f_fixed_positionB\x0b\n\t_ringtoneB\x12\n\x10_canned_messagesBf\n\x14org.meshtastic.protoB\x10\x43lientOnlyProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$meshtastic/protobuf/clientonly.proto\x12\x13meshtastic.protobuf\x1a#meshtastic/protobuf/localonly.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a meshtastic/protobuf/nanopb.proto\"\xe2\x03\n\rDeviceProfile\x12\x1d\n\tlong_name\x18\x01 \x01(\tB\x05\x92?\x02\x08(H\x00\x88\x01\x01\x12\x1e\n\nshort_name\x18\x02 \x01(\tB\x05\x92?\x02\x08\x05H\x01\x88\x01\x01\x12\x18\n\x0b\x63hannel_url\x18\x03 \x01(\tH\x02\x88\x01\x01\x12\x35\n\x06\x63onfig\x18\x04 \x01(\x0b\x32 .meshtastic.protobuf.LocalConfigH\x03\x88\x01\x01\x12\x42\n\rmodule_config\x18\x05 \x01(\x0b\x32&.meshtastic.protobuf.LocalModuleConfigH\x04\x88\x01\x01\x12:\n\x0e\x66ixed_position\x18\x06 \x01(\x0b\x32\x1d.meshtastic.protobuf.PositionH\x05\x88\x01\x01\x12\x1d\n\x08ringtone\x18\x07 \x01(\tB\x06\x92?\x03\x08\xe7\x01H\x06\x88\x01\x01\x12$\n\x0f\x63\x61nned_messages\x18\x08 \x01(\tB\x06\x92?\x03\x08\xc9\x01H\x07\x88\x01\x01\x42\x0c\n\n_long_nameB\r\n\x0b_short_nameB\x0e\n\x0c_channel_urlB\t\n\x07_configB\x10\n\x0e_module_configB\x11\n\x0f_fixed_positionB\x0b\n\t_ringtoneB\x12\n\x10_canned_messagesBf\n\x14org.meshtastic.protoB\x10\x43lientOnlyProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -23,6 +24,14 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.cliento if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\020ClientOnlyProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _globals['_DEVICEPROFILE']._serialized_start=131 - _globals['_DEVICEPROFILE']._serialized_end=583 + _DEVICEPROFILE.fields_by_name['long_name']._options = None + _DEVICEPROFILE.fields_by_name['long_name']._serialized_options = b'\222?\002\010(' + _DEVICEPROFILE.fields_by_name['short_name']._options = None + _DEVICEPROFILE.fields_by_name['short_name']._serialized_options = b'\222?\002\010\005' + _DEVICEPROFILE.fields_by_name['ringtone']._options = None + _DEVICEPROFILE.fields_by_name['ringtone']._serialized_options = b'\222?\003\010\347\001' + _DEVICEPROFILE.fields_by_name['canned_messages']._options = None + _DEVICEPROFILE.fields_by_name['canned_messages']._serialized_options = b'\222?\003\010\311\001' + _globals['_DEVICEPROFILE']._serialized_start=165 + _globals['_DEVICEPROFILE']._serialized_end=647 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/config_pb2.py b/meshtastic/protobuf/config_pb2.py index f709d1d..b483c57 100644 --- a/meshtastic/protobuf/config_pb2.py +++ b/meshtastic/protobuf/config_pb2.py @@ -12,9 +12,10 @@ _sym_db = _symbol_database.Default() from meshtastic.protobuf import device_ui_pb2 as meshtastic_dot_protobuf_dot_device__ui__pb2 +from meshtastic.protobuf import nanopb_pb2 as meshtastic_dot_protobuf_dot_nanopb__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/protobuf/config.proto\x12\x13meshtastic.protobuf\x1a#meshtastic/protobuf/device_ui.proto\"\xf9*\n\x06\x43onfig\x12:\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfigH\x00\x12>\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfigH\x00\x12\x38\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfigH\x00\x12<\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfigH\x00\x12<\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfigH\x00\x12\x36\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfigH\x00\x12@\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfigH\x00\x12>\n\x08security\x18\x08 \x01(\x0b\x32*.meshtastic.protobuf.Config.SecurityConfigH\x00\x12\x42\n\nsessionkey\x18\t \x01(\x0b\x32,.meshtastic.protobuf.Config.SessionkeyConfigH\x00\x12\x38\n\tdevice_ui\x18\n \x01(\x0b\x32#.meshtastic.protobuf.DeviceUIConfigH\x00\x1a\x91\x07\n\x0c\x44\x65viceConfig\x12;\n\x04role\x18\x01 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x1a\n\x0eserial_enabled\x18\x02 \x01(\x08\x42\x02\x18\x01\x12\x13\n\x0b\x62utton_gpio\x18\x04 \x01(\r\x12\x13\n\x0b\x62uzzer_gpio\x18\x05 \x01(\r\x12R\n\x10rebroadcast_mode\x18\x06 \x01(\x0e\x32\x38.meshtastic.protobuf.Config.DeviceConfig.RebroadcastMode\x12 \n\x18node_info_broadcast_secs\x18\x07 \x01(\r\x12\"\n\x1a\x64ouble_tap_as_button_press\x18\x08 \x01(\x08\x12\x16\n\nis_managed\x18\t \x01(\x08\x42\x02\x18\x01\x12\x1c\n\x14\x64isable_triple_click\x18\n \x01(\x08\x12\r\n\x05tzdef\x18\x0b \x01(\t\x12\x1e\n\x16led_heartbeat_disabled\x18\x0c \x01(\x08\x12H\n\x0b\x62uzzer_mode\x18\r \x01(\x0e\x32\x33.meshtastic.protobuf.Config.DeviceConfig.BuzzerMode\"\xd4\x01\n\x04Role\x12\n\n\x06\x43LIENT\x10\x00\x12\x0f\n\x0b\x43LIENT_MUTE\x10\x01\x12\n\n\x06ROUTER\x10\x02\x12\x15\n\rROUTER_CLIENT\x10\x03\x1a\x02\x08\x01\x12\x10\n\x08REPEATER\x10\x04\x1a\x02\x08\x01\x12\x0b\n\x07TRACKER\x10\x05\x12\n\n\x06SENSOR\x10\x06\x12\x07\n\x03TAK\x10\x07\x12\x11\n\rCLIENT_HIDDEN\x10\x08\x12\x12\n\x0eLOST_AND_FOUND\x10\t\x12\x0f\n\x0bTAK_TRACKER\x10\n\x12\x0f\n\x0bROUTER_LATE\x10\x0b\x12\x0f\n\x0b\x43LIENT_BASE\x10\x0c\"s\n\x0fRebroadcastMode\x12\x07\n\x03\x41LL\x10\x00\x12\x15\n\x11\x41LL_SKIP_DECODING\x10\x01\x12\x0e\n\nLOCAL_ONLY\x10\x02\x12\x0e\n\nKNOWN_ONLY\x10\x03\x12\x08\n\x04NONE\x10\x04\x12\x16\n\x12\x43ORE_PORTNUMS_ONLY\x10\x05\"i\n\nBuzzerMode\x12\x0f\n\x0b\x41LL_ENABLED\x10\x00\x12\x0c\n\x08\x44ISABLED\x10\x01\x12\x16\n\x12NOTIFICATIONS_ONLY\x10\x02\x12\x0f\n\x0bSYSTEM_ONLY\x10\x03\x12\x13\n\x0f\x44IRECT_MSG_ONLY\x10\x04\x1a\x9a\x05\n\x0ePositionConfig\x12\x1f\n\x17position_broadcast_secs\x18\x01 \x01(\r\x12(\n position_broadcast_smart_enabled\x18\x02 \x01(\x08\x12\x16\n\x0e\x66ixed_position\x18\x03 \x01(\x08\x12\x17\n\x0bgps_enabled\x18\x04 \x01(\x08\x42\x02\x18\x01\x12\x1b\n\x13gps_update_interval\x18\x05 \x01(\r\x12\x1c\n\x10gps_attempt_time\x18\x06 \x01(\rB\x02\x18\x01\x12\x16\n\x0eposition_flags\x18\x07 \x01(\r\x12\x0f\n\x07rx_gpio\x18\x08 \x01(\r\x12\x0f\n\x07tx_gpio\x18\t \x01(\r\x12(\n broadcast_smart_minimum_distance\x18\n \x01(\r\x12-\n%broadcast_smart_minimum_interval_secs\x18\x0b \x01(\r\x12\x13\n\x0bgps_en_gpio\x18\x0c \x01(\r\x12\x44\n\x08gps_mode\x18\r \x01(\x0e\x32\x32.meshtastic.protobuf.Config.PositionConfig.GpsMode\"\xab\x01\n\rPositionFlags\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x41LTITUDE\x10\x01\x12\x10\n\x0c\x41LTITUDE_MSL\x10\x02\x12\x16\n\x12GEOIDAL_SEPARATION\x10\x04\x12\x07\n\x03\x44OP\x10\x08\x12\t\n\x05HVDOP\x10\x10\x12\r\n\tSATINVIEW\x10 \x12\n\n\x06SEQ_NO\x10@\x12\x0e\n\tTIMESTAMP\x10\x80\x01\x12\x0c\n\x07HEADING\x10\x80\x02\x12\n\n\x05SPEED\x10\x80\x04\"5\n\x07GpsMode\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07\x45NABLED\x10\x01\x12\x0f\n\x0bNOT_PRESENT\x10\x02\x1a\x84\x02\n\x0bPowerConfig\x12\x17\n\x0fis_power_saving\x18\x01 \x01(\x08\x12&\n\x1eon_battery_shutdown_after_secs\x18\x02 \x01(\r\x12\x1f\n\x17\x61\x64\x63_multiplier_override\x18\x03 \x01(\x02\x12\x1b\n\x13wait_bluetooth_secs\x18\x04 \x01(\r\x12\x10\n\x08sds_secs\x18\x06 \x01(\r\x12\x0f\n\x07ls_secs\x18\x07 \x01(\r\x12\x15\n\rmin_wake_secs\x18\x08 \x01(\r\x12\"\n\x1a\x64\x65vice_battery_ina_address\x18\t \x01(\r\x12\x18\n\x10powermon_enables\x18 \x01(\x04\x1a\xf7\x03\n\rNetworkConfig\x12\x14\n\x0cwifi_enabled\x18\x01 \x01(\x08\x12\x11\n\twifi_ssid\x18\x03 \x01(\t\x12\x10\n\x08wifi_psk\x18\x04 \x01(\t\x12\x12\n\nntp_server\x18\x05 \x01(\t\x12\x13\n\x0b\x65th_enabled\x18\x06 \x01(\x08\x12K\n\x0c\x61\x64\x64ress_mode\x18\x07 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.NetworkConfig.AddressMode\x12I\n\x0bipv4_config\x18\x08 \x01(\x0b\x32\x34.meshtastic.protobuf.Config.NetworkConfig.IpV4Config\x12\x16\n\x0ersyslog_server\x18\t \x01(\t\x12\x19\n\x11\x65nabled_protocols\x18\n \x01(\r\x12\x14\n\x0cipv6_enabled\x18\x0b \x01(\x08\x1a\x46\n\nIpV4Config\x12\n\n\x02ip\x18\x01 \x01(\x07\x12\x0f\n\x07gateway\x18\x02 \x01(\x07\x12\x0e\n\x06subnet\x18\x03 \x01(\x07\x12\x0b\n\x03\x64ns\x18\x04 \x01(\x07\"#\n\x0b\x41\x64\x64ressMode\x12\x08\n\x04\x44HCP\x10\x00\x12\n\n\x06STATIC\x10\x01\"4\n\rProtocolFlags\x12\x10\n\x0cNO_BROADCAST\x10\x00\x12\x11\n\rUDP_BROADCAST\x10\x01\x1a\xb6\x08\n\rDisplayConfig\x12\x16\n\x0escreen_on_secs\x18\x01 \x01(\r\x12_\n\ngps_format\x18\x02 \x01(\x0e\x32G.meshtastic.protobuf.Config.DisplayConfig.DeprecatedGpsCoordinateFormatB\x02\x18\x01\x12!\n\x19\x61uto_screen_carousel_secs\x18\x03 \x01(\r\x12\x1d\n\x11\x63ompass_north_top\x18\x04 \x01(\x08\x42\x02\x18\x01\x12\x13\n\x0b\x66lip_screen\x18\x05 \x01(\x08\x12\x45\n\x05units\x18\x06 \x01(\x0e\x32\x36.meshtastic.protobuf.Config.DisplayConfig.DisplayUnits\x12@\n\x04oled\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.DisplayConfig.OledType\x12J\n\x0b\x64isplaymode\x18\x08 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.DisplayConfig.DisplayMode\x12\x14\n\x0cheading_bold\x18\t \x01(\x08\x12\x1d\n\x15wake_on_tap_or_motion\x18\n \x01(\x08\x12Y\n\x13\x63ompass_orientation\x18\x0b \x01(\x0e\x32<.meshtastic.protobuf.Config.DisplayConfig.CompassOrientation\x12\x15\n\ruse_12h_clock\x18\x0c \x01(\x08\x12\x1a\n\x12use_long_node_name\x18\r \x01(\x08\"+\n\x1d\x44\x65precatedGpsCoordinateFormat\x12\n\n\x06UNUSED\x10\x00\"(\n\x0c\x44isplayUnits\x12\n\n\x06METRIC\x10\x00\x12\x0c\n\x08IMPERIAL\x10\x01\"f\n\x08OledType\x12\r\n\tOLED_AUTO\x10\x00\x12\x10\n\x0cOLED_SSD1306\x10\x01\x12\x0f\n\x0bOLED_SH1106\x10\x02\x12\x0f\n\x0bOLED_SH1107\x10\x03\x12\x17\n\x13OLED_SH1107_128_128\x10\x04\"A\n\x0b\x44isplayMode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x0c\n\x08TWOCOLOR\x10\x01\x12\x0c\n\x08INVERTED\x10\x02\x12\t\n\x05\x43OLOR\x10\x03\"\xba\x01\n\x12\x43ompassOrientation\x12\r\n\tDEGREES_0\x10\x00\x12\x0e\n\nDEGREES_90\x10\x01\x12\x0f\n\x0b\x44\x45GREES_180\x10\x02\x12\x0f\n\x0b\x44\x45GREES_270\x10\x03\x12\x16\n\x12\x44\x45GREES_0_INVERTED\x10\x04\x12\x17\n\x13\x44\x45GREES_90_INVERTED\x10\x05\x12\x18\n\x14\x44\x45GREES_180_INVERTED\x10\x06\x12\x18\n\x14\x44\x45GREES_270_INVERTED\x10\x07\x1a\x80\x08\n\nLoRaConfig\x12\x12\n\nuse_preset\x18\x01 \x01(\x08\x12H\n\x0cmodem_preset\x18\x02 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.LoRaConfig.ModemPreset\x12\x11\n\tbandwidth\x18\x03 \x01(\r\x12\x15\n\rspread_factor\x18\x04 \x01(\r\x12\x13\n\x0b\x63oding_rate\x18\x05 \x01(\r\x12\x18\n\x10\x66requency_offset\x18\x06 \x01(\x02\x12\x41\n\x06region\x18\x07 \x01(\x0e\x32\x31.meshtastic.protobuf.Config.LoRaConfig.RegionCode\x12\x11\n\thop_limit\x18\x08 \x01(\r\x12\x12\n\ntx_enabled\x18\t \x01(\x08\x12\x10\n\x08tx_power\x18\n \x01(\x05\x12\x13\n\x0b\x63hannel_num\x18\x0b \x01(\r\x12\x1b\n\x13override_duty_cycle\x18\x0c \x01(\x08\x12\x1e\n\x16sx126x_rx_boosted_gain\x18\r \x01(\x08\x12\x1a\n\x12override_frequency\x18\x0e \x01(\x02\x12\x17\n\x0fpa_fan_disabled\x18\x0f \x01(\x08\x12\x17\n\x0fignore_incoming\x18g \x03(\r\x12\x13\n\x0bignore_mqtt\x18h \x01(\x08\x12\x19\n\x11\x63onfig_ok_to_mqtt\x18i \x01(\x08\"\xae\x02\n\nRegionCode\x12\t\n\x05UNSET\x10\x00\x12\x06\n\x02US\x10\x01\x12\n\n\x06\x45U_433\x10\x02\x12\n\n\x06\x45U_868\x10\x03\x12\x06\n\x02\x43N\x10\x04\x12\x06\n\x02JP\x10\x05\x12\x07\n\x03\x41NZ\x10\x06\x12\x06\n\x02KR\x10\x07\x12\x06\n\x02TW\x10\x08\x12\x06\n\x02RU\x10\t\x12\x06\n\x02IN\x10\n\x12\n\n\x06NZ_865\x10\x0b\x12\x06\n\x02TH\x10\x0c\x12\x0b\n\x07LORA_24\x10\r\x12\n\n\x06UA_433\x10\x0e\x12\n\n\x06UA_868\x10\x0f\x12\n\n\x06MY_433\x10\x10\x12\n\n\x06MY_919\x10\x11\x12\n\n\x06SG_923\x10\x12\x12\n\n\x06PH_433\x10\x13\x12\n\n\x06PH_868\x10\x14\x12\n\n\x06PH_915\x10\x15\x12\x0b\n\x07\x41NZ_433\x10\x16\x12\n\n\x06KZ_433\x10\x17\x12\n\n\x06KZ_863\x10\x18\x12\n\n\x06NP_865\x10\x19\x12\n\n\x06\x42R_902\x10\x1a\"\xbd\x01\n\x0bModemPreset\x12\r\n\tLONG_FAST\x10\x00\x12\x11\n\tLONG_SLOW\x10\x01\x1a\x02\x08\x01\x12\x16\n\x0eVERY_LONG_SLOW\x10\x02\x1a\x02\x08\x01\x12\x0f\n\x0bMEDIUM_SLOW\x10\x03\x12\x0f\n\x0bMEDIUM_FAST\x10\x04\x12\x0e\n\nSHORT_SLOW\x10\x05\x12\x0e\n\nSHORT_FAST\x10\x06\x12\x11\n\rLONG_MODERATE\x10\x07\x12\x0f\n\x0bSHORT_TURBO\x10\x08\x12\x0e\n\nLONG_TURBO\x10\t\x1a\xb6\x01\n\x0f\x42luetoothConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x45\n\x04mode\x18\x02 \x01(\x0e\x32\x37.meshtastic.protobuf.Config.BluetoothConfig.PairingMode\x12\x11\n\tfixed_pin\x18\x03 \x01(\r\"8\n\x0bPairingMode\x12\x0e\n\nRANDOM_PIN\x10\x00\x12\r\n\tFIXED_PIN\x10\x01\x12\n\n\x06NO_PIN\x10\x02\x1a\xb6\x01\n\x0eSecurityConfig\x12\x12\n\npublic_key\x18\x01 \x01(\x0c\x12\x13\n\x0bprivate_key\x18\x02 \x01(\x0c\x12\x11\n\tadmin_key\x18\x03 \x03(\x0c\x12\x12\n\nis_managed\x18\x04 \x01(\x08\x12\x16\n\x0eserial_enabled\x18\x05 \x01(\x08\x12\x1d\n\x15\x64\x65\x62ug_log_api_enabled\x18\x06 \x01(\x08\x12\x1d\n\x15\x61\x64min_channel_enabled\x18\x08 \x01(\x08\x1a\x12\n\x10SessionkeyConfigB\x11\n\x0fpayload_variantBb\n\x14org.meshtastic.protoB\x0c\x43onfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/protobuf/config.proto\x12\x13meshtastic.protobuf\x1a#meshtastic/protobuf/device_ui.proto\x1a meshtastic/protobuf/nanopb.proto\"\xd6.\n\x06\x43onfig\x12:\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfigH\x00\x12>\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfigH\x00\x12\x38\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfigH\x00\x12<\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfigH\x00\x12<\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfigH\x00\x12\x36\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfigH\x00\x12@\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfigH\x00\x12>\n\x08security\x18\x08 \x01(\x0b\x32*.meshtastic.protobuf.Config.SecurityConfigH\x00\x12\x42\n\nsessionkey\x18\t \x01(\x0b\x32,.meshtastic.protobuf.Config.SessionkeyConfigH\x00\x12\x38\n\tdevice_ui\x18\n \x01(\x0b\x32#.meshtastic.protobuf.DeviceUIConfigH\x00\x1a\x9f\x07\n\x0c\x44\x65viceConfig\x12;\n\x04role\x18\x01 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x1a\n\x0eserial_enabled\x18\x02 \x01(\x08\x42\x02\x18\x01\x12\x13\n\x0b\x62utton_gpio\x18\x04 \x01(\r\x12\x13\n\x0b\x62uzzer_gpio\x18\x05 \x01(\r\x12R\n\x10rebroadcast_mode\x18\x06 \x01(\x0e\x32\x38.meshtastic.protobuf.Config.DeviceConfig.RebroadcastMode\x12 \n\x18node_info_broadcast_secs\x18\x07 \x01(\r\x12\"\n\x1a\x64ouble_tap_as_button_press\x18\x08 \x01(\x08\x12\x16\n\nis_managed\x18\t \x01(\x08\x42\x02\x18\x01\x12\x1c\n\x14\x64isable_triple_click\x18\n \x01(\x08\x12\x14\n\x05tzdef\x18\x0b \x01(\tB\x05\x92?\x02\x08\x41\x12\x1e\n\x16led_heartbeat_disabled\x18\x0c \x01(\x08\x12O\n\x0b\x62uzzer_mode\x18\r \x01(\x0e\x32\x33.meshtastic.protobuf.Config.DeviceConfig.BuzzerModeB\x05\x92?\x02\x38\x08\"\xd4\x01\n\x04Role\x12\n\n\x06\x43LIENT\x10\x00\x12\x0f\n\x0b\x43LIENT_MUTE\x10\x01\x12\n\n\x06ROUTER\x10\x02\x12\x15\n\rROUTER_CLIENT\x10\x03\x1a\x02\x08\x01\x12\x10\n\x08REPEATER\x10\x04\x1a\x02\x08\x01\x12\x0b\n\x07TRACKER\x10\x05\x12\n\n\x06SENSOR\x10\x06\x12\x07\n\x03TAK\x10\x07\x12\x11\n\rCLIENT_HIDDEN\x10\x08\x12\x12\n\x0eLOST_AND_FOUND\x10\t\x12\x0f\n\x0bTAK_TRACKER\x10\n\x12\x0f\n\x0bROUTER_LATE\x10\x0b\x12\x0f\n\x0b\x43LIENT_BASE\x10\x0c\"s\n\x0fRebroadcastMode\x12\x07\n\x03\x41LL\x10\x00\x12\x15\n\x11\x41LL_SKIP_DECODING\x10\x01\x12\x0e\n\nLOCAL_ONLY\x10\x02\x12\x0e\n\nKNOWN_ONLY\x10\x03\x12\x08\n\x04NONE\x10\x04\x12\x16\n\x12\x43ORE_PORTNUMS_ONLY\x10\x05\"i\n\nBuzzerMode\x12\x0f\n\x0b\x41LL_ENABLED\x10\x00\x12\x0c\n\x08\x44ISABLED\x10\x01\x12\x16\n\x12NOTIFICATIONS_ONLY\x10\x02\x12\x0f\n\x0bSYSTEM_ONLY\x10\x03\x12\x13\n\x0f\x44IRECT_MSG_ONLY\x10\x04\x1a\x9a\x05\n\x0ePositionConfig\x12\x1f\n\x17position_broadcast_secs\x18\x01 \x01(\r\x12(\n position_broadcast_smart_enabled\x18\x02 \x01(\x08\x12\x16\n\x0e\x66ixed_position\x18\x03 \x01(\x08\x12\x17\n\x0bgps_enabled\x18\x04 \x01(\x08\x42\x02\x18\x01\x12\x1b\n\x13gps_update_interval\x18\x05 \x01(\r\x12\x1c\n\x10gps_attempt_time\x18\x06 \x01(\rB\x02\x18\x01\x12\x16\n\x0eposition_flags\x18\x07 \x01(\r\x12\x0f\n\x07rx_gpio\x18\x08 \x01(\r\x12\x0f\n\x07tx_gpio\x18\t \x01(\r\x12(\n broadcast_smart_minimum_distance\x18\n \x01(\r\x12-\n%broadcast_smart_minimum_interval_secs\x18\x0b \x01(\r\x12\x13\n\x0bgps_en_gpio\x18\x0c \x01(\r\x12\x44\n\x08gps_mode\x18\r \x01(\x0e\x32\x32.meshtastic.protobuf.Config.PositionConfig.GpsMode\"\xab\x01\n\rPositionFlags\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x41LTITUDE\x10\x01\x12\x10\n\x0c\x41LTITUDE_MSL\x10\x02\x12\x16\n\x12GEOIDAL_SEPARATION\x10\x04\x12\x07\n\x03\x44OP\x10\x08\x12\t\n\x05HVDOP\x10\x10\x12\r\n\tSATINVIEW\x10 \x12\n\n\x06SEQ_NO\x10@\x12\x0e\n\tTIMESTAMP\x10\x80\x01\x12\x0c\n\x07HEADING\x10\x80\x02\x12\n\n\x05SPEED\x10\x80\x04\"5\n\x07GpsMode\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07\x45NABLED\x10\x01\x12\x0f\n\x0bNOT_PRESENT\x10\x02\x1a\x8b\x02\n\x0bPowerConfig\x12\x17\n\x0fis_power_saving\x18\x01 \x01(\x08\x12&\n\x1eon_battery_shutdown_after_secs\x18\x02 \x01(\r\x12\x1f\n\x17\x61\x64\x63_multiplier_override\x18\x03 \x01(\x02\x12\x1b\n\x13wait_bluetooth_secs\x18\x04 \x01(\r\x12\x10\n\x08sds_secs\x18\x06 \x01(\r\x12\x0f\n\x07ls_secs\x18\x07 \x01(\r\x12\x15\n\rmin_wake_secs\x18\x08 \x01(\r\x12)\n\x1a\x64\x65vice_battery_ina_address\x18\t \x01(\rB\x05\x92?\x02\x38\x08\x12\x18\n\x10powermon_enables\x18 \x01(\x04\x1a\x93\x04\n\rNetworkConfig\x12\x14\n\x0cwifi_enabled\x18\x01 \x01(\x08\x12\x18\n\twifi_ssid\x18\x03 \x01(\tB\x05\x92?\x02\x08!\x12\x17\n\x08wifi_psk\x18\x04 \x01(\tB\x05\x92?\x02\x08\x41\x12\x19\n\nntp_server\x18\x05 \x01(\tB\x05\x92?\x02\x08!\x12\x13\n\x0b\x65th_enabled\x18\x06 \x01(\x08\x12K\n\x0c\x61\x64\x64ress_mode\x18\x07 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.NetworkConfig.AddressMode\x12I\n\x0bipv4_config\x18\x08 \x01(\x0b\x32\x34.meshtastic.protobuf.Config.NetworkConfig.IpV4Config\x12\x1d\n\x0ersyslog_server\x18\t \x01(\tB\x05\x92?\x02\x08!\x12\x19\n\x11\x65nabled_protocols\x18\n \x01(\r\x12\x14\n\x0cipv6_enabled\x18\x0b \x01(\x08\x1a\x46\n\nIpV4Config\x12\n\n\x02ip\x18\x01 \x01(\x07\x12\x0f\n\x07gateway\x18\x02 \x01(\x07\x12\x0e\n\x06subnet\x18\x03 \x01(\x07\x12\x0b\n\x03\x64ns\x18\x04 \x01(\x07\"#\n\x0b\x41\x64\x64ressMode\x12\x08\n\x04\x44HCP\x10\x00\x12\n\n\x06STATIC\x10\x01\"4\n\rProtocolFlags\x12\x10\n\x0cNO_BROADCAST\x10\x00\x12\x11\n\rUDP_BROADCAST\x10\x01\x1a\xef\x08\n\rDisplayConfig\x12\x16\n\x0escreen_on_secs\x18\x01 \x01(\r\x12_\n\ngps_format\x18\x02 \x01(\x0e\x32G.meshtastic.protobuf.Config.DisplayConfig.DeprecatedGpsCoordinateFormatB\x02\x18\x01\x12!\n\x19\x61uto_screen_carousel_secs\x18\x03 \x01(\r\x12\x1d\n\x11\x63ompass_north_top\x18\x04 \x01(\x08\x42\x02\x18\x01\x12\x13\n\x0b\x66lip_screen\x18\x05 \x01(\x08\x12\x45\n\x05units\x18\x06 \x01(\x0e\x32\x36.meshtastic.protobuf.Config.DisplayConfig.DisplayUnits\x12@\n\x04oled\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.DisplayConfig.OledType\x12J\n\x0b\x64isplaymode\x18\x08 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.DisplayConfig.DisplayMode\x12\x14\n\x0cheading_bold\x18\t \x01(\x08\x12\x1d\n\x15wake_on_tap_or_motion\x18\n \x01(\x08\x12Y\n\x13\x63ompass_orientation\x18\x0b \x01(\x0e\x32<.meshtastic.protobuf.Config.DisplayConfig.CompassOrientation\x12\x15\n\ruse_12h_clock\x18\x0c \x01(\x08\x12\x1a\n\x12use_long_node_name\x18\r \x01(\x08\x12\x1e\n\x16\x65nable_message_bubbles\x18\x0e \x01(\x08\"+\n\x1d\x44\x65precatedGpsCoordinateFormat\x12\n\n\x06UNUSED\x10\x00\"(\n\x0c\x44isplayUnits\x12\n\n\x06METRIC\x10\x00\x12\x0c\n\x08IMPERIAL\x10\x01\"\x7f\n\x08OledType\x12\r\n\tOLED_AUTO\x10\x00\x12\x10\n\x0cOLED_SSD1306\x10\x01\x12\x0f\n\x0bOLED_SH1106\x10\x02\x12\x0f\n\x0bOLED_SH1107\x10\x03\x12\x17\n\x13OLED_SH1107_128_128\x10\x04\x12\x17\n\x13OLED_SH1107_ROTATED\x10\x05\"A\n\x0b\x44isplayMode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x0c\n\x08TWOCOLOR\x10\x01\x12\x0c\n\x08INVERTED\x10\x02\x12\t\n\x05\x43OLOR\x10\x03\"\xba\x01\n\x12\x43ompassOrientation\x12\r\n\tDEGREES_0\x10\x00\x12\x0e\n\nDEGREES_90\x10\x01\x12\x0f\n\x0b\x44\x45GREES_180\x10\x02\x12\x0f\n\x0b\x44\x45GREES_270\x10\x03\x12\x16\n\x12\x44\x45GREES_0_INVERTED\x10\x04\x12\x17\n\x13\x44\x45GREES_90_INVERTED\x10\x05\x12\x18\n\x14\x44\x45GREES_180_INVERTED\x10\x06\x12\x18\n\x14\x44\x45GREES_270_INVERTED\x10\x07\x1a\xdc\n\n\nLoRaConfig\x12\x12\n\nuse_preset\x18\x01 \x01(\x08\x12H\n\x0cmodem_preset\x18\x02 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.LoRaConfig.ModemPreset\x12\x18\n\tbandwidth\x18\x03 \x01(\rB\x05\x92?\x02\x38\x10\x12\x15\n\rspread_factor\x18\x04 \x01(\r\x12\x1a\n\x0b\x63oding_rate\x18\x05 \x01(\rB\x05\x92?\x02\x38\x08\x12\x18\n\x10\x66requency_offset\x18\x06 \x01(\x02\x12\x41\n\x06region\x18\x07 \x01(\x0e\x32\x31.meshtastic.protobuf.Config.LoRaConfig.RegionCode\x12\x11\n\thop_limit\x18\x08 \x01(\r\x12\x12\n\ntx_enabled\x18\t \x01(\x08\x12\x17\n\x08tx_power\x18\n \x01(\x05\x42\x05\x92?\x02\x38\x08\x12\x1a\n\x0b\x63hannel_num\x18\x0b \x01(\rB\x05\x92?\x02\x38\x10\x12\x1b\n\x13override_duty_cycle\x18\x0c \x01(\x08\x12\x1e\n\x16sx126x_rx_boosted_gain\x18\r \x01(\x08\x12\x1a\n\x12override_frequency\x18\x0e \x01(\x02\x12\x17\n\x0fpa_fan_disabled\x18\x0f \x01(\x08\x12\x1e\n\x0fignore_incoming\x18g \x03(\rB\x05\x92?\x02\x10\x03\x12\x13\n\x0bignore_mqtt\x18h \x01(\x08\x12\x19\n\x11\x63onfig_ok_to_mqtt\x18i \x01(\x08\x12I\n\x0c\x66\x65m_lna_mode\x18j \x01(\x0e\x32\x33.meshtastic.protobuf.Config.LoRaConfig.FEM_LNA_Mode\x12\x17\n\x0fserial_hal_only\x18k \x01(\x08\"\x87\x03\n\nRegionCode\x12\t\n\x05UNSET\x10\x00\x12\x06\n\x02US\x10\x01\x12\n\n\x06\x45U_433\x10\x02\x12\n\n\x06\x45U_868\x10\x03\x12\x06\n\x02\x43N\x10\x04\x12\x06\n\x02JP\x10\x05\x12\x07\n\x03\x41NZ\x10\x06\x12\x06\n\x02KR\x10\x07\x12\x06\n\x02TW\x10\x08\x12\x06\n\x02RU\x10\t\x12\x06\n\x02IN\x10\n\x12\n\n\x06NZ_865\x10\x0b\x12\x06\n\x02TH\x10\x0c\x12\x0b\n\x07LORA_24\x10\r\x12\n\n\x06UA_433\x10\x0e\x12\n\n\x06UA_868\x10\x0f\x12\n\n\x06MY_433\x10\x10\x12\n\n\x06MY_919\x10\x11\x12\n\n\x06SG_923\x10\x12\x12\n\n\x06PH_433\x10\x13\x12\n\n\x06PH_868\x10\x14\x12\n\n\x06PH_915\x10\x15\x12\x0b\n\x07\x41NZ_433\x10\x16\x12\n\n\x06KZ_433\x10\x17\x12\n\n\x06KZ_863\x10\x18\x12\n\n\x06NP_865\x10\x19\x12\n\n\x06\x42R_902\x10\x1a\x12\x0b\n\x07ITU1_2M\x10\x1b\x12\x0b\n\x07ITU2_2M\x10\x1c\x12\n\n\x06\x45U_866\x10\x1d\x12\n\n\x06\x45U_874\x10\x1e\x12\n\n\x06\x45U_917\x10\x1f\x12\x0c\n\x08\x45U_N_868\x10 \x12\x0b\n\x07ITU3_2M\x10!\"\xfd\x01\n\x0bModemPreset\x12\r\n\tLONG_FAST\x10\x00\x12\x11\n\tLONG_SLOW\x10\x01\x1a\x02\x08\x01\x12\x16\n\x0eVERY_LONG_SLOW\x10\x02\x1a\x02\x08\x01\x12\x0f\n\x0bMEDIUM_SLOW\x10\x03\x12\x0f\n\x0bMEDIUM_FAST\x10\x04\x12\x0e\n\nSHORT_SLOW\x10\x05\x12\x0e\n\nSHORT_FAST\x10\x06\x12\x11\n\rLONG_MODERATE\x10\x07\x12\x0f\n\x0bSHORT_TURBO\x10\x08\x12\x0e\n\nLONG_TURBO\x10\t\x12\r\n\tLITE_FAST\x10\n\x12\r\n\tLITE_SLOW\x10\x0b\x12\x0f\n\x0bNARROW_FAST\x10\x0c\x12\x0f\n\x0bNARROW_SLOW\x10\r\":\n\x0c\x46\x45M_LNA_Mode\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07\x45NABLED\x10\x01\x12\x0f\n\x0bNOT_PRESENT\x10\x02\x1a\xb6\x01\n\x0f\x42luetoothConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x45\n\x04mode\x18\x02 \x01(\x0e\x32\x37.meshtastic.protobuf.Config.BluetoothConfig.PairingMode\x12\x11\n\tfixed_pin\x18\x03 \x01(\r\"8\n\x0bPairingMode\x12\x0e\n\nRANDOM_PIN\x10\x00\x12\r\n\tFIXED_PIN\x10\x01\x12\n\n\x06NO_PIN\x10\x02\x1a\xcd\x01\n\x0eSecurityConfig\x12\x19\n\npublic_key\x18\x01 \x01(\x0c\x42\x05\x92?\x02\x08 \x12\x1a\n\x0bprivate_key\x18\x02 \x01(\x0c\x42\x05\x92?\x02\x08 \x12\x1a\n\tadmin_key\x18\x03 \x03(\x0c\x42\x07\x92?\x04\x08 \x10\x03\x12\x12\n\nis_managed\x18\x04 \x01(\x08\x12\x16\n\x0eserial_enabled\x18\x05 \x01(\x08\x12\x1d\n\x15\x64\x65\x62ug_log_api_enabled\x18\x06 \x01(\x08\x12\x1d\n\x15\x61\x64min_channel_enabled\x18\x08 \x01(\x08\x1a\x12\n\x10SessionkeyConfigB\x11\n\x0fpayload_variantBb\n\x14org.meshtastic.protoB\x0c\x43onfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -30,10 +31,24 @@ if _descriptor._USE_C_DESCRIPTORS == False: _CONFIG_DEVICECONFIG.fields_by_name['serial_enabled']._serialized_options = b'\030\001' _CONFIG_DEVICECONFIG.fields_by_name['is_managed']._options = None _CONFIG_DEVICECONFIG.fields_by_name['is_managed']._serialized_options = b'\030\001' + _CONFIG_DEVICECONFIG.fields_by_name['tzdef']._options = None + _CONFIG_DEVICECONFIG.fields_by_name['tzdef']._serialized_options = b'\222?\002\010A' + _CONFIG_DEVICECONFIG.fields_by_name['buzzer_mode']._options = None + _CONFIG_DEVICECONFIG.fields_by_name['buzzer_mode']._serialized_options = b'\222?\0028\010' _CONFIG_POSITIONCONFIG.fields_by_name['gps_enabled']._options = None _CONFIG_POSITIONCONFIG.fields_by_name['gps_enabled']._serialized_options = b'\030\001' _CONFIG_POSITIONCONFIG.fields_by_name['gps_attempt_time']._options = None _CONFIG_POSITIONCONFIG.fields_by_name['gps_attempt_time']._serialized_options = b'\030\001' + _CONFIG_POWERCONFIG.fields_by_name['device_battery_ina_address']._options = None + _CONFIG_POWERCONFIG.fields_by_name['device_battery_ina_address']._serialized_options = b'\222?\0028\010' + _CONFIG_NETWORKCONFIG.fields_by_name['wifi_ssid']._options = None + _CONFIG_NETWORKCONFIG.fields_by_name['wifi_ssid']._serialized_options = b'\222?\002\010!' + _CONFIG_NETWORKCONFIG.fields_by_name['wifi_psk']._options = None + _CONFIG_NETWORKCONFIG.fields_by_name['wifi_psk']._serialized_options = b'\222?\002\010A' + _CONFIG_NETWORKCONFIG.fields_by_name['ntp_server']._options = None + _CONFIG_NETWORKCONFIG.fields_by_name['ntp_server']._serialized_options = b'\222?\002\010!' + _CONFIG_NETWORKCONFIG.fields_by_name['rsyslog_server']._options = None + _CONFIG_NETWORKCONFIG.fields_by_name['rsyslog_server']._serialized_options = b'\222?\002\010!' _CONFIG_DISPLAYCONFIG.fields_by_name['gps_format']._options = None _CONFIG_DISPLAYCONFIG.fields_by_name['gps_format']._serialized_options = b'\030\001' _CONFIG_DISPLAYCONFIG.fields_by_name['compass_north_top']._options = None @@ -42,56 +57,74 @@ if _descriptor._USE_C_DESCRIPTORS == False: _CONFIG_LORACONFIG_MODEMPRESET.values_by_name["LONG_SLOW"]._serialized_options = b'\010\001' _CONFIG_LORACONFIG_MODEMPRESET.values_by_name["VERY_LONG_SLOW"]._options = None _CONFIG_LORACONFIG_MODEMPRESET.values_by_name["VERY_LONG_SLOW"]._serialized_options = b'\010\001' - _globals['_CONFIG']._serialized_start=95 - _globals['_CONFIG']._serialized_end=5592 - _globals['_CONFIG_DEVICECONFIG']._serialized_start=724 - _globals['_CONFIG_DEVICECONFIG']._serialized_end=1637 - _globals['_CONFIG_DEVICECONFIG_ROLE']._serialized_start=1201 - _globals['_CONFIG_DEVICECONFIG_ROLE']._serialized_end=1413 - _globals['_CONFIG_DEVICECONFIG_REBROADCASTMODE']._serialized_start=1415 - _globals['_CONFIG_DEVICECONFIG_REBROADCASTMODE']._serialized_end=1530 - _globals['_CONFIG_DEVICECONFIG_BUZZERMODE']._serialized_start=1532 - _globals['_CONFIG_DEVICECONFIG_BUZZERMODE']._serialized_end=1637 - _globals['_CONFIG_POSITIONCONFIG']._serialized_start=1640 - _globals['_CONFIG_POSITIONCONFIG']._serialized_end=2306 - _globals['_CONFIG_POSITIONCONFIG_POSITIONFLAGS']._serialized_start=2080 - _globals['_CONFIG_POSITIONCONFIG_POSITIONFLAGS']._serialized_end=2251 - _globals['_CONFIG_POSITIONCONFIG_GPSMODE']._serialized_start=2253 - _globals['_CONFIG_POSITIONCONFIG_GPSMODE']._serialized_end=2306 - _globals['_CONFIG_POWERCONFIG']._serialized_start=2309 - _globals['_CONFIG_POWERCONFIG']._serialized_end=2569 - _globals['_CONFIG_NETWORKCONFIG']._serialized_start=2572 - _globals['_CONFIG_NETWORKCONFIG']._serialized_end=3075 - _globals['_CONFIG_NETWORKCONFIG_IPV4CONFIG']._serialized_start=2914 - _globals['_CONFIG_NETWORKCONFIG_IPV4CONFIG']._serialized_end=2984 - _globals['_CONFIG_NETWORKCONFIG_ADDRESSMODE']._serialized_start=2986 - _globals['_CONFIG_NETWORKCONFIG_ADDRESSMODE']._serialized_end=3021 - _globals['_CONFIG_NETWORKCONFIG_PROTOCOLFLAGS']._serialized_start=3023 - _globals['_CONFIG_NETWORKCONFIG_PROTOCOLFLAGS']._serialized_end=3075 - _globals['_CONFIG_DISPLAYCONFIG']._serialized_start=3078 - _globals['_CONFIG_DISPLAYCONFIG']._serialized_end=4156 - _globals['_CONFIG_DISPLAYCONFIG_DEPRECATEDGPSCOORDINATEFORMAT']._serialized_start=3711 - _globals['_CONFIG_DISPLAYCONFIG_DEPRECATEDGPSCOORDINATEFORMAT']._serialized_end=3754 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_start=3756 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_end=3796 - _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_start=3798 - _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_end=3900 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_start=3902 - _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_end=3967 - _globals['_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION']._serialized_start=3970 - _globals['_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION']._serialized_end=4156 - _globals['_CONFIG_LORACONFIG']._serialized_start=4159 - _globals['_CONFIG_LORACONFIG']._serialized_end=5183 - _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_start=4689 - _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_end=4991 - _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_start=4994 - _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_end=5183 - _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_start=5186 - _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_end=5368 - _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_start=5312 - _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_end=5368 - _globals['_CONFIG_SECURITYCONFIG']._serialized_start=5371 - _globals['_CONFIG_SECURITYCONFIG']._serialized_end=5553 - _globals['_CONFIG_SESSIONKEYCONFIG']._serialized_start=5555 - _globals['_CONFIG_SESSIONKEYCONFIG']._serialized_end=5573 + _CONFIG_LORACONFIG.fields_by_name['bandwidth']._options = None + _CONFIG_LORACONFIG.fields_by_name['bandwidth']._serialized_options = b'\222?\0028\020' + _CONFIG_LORACONFIG.fields_by_name['coding_rate']._options = None + _CONFIG_LORACONFIG.fields_by_name['coding_rate']._serialized_options = b'\222?\0028\010' + _CONFIG_LORACONFIG.fields_by_name['tx_power']._options = None + _CONFIG_LORACONFIG.fields_by_name['tx_power']._serialized_options = b'\222?\0028\010' + _CONFIG_LORACONFIG.fields_by_name['channel_num']._options = None + _CONFIG_LORACONFIG.fields_by_name['channel_num']._serialized_options = b'\222?\0028\020' + _CONFIG_LORACONFIG.fields_by_name['ignore_incoming']._options = None + _CONFIG_LORACONFIG.fields_by_name['ignore_incoming']._serialized_options = b'\222?\002\020\003' + _CONFIG_SECURITYCONFIG.fields_by_name['public_key']._options = None + _CONFIG_SECURITYCONFIG.fields_by_name['public_key']._serialized_options = b'\222?\002\010 ' + _CONFIG_SECURITYCONFIG.fields_by_name['private_key']._options = None + _CONFIG_SECURITYCONFIG.fields_by_name['private_key']._serialized_options = b'\222?\002\010 ' + _CONFIG_SECURITYCONFIG.fields_by_name['admin_key']._options = None + _CONFIG_SECURITYCONFIG.fields_by_name['admin_key']._serialized_options = b'\222?\004\010 \020\003' + _globals['_CONFIG']._serialized_start=129 + _globals['_CONFIG']._serialized_end=6103 + _globals['_CONFIG_DEVICECONFIG']._serialized_start=758 + _globals['_CONFIG_DEVICECONFIG']._serialized_end=1685 + _globals['_CONFIG_DEVICECONFIG_ROLE']._serialized_start=1249 + _globals['_CONFIG_DEVICECONFIG_ROLE']._serialized_end=1461 + _globals['_CONFIG_DEVICECONFIG_REBROADCASTMODE']._serialized_start=1463 + _globals['_CONFIG_DEVICECONFIG_REBROADCASTMODE']._serialized_end=1578 + _globals['_CONFIG_DEVICECONFIG_BUZZERMODE']._serialized_start=1580 + _globals['_CONFIG_DEVICECONFIG_BUZZERMODE']._serialized_end=1685 + _globals['_CONFIG_POSITIONCONFIG']._serialized_start=1688 + _globals['_CONFIG_POSITIONCONFIG']._serialized_end=2354 + _globals['_CONFIG_POSITIONCONFIG_POSITIONFLAGS']._serialized_start=2128 + _globals['_CONFIG_POSITIONCONFIG_POSITIONFLAGS']._serialized_end=2299 + _globals['_CONFIG_POSITIONCONFIG_GPSMODE']._serialized_start=2301 + _globals['_CONFIG_POSITIONCONFIG_GPSMODE']._serialized_end=2354 + _globals['_CONFIG_POWERCONFIG']._serialized_start=2357 + _globals['_CONFIG_POWERCONFIG']._serialized_end=2624 + _globals['_CONFIG_NETWORKCONFIG']._serialized_start=2627 + _globals['_CONFIG_NETWORKCONFIG']._serialized_end=3158 + _globals['_CONFIG_NETWORKCONFIG_IPV4CONFIG']._serialized_start=2997 + _globals['_CONFIG_NETWORKCONFIG_IPV4CONFIG']._serialized_end=3067 + _globals['_CONFIG_NETWORKCONFIG_ADDRESSMODE']._serialized_start=3069 + _globals['_CONFIG_NETWORKCONFIG_ADDRESSMODE']._serialized_end=3104 + _globals['_CONFIG_NETWORKCONFIG_PROTOCOLFLAGS']._serialized_start=3106 + _globals['_CONFIG_NETWORKCONFIG_PROTOCOLFLAGS']._serialized_end=3158 + _globals['_CONFIG_DISPLAYCONFIG']._serialized_start=3161 + _globals['_CONFIG_DISPLAYCONFIG']._serialized_end=4296 + _globals['_CONFIG_DISPLAYCONFIG_DEPRECATEDGPSCOORDINATEFORMAT']._serialized_start=3826 + _globals['_CONFIG_DISPLAYCONFIG_DEPRECATEDGPSCOORDINATEFORMAT']._serialized_end=3869 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_start=3871 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYUNITS']._serialized_end=3911 + _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_start=3913 + _globals['_CONFIG_DISPLAYCONFIG_OLEDTYPE']._serialized_end=4040 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_start=4042 + _globals['_CONFIG_DISPLAYCONFIG_DISPLAYMODE']._serialized_end=4107 + _globals['_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION']._serialized_start=4110 + _globals['_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION']._serialized_end=4296 + _globals['_CONFIG_LORACONFIG']._serialized_start=4299 + _globals['_CONFIG_LORACONFIG']._serialized_end=5671 + _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_start=4964 + _globals['_CONFIG_LORACONFIG_REGIONCODE']._serialized_end=5355 + _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_start=5358 + _globals['_CONFIG_LORACONFIG_MODEMPRESET']._serialized_end=5611 + _globals['_CONFIG_LORACONFIG_FEM_LNA_MODE']._serialized_start=5613 + _globals['_CONFIG_LORACONFIG_FEM_LNA_MODE']._serialized_end=5671 + _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_start=5674 + _globals['_CONFIG_BLUETOOTHCONFIG']._serialized_end=5856 + _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_start=5800 + _globals['_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE']._serialized_end=5856 + _globals['_CONFIG_SECURITYCONFIG']._serialized_start=5859 + _globals['_CONFIG_SECURITYCONFIG']._serialized_end=6064 + _globals['_CONFIG_SESSIONKEYCONFIG']._serialized_start=6066 + _globals['_CONFIG_SESSIONKEYCONFIG']._serialized_end=6084 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/config_pb2.pyi b/meshtastic/protobuf/config_pb2.pyi index 47941b4..a6feaf7 100644 --- a/meshtastic/protobuf/config_pb2.pyi +++ b/meshtastic/protobuf/config_pb2.pyi @@ -1010,6 +1010,10 @@ class Config(google.protobuf.message.Message): """ Can not be auto detected but set by proto. Used for 128x128 screens """ + OLED_SH1107_ROTATED: Config.DisplayConfig._OledType.ValueType # 5 + """ + Can not be auto detected but set by proto. Used for 64x128 rotated screens + """ class OledType(_OledType, metaclass=_OledTypeEnumTypeWrapper): """ @@ -1036,6 +1040,10 @@ class Config(google.protobuf.message.Message): """ Can not be auto detected but set by proto. Used for 128x128 screens """ + OLED_SH1107_ROTATED: Config.DisplayConfig.OledType.ValueType # 5 + """ + Can not be auto detected but set by proto. Used for 64x128 rotated screens + """ class _DisplayMode: ValueType = typing.NewType("ValueType", builtins.int) @@ -1164,6 +1172,7 @@ class Config(google.protobuf.message.Message): COMPASS_ORIENTATION_FIELD_NUMBER: builtins.int USE_12H_CLOCK_FIELD_NUMBER: builtins.int USE_LONG_NODE_NAME_FIELD_NUMBER: builtins.int + ENABLE_MESSAGE_BUBBLES_FIELD_NUMBER: builtins.int screen_on_secs: builtins.int """ Number of seconds the screen stays on after pressing the user button or receiving a message @@ -1222,6 +1231,10 @@ class Config(google.protobuf.message.Message): If false (default), the device will use short names for various display screens. If true, node names will show in long format """ + enable_message_bubbles: builtins.bool + """ + If true, the device will display message bubbles on screen. + """ def __init__( self, *, @@ -1238,8 +1251,9 @@ class Config(google.protobuf.message.Message): compass_orientation: global___Config.DisplayConfig.CompassOrientation.ValueType = ..., use_12h_clock: builtins.bool = ..., use_long_node_name: builtins.bool = ..., + enable_message_bubbles: builtins.bool = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["auto_screen_carousel_secs", b"auto_screen_carousel_secs", "compass_north_top", b"compass_north_top", "compass_orientation", b"compass_orientation", "displaymode", b"displaymode", "flip_screen", b"flip_screen", "gps_format", b"gps_format", "heading_bold", b"heading_bold", "oled", b"oled", "screen_on_secs", b"screen_on_secs", "units", b"units", "use_12h_clock", b"use_12h_clock", "use_long_node_name", b"use_long_node_name", "wake_on_tap_or_motion", b"wake_on_tap_or_motion"]) -> None: ... + def ClearField(self, field_name: typing.Literal["auto_screen_carousel_secs", b"auto_screen_carousel_secs", "compass_north_top", b"compass_north_top", "compass_orientation", b"compass_orientation", "displaymode", b"displaymode", "enable_message_bubbles", b"enable_message_bubbles", "flip_screen", b"flip_screen", "gps_format", b"gps_format", "heading_bold", b"heading_bold", "oled", b"oled", "screen_on_secs", b"screen_on_secs", "units", b"units", "use_12h_clock", b"use_12h_clock", "use_long_node_name", b"use_long_node_name", "wake_on_tap_or_motion", b"wake_on_tap_or_motion"]) -> None: ... @typing.final class LoRaConfig(google.protobuf.message.Message): @@ -1363,6 +1377,31 @@ class Config(google.protobuf.message.Message): """ Brazil 902MHz """ + ITU1_2M: Config.LoRaConfig._RegionCode.ValueType # 27 + """ + ITU Region 1 Amateur Radio 2m band (144-146 MHz) + """ + ITU2_2M: Config.LoRaConfig._RegionCode.ValueType # 28 + """ + ITU Region 2 Amateur Radio 2m band (144-148 MHz) + """ + EU_866: Config.LoRaConfig._RegionCode.ValueType # 29 + """ + EU 866MHz band (Band no. 47b of 2006/771/EC and subsequent amendments) for Non-specific short-range devices (SRD) + """ + EU_874: Config.LoRaConfig._RegionCode.ValueType # 30 + """ + EU 874MHz and 917MHz bands (Band no. 1 and 4 of 2022/172/EC and subsequent amendments) for Non-specific short-range devices (SRD) + """ + EU_917: Config.LoRaConfig._RegionCode.ValueType # 31 + EU_N_868: Config.LoRaConfig._RegionCode.ValueType # 32 + """ + EU 868MHz band, with narrow presets + """ + ITU3_2M: Config.LoRaConfig._RegionCode.ValueType # 33 + """ + ITU Region 3 Amateur Radio 2m band (144-148 MHz) + """ class RegionCode(_RegionCode, metaclass=_RegionCodeEnumTypeWrapper): ... UNSET: Config.LoRaConfig.RegionCode.ValueType # 0 @@ -1473,6 +1512,31 @@ class Config(google.protobuf.message.Message): """ Brazil 902MHz """ + ITU1_2M: Config.LoRaConfig.RegionCode.ValueType # 27 + """ + ITU Region 1 Amateur Radio 2m band (144-146 MHz) + """ + ITU2_2M: Config.LoRaConfig.RegionCode.ValueType # 28 + """ + ITU Region 2 Amateur Radio 2m band (144-148 MHz) + """ + EU_866: Config.LoRaConfig.RegionCode.ValueType # 29 + """ + EU 866MHz band (Band no. 47b of 2006/771/EC and subsequent amendments) for Non-specific short-range devices (SRD) + """ + EU_874: Config.LoRaConfig.RegionCode.ValueType # 30 + """ + EU 874MHz and 917MHz bands (Band no. 1 and 4 of 2022/172/EC and subsequent amendments) for Non-specific short-range devices (SRD) + """ + EU_917: Config.LoRaConfig.RegionCode.ValueType # 31 + EU_N_868: Config.LoRaConfig.RegionCode.ValueType # 32 + """ + EU 868MHz band, with narrow presets + """ + ITU3_2M: Config.LoRaConfig.RegionCode.ValueType # 33 + """ + ITU Region 3 Amateur Radio 2m band (144-148 MHz) + """ class _ModemPreset: ValueType = typing.NewType("ValueType", builtins.int) @@ -1525,6 +1589,31 @@ class Config(google.protobuf.message.Message): Long Range - Turbo This preset performs similarly to LongFast, but with 500Khz bandwidth. """ + LITE_FAST: Config.LoRaConfig._ModemPreset.ValueType # 10 + """ + Lite Fast + Medium range preset optimized for EU 866MHz SRD band with 125kHz bandwidth. + Comparable link budget to MEDIUM_FAST but compliant with Band no. 47b of 2006/771/EC. + """ + LITE_SLOW: Config.LoRaConfig._ModemPreset.ValueType # 11 + """ + Lite Slow + Medium-to-moderate range preset optimized for EU 866MHz SRD band with 125kHz bandwidth. + Comparable link budget to LONG_FAST but compliant with Band no. 47b of 2006/771/EC. + """ + NARROW_FAST: Config.LoRaConfig._ModemPreset.ValueType # 12 + """ + Narrow Fast + Medium-to-moderate range preset optimized for EU 868MHz band with 62.5kHz bandwidth. + Comparable link budget to SHORT_SLOW, but with half the data rate. + Intended to avoid interference with other devices. + """ + NARROW_SLOW: Config.LoRaConfig._ModemPreset.ValueType # 13 + """ + Narrow Slow + Moderate range preset optimized for EU 868MHz band with 62.5kHz bandwidth. + Comparable link budget and data rate to LONG_FAST. + """ class ModemPreset(_ModemPreset, metaclass=_ModemPresetEnumTypeWrapper): """ @@ -1577,6 +1666,64 @@ class Config(google.protobuf.message.Message): Long Range - Turbo This preset performs similarly to LongFast, but with 500Khz bandwidth. """ + LITE_FAST: Config.LoRaConfig.ModemPreset.ValueType # 10 + """ + Lite Fast + Medium range preset optimized for EU 866MHz SRD band with 125kHz bandwidth. + Comparable link budget to MEDIUM_FAST but compliant with Band no. 47b of 2006/771/EC. + """ + LITE_SLOW: Config.LoRaConfig.ModemPreset.ValueType # 11 + """ + Lite Slow + Medium-to-moderate range preset optimized for EU 866MHz SRD band with 125kHz bandwidth. + Comparable link budget to LONG_FAST but compliant with Band no. 47b of 2006/771/EC. + """ + NARROW_FAST: Config.LoRaConfig.ModemPreset.ValueType # 12 + """ + Narrow Fast + Medium-to-moderate range preset optimized for EU 868MHz band with 62.5kHz bandwidth. + Comparable link budget to SHORT_SLOW, but with half the data rate. + Intended to avoid interference with other devices. + """ + NARROW_SLOW: Config.LoRaConfig.ModemPreset.ValueType # 13 + """ + Narrow Slow + Moderate range preset optimized for EU 868MHz band with 62.5kHz bandwidth. + Comparable link budget and data rate to LONG_FAST. + """ + + class _FEM_LNA_Mode: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _FEM_LNA_ModeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.LoRaConfig._FEM_LNA_Mode.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + DISABLED: Config.LoRaConfig._FEM_LNA_Mode.ValueType # 0 + """ + FEM_LNA is present but disabled + """ + ENABLED: Config.LoRaConfig._FEM_LNA_Mode.ValueType # 1 + """ + FEM_LNA is present and enabled + """ + NOT_PRESENT: Config.LoRaConfig._FEM_LNA_Mode.ValueType # 2 + """ + FEM_LNA is not present on the device + """ + + class FEM_LNA_Mode(_FEM_LNA_Mode, metaclass=_FEM_LNA_ModeEnumTypeWrapper): ... + DISABLED: Config.LoRaConfig.FEM_LNA_Mode.ValueType # 0 + """ + FEM_LNA is present but disabled + """ + ENABLED: Config.LoRaConfig.FEM_LNA_Mode.ValueType # 1 + """ + FEM_LNA is present and enabled + """ + NOT_PRESENT: Config.LoRaConfig.FEM_LNA_Mode.ValueType # 2 + """ + FEM_LNA is not present on the device + """ USE_PRESET_FIELD_NUMBER: builtins.int MODEM_PRESET_FIELD_NUMBER: builtins.int @@ -1596,6 +1743,8 @@ class Config(google.protobuf.message.Message): IGNORE_INCOMING_FIELD_NUMBER: builtins.int IGNORE_MQTT_FIELD_NUMBER: builtins.int CONFIG_OK_TO_MQTT_FIELD_NUMBER: builtins.int + FEM_LNA_MODE_FIELD_NUMBER: builtins.int + SERIAL_HAL_ONLY_FIELD_NUMBER: builtins.int use_preset: builtins.bool """ When enabled, the `modem_preset` fields will be adhered to, else the `bandwidth`/`spread_factor`/`coding_rate` @@ -1693,6 +1842,14 @@ class Config(google.protobuf.message.Message): """ Sets the ok_to_mqtt bit on outgoing packets """ + fem_lna_mode: global___Config.LoRaConfig.FEM_LNA_Mode.ValueType + """ + Set where LORA FEM is enabled, disabled, or not present + """ + serial_hal_only: builtins.bool + """ + Don't use radiolib to initialize the radio, instead listen for a serialHal connection + """ @property def ignore_incoming(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: """ @@ -1722,8 +1879,10 @@ class Config(google.protobuf.message.Message): ignore_incoming: collections.abc.Iterable[builtins.int] | None = ..., ignore_mqtt: builtins.bool = ..., config_ok_to_mqtt: builtins.bool = ..., + fem_lna_mode: global___Config.LoRaConfig.FEM_LNA_Mode.ValueType = ..., + serial_hal_only: builtins.bool = ..., ) -> None: ... - def ClearField(self, field_name: typing.Literal["bandwidth", b"bandwidth", "channel_num", b"channel_num", "coding_rate", b"coding_rate", "config_ok_to_mqtt", b"config_ok_to_mqtt", "frequency_offset", b"frequency_offset", "hop_limit", b"hop_limit", "ignore_incoming", b"ignore_incoming", "ignore_mqtt", b"ignore_mqtt", "modem_preset", b"modem_preset", "override_duty_cycle", b"override_duty_cycle", "override_frequency", b"override_frequency", "pa_fan_disabled", b"pa_fan_disabled", "region", b"region", "spread_factor", b"spread_factor", "sx126x_rx_boosted_gain", b"sx126x_rx_boosted_gain", "tx_enabled", b"tx_enabled", "tx_power", b"tx_power", "use_preset", b"use_preset"]) -> None: ... + def ClearField(self, field_name: typing.Literal["bandwidth", b"bandwidth", "channel_num", b"channel_num", "coding_rate", b"coding_rate", "config_ok_to_mqtt", b"config_ok_to_mqtt", "fem_lna_mode", b"fem_lna_mode", "frequency_offset", b"frequency_offset", "hop_limit", b"hop_limit", "ignore_incoming", b"ignore_incoming", "ignore_mqtt", b"ignore_mqtt", "modem_preset", b"modem_preset", "override_duty_cycle", b"override_duty_cycle", "override_frequency", b"override_frequency", "pa_fan_disabled", b"pa_fan_disabled", "region", b"region", "serial_hal_only", b"serial_hal_only", "spread_factor", b"spread_factor", "sx126x_rx_boosted_gain", b"sx126x_rx_boosted_gain", "tx_enabled", b"tx_enabled", "tx_power", b"tx_power", "use_preset", b"use_preset"]) -> None: ... @typing.final class BluetoothConfig(google.protobuf.message.Message): diff --git a/meshtastic/protobuf/connection_status_pb2.py b/meshtastic/protobuf/connection_status_pb2.py index 050e330..9c9156a 100644 --- a/meshtastic/protobuf/connection_status_pb2.py +++ b/meshtastic/protobuf/connection_status_pb2.py @@ -11,9 +11,10 @@ from google.protobuf.internal import builder as _builder _sym_db = _symbol_database.Default() +from meshtastic.protobuf import nanopb_pb2 as meshtastic_dot_protobuf_dot_nanopb__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n+meshtastic/protobuf/connection_status.proto\x12\x13meshtastic.protobuf\"\xd5\x02\n\x16\x44\x65viceConnectionStatus\x12<\n\x04wifi\x18\x01 \x01(\x0b\x32).meshtastic.protobuf.WifiConnectionStatusH\x00\x88\x01\x01\x12\x44\n\x08\x65thernet\x18\x02 \x01(\x0b\x32-.meshtastic.protobuf.EthernetConnectionStatusH\x01\x88\x01\x01\x12\x46\n\tbluetooth\x18\x03 \x01(\x0b\x32..meshtastic.protobuf.BluetoothConnectionStatusH\x02\x88\x01\x01\x12@\n\x06serial\x18\x04 \x01(\x0b\x32+.meshtastic.protobuf.SerialConnectionStatusH\x03\x88\x01\x01\x42\x07\n\x05_wifiB\x0b\n\t_ethernetB\x0c\n\n_bluetoothB\t\n\x07_serial\"p\n\x14WifiConnectionStatus\x12<\n\x06status\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.NetworkConnectionStatus\x12\x0c\n\x04ssid\x18\x02 \x01(\t\x12\x0c\n\x04rssi\x18\x03 \x01(\x05\"X\n\x18\x45thernetConnectionStatus\x12<\n\x06status\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.NetworkConnectionStatus\"{\n\x17NetworkConnectionStatus\x12\x12\n\nip_address\x18\x01 \x01(\x07\x12\x14\n\x0cis_connected\x18\x02 \x01(\x08\x12\x19\n\x11is_mqtt_connected\x18\x03 \x01(\x08\x12\x1b\n\x13is_syslog_connected\x18\x04 \x01(\x08\"L\n\x19\x42luetoothConnectionStatus\x12\x0b\n\x03pin\x18\x01 \x01(\r\x12\x0c\n\x04rssi\x18\x02 \x01(\x05\x12\x14\n\x0cis_connected\x18\x03 \x01(\x08\"<\n\x16SerialConnectionStatus\x12\x0c\n\x04\x62\x61ud\x18\x01 \x01(\r\x12\x14\n\x0cis_connected\x18\x02 \x01(\x08\x42\x66\n\x14org.meshtastic.protoB\x10\x43onnStatusProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n+meshtastic/protobuf/connection_status.proto\x12\x13meshtastic.protobuf\x1a meshtastic/protobuf/nanopb.proto\"\xd5\x02\n\x16\x44\x65viceConnectionStatus\x12<\n\x04wifi\x18\x01 \x01(\x0b\x32).meshtastic.protobuf.WifiConnectionStatusH\x00\x88\x01\x01\x12\x44\n\x08\x65thernet\x18\x02 \x01(\x0b\x32-.meshtastic.protobuf.EthernetConnectionStatusH\x01\x88\x01\x01\x12\x46\n\tbluetooth\x18\x03 \x01(\x0b\x32..meshtastic.protobuf.BluetoothConnectionStatusH\x02\x88\x01\x01\x12@\n\x06serial\x18\x04 \x01(\x0b\x32+.meshtastic.protobuf.SerialConnectionStatusH\x03\x88\x01\x01\x42\x07\n\x05_wifiB\x0b\n\t_ethernetB\x0c\n\n_bluetoothB\t\n\x07_serial\"w\n\x14WifiConnectionStatus\x12<\n\x06status\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.NetworkConnectionStatus\x12\x13\n\x04ssid\x18\x02 \x01(\tB\x05\x92?\x02\x08!\x12\x0c\n\x04rssi\x18\x03 \x01(\x05\"X\n\x18\x45thernetConnectionStatus\x12<\n\x06status\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.NetworkConnectionStatus\"{\n\x17NetworkConnectionStatus\x12\x12\n\nip_address\x18\x01 \x01(\x07\x12\x14\n\x0cis_connected\x18\x02 \x01(\x08\x12\x19\n\x11is_mqtt_connected\x18\x03 \x01(\x08\x12\x1b\n\x13is_syslog_connected\x18\x04 \x01(\x08\"L\n\x19\x42luetoothConnectionStatus\x12\x0b\n\x03pin\x18\x01 \x01(\r\x12\x0c\n\x04rssi\x18\x02 \x01(\x05\x12\x14\n\x0cis_connected\x18\x03 \x01(\x08\"<\n\x16SerialConnectionStatus\x12\x0c\n\x04\x62\x61ud\x18\x01 \x01(\r\x12\x14\n\x0cis_connected\x18\x02 \x01(\x08\x42\x66\n\x14org.meshtastic.protoB\x10\x43onnStatusProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -21,16 +22,18 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.connect if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\020ConnStatusProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _globals['_DEVICECONNECTIONSTATUS']._serialized_start=69 - _globals['_DEVICECONNECTIONSTATUS']._serialized_end=410 - _globals['_WIFICONNECTIONSTATUS']._serialized_start=412 - _globals['_WIFICONNECTIONSTATUS']._serialized_end=524 - _globals['_ETHERNETCONNECTIONSTATUS']._serialized_start=526 - _globals['_ETHERNETCONNECTIONSTATUS']._serialized_end=614 - _globals['_NETWORKCONNECTIONSTATUS']._serialized_start=616 - _globals['_NETWORKCONNECTIONSTATUS']._serialized_end=739 - _globals['_BLUETOOTHCONNECTIONSTATUS']._serialized_start=741 - _globals['_BLUETOOTHCONNECTIONSTATUS']._serialized_end=817 - _globals['_SERIALCONNECTIONSTATUS']._serialized_start=819 - _globals['_SERIALCONNECTIONSTATUS']._serialized_end=879 + _WIFICONNECTIONSTATUS.fields_by_name['ssid']._options = None + _WIFICONNECTIONSTATUS.fields_by_name['ssid']._serialized_options = b'\222?\002\010!' + _globals['_DEVICECONNECTIONSTATUS']._serialized_start=103 + _globals['_DEVICECONNECTIONSTATUS']._serialized_end=444 + _globals['_WIFICONNECTIONSTATUS']._serialized_start=446 + _globals['_WIFICONNECTIONSTATUS']._serialized_end=565 + _globals['_ETHERNETCONNECTIONSTATUS']._serialized_start=567 + _globals['_ETHERNETCONNECTIONSTATUS']._serialized_end=655 + _globals['_NETWORKCONNECTIONSTATUS']._serialized_start=657 + _globals['_NETWORKCONNECTIONSTATUS']._serialized_end=780 + _globals['_BLUETOOTHCONNECTIONSTATUS']._serialized_start=782 + _globals['_BLUETOOTHCONNECTIONSTATUS']._serialized_end=858 + _globals['_SERIALCONNECTIONSTATUS']._serialized_start=860 + _globals['_SERIALCONNECTIONSTATUS']._serialized_end=920 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/device_ui_pb2.py b/meshtastic/protobuf/device_ui_pb2.py index 28eb04e..54a8f6c 100644 --- a/meshtastic/protobuf/device_ui_pb2.py +++ b/meshtastic/protobuf/device_ui_pb2.py @@ -11,9 +11,10 @@ from google.protobuf.internal import builder as _builder _sym_db = _symbol_database.Default() +from meshtastic.protobuf import nanopb_pb2 as meshtastic_dot_protobuf_dot_nanopb__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/device_ui.proto\x12\x13meshtastic.protobuf\"\xff\x05\n\x0e\x44\x65viceUIConfig\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\x19\n\x11screen_brightness\x18\x02 \x01(\r\x12\x16\n\x0escreen_timeout\x18\x03 \x01(\r\x12\x13\n\x0bscreen_lock\x18\x04 \x01(\x08\x12\x15\n\rsettings_lock\x18\x05 \x01(\x08\x12\x10\n\x08pin_code\x18\x06 \x01(\r\x12)\n\x05theme\x18\x07 \x01(\x0e\x32\x1a.meshtastic.protobuf.Theme\x12\x15\n\ralert_enabled\x18\x08 \x01(\x08\x12\x16\n\x0e\x62\x61nner_enabled\x18\t \x01(\x08\x12\x14\n\x0cring_tone_id\x18\n \x01(\r\x12/\n\x08language\x18\x0b \x01(\x0e\x32\x1d.meshtastic.protobuf.Language\x12\x34\n\x0bnode_filter\x18\x0c \x01(\x0b\x32\x1f.meshtastic.protobuf.NodeFilter\x12:\n\x0enode_highlight\x18\r \x01(\x0b\x32\".meshtastic.protobuf.NodeHighlight\x12\x18\n\x10\x63\x61libration_data\x18\x0e \x01(\x0c\x12*\n\x08map_data\x18\x0f \x01(\x0b\x32\x18.meshtastic.protobuf.Map\x12\x36\n\x0c\x63ompass_mode\x18\x10 \x01(\x0e\x32 .meshtastic.protobuf.CompassMode\x12\x18\n\x10screen_rgb_color\x18\x11 \x01(\r\x12\x1b\n\x13is_clockface_analog\x18\x12 \x01(\x08\x12K\n\ngps_format\x18\x13 \x01(\x0e\x32\x37.meshtastic.protobuf.DeviceUIConfig.GpsCoordinateFormat\"V\n\x13GpsCoordinateFormat\x12\x07\n\x03\x44\x45\x43\x10\x00\x12\x07\n\x03\x44MS\x10\x01\x12\x07\n\x03UTM\x10\x02\x12\x08\n\x04MGRS\x10\x03\x12\x07\n\x03OLC\x10\x04\x12\x08\n\x04OSGR\x10\x05\x12\x07\n\x03MLS\x10\x06\"\xa7\x01\n\nNodeFilter\x12\x16\n\x0eunknown_switch\x18\x01 \x01(\x08\x12\x16\n\x0eoffline_switch\x18\x02 \x01(\x08\x12\x19\n\x11public_key_switch\x18\x03 \x01(\x08\x12\x11\n\thops_away\x18\x04 \x01(\x05\x12\x17\n\x0fposition_switch\x18\x05 \x01(\x08\x12\x11\n\tnode_name\x18\x06 \x01(\t\x12\x0f\n\x07\x63hannel\x18\x07 \x01(\x05\"~\n\rNodeHighlight\x12\x13\n\x0b\x63hat_switch\x18\x01 \x01(\x08\x12\x17\n\x0fposition_switch\x18\x02 \x01(\x08\x12\x18\n\x10telemetry_switch\x18\x03 \x01(\x08\x12\x12\n\niaq_switch\x18\x04 \x01(\x08\x12\x11\n\tnode_name\x18\x05 \x01(\t\"=\n\x08GeoPoint\x12\x0c\n\x04zoom\x18\x01 \x01(\x05\x12\x10\n\x08latitude\x18\x02 \x01(\x05\x12\x11\n\tlongitude\x18\x03 \x01(\x05\"U\n\x03Map\x12+\n\x04home\x18\x01 \x01(\x0b\x32\x1d.meshtastic.protobuf.GeoPoint\x12\r\n\x05style\x18\x02 \x01(\t\x12\x12\n\nfollow_gps\x18\x03 \x01(\x08*>\n\x0b\x43ompassMode\x12\x0b\n\x07\x44YNAMIC\x10\x00\x12\x0e\n\nFIXED_RING\x10\x01\x12\x12\n\x0e\x46REEZE_HEADING\x10\x02*%\n\x05Theme\x12\x08\n\x04\x44\x41RK\x10\x00\x12\t\n\x05LIGHT\x10\x01\x12\x07\n\x03RED\x10\x02*\xc0\x02\n\x08Language\x12\x0b\n\x07\x45NGLISH\x10\x00\x12\n\n\x06\x46RENCH\x10\x01\x12\n\n\x06GERMAN\x10\x02\x12\x0b\n\x07ITALIAN\x10\x03\x12\x0e\n\nPORTUGUESE\x10\x04\x12\x0b\n\x07SPANISH\x10\x05\x12\x0b\n\x07SWEDISH\x10\x06\x12\x0b\n\x07\x46INNISH\x10\x07\x12\n\n\x06POLISH\x10\x08\x12\x0b\n\x07TURKISH\x10\t\x12\x0b\n\x07SERBIAN\x10\n\x12\x0b\n\x07RUSSIAN\x10\x0b\x12\t\n\x05\x44UTCH\x10\x0c\x12\t\n\x05GREEK\x10\r\x12\r\n\tNORWEGIAN\x10\x0e\x12\r\n\tSLOVENIAN\x10\x0f\x12\r\n\tUKRAINIAN\x10\x10\x12\r\n\tBULGARIAN\x10\x11\x12\t\n\x05\x43ZECH\x10\x12\x12\n\n\x06\x44\x41NISH\x10\x13\x12\x16\n\x12SIMPLIFIED_CHINESE\x10\x1e\x12\x17\n\x13TRADITIONAL_CHINESE\x10\x1f\x42\x64\n\x14org.meshtastic.protoB\x0e\x44\x65viceUIProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/device_ui.proto\x12\x13meshtastic.protobuf\x1a meshtastic/protobuf/nanopb.proto\"\xa9\x06\n\x0e\x44\x65viceUIConfig\x12\x0f\n\x07version\x18\x01 \x01(\r\x12 \n\x11screen_brightness\x18\x02 \x01(\rB\x05\x92?\x02\x38\x08\x12\x1d\n\x0escreen_timeout\x18\x03 \x01(\rB\x05\x92?\x02\x38\x10\x12\x13\n\x0bscreen_lock\x18\x04 \x01(\x08\x12\x15\n\rsettings_lock\x18\x05 \x01(\x08\x12\x10\n\x08pin_code\x18\x06 \x01(\r\x12)\n\x05theme\x18\x07 \x01(\x0e\x32\x1a.meshtastic.protobuf.Theme\x12\x15\n\ralert_enabled\x18\x08 \x01(\x08\x12\x16\n\x0e\x62\x61nner_enabled\x18\t \x01(\x08\x12\x1b\n\x0cring_tone_id\x18\n \x01(\rB\x05\x92?\x02\x38\x08\x12/\n\x08language\x18\x0b \x01(\x0e\x32\x1d.meshtastic.protobuf.Language\x12\x34\n\x0bnode_filter\x18\x0c \x01(\x0b\x32\x1f.meshtastic.protobuf.NodeFilter\x12:\n\x0enode_highlight\x18\r \x01(\x0b\x32\".meshtastic.protobuf.NodeHighlight\x12\x1f\n\x10\x63\x61libration_data\x18\x0e \x01(\x0c\x42\x05\x92?\x02\x08\x10\x12*\n\x08map_data\x18\x0f \x01(\x0b\x32\x18.meshtastic.protobuf.Map\x12=\n\x0c\x63ompass_mode\x18\x10 \x01(\x0e\x32 .meshtastic.protobuf.CompassModeB\x05\x92?\x02\x38\x08\x12\x18\n\x10screen_rgb_color\x18\x11 \x01(\r\x12\x1b\n\x13is_clockface_analog\x18\x12 \x01(\x08\x12R\n\ngps_format\x18\x13 \x01(\x0e\x32\x37.meshtastic.protobuf.DeviceUIConfig.GpsCoordinateFormatB\x05\x92?\x02\x38\x08\"V\n\x13GpsCoordinateFormat\x12\x07\n\x03\x44\x45\x43\x10\x00\x12\x07\n\x03\x44MS\x10\x01\x12\x07\n\x03UTM\x10\x02\x12\x08\n\x04MGRS\x10\x03\x12\x07\n\x03OLC\x10\x04\x12\x08\n\x04OSGR\x10\x05\x12\x07\n\x03MLS\x10\x06\"\xbc\x01\n\nNodeFilter\x12\x16\n\x0eunknown_switch\x18\x01 \x01(\x08\x12\x16\n\x0eoffline_switch\x18\x02 \x01(\x08\x12\x19\n\x11public_key_switch\x18\x03 \x01(\x08\x12\x18\n\thops_away\x18\x04 \x01(\x05\x42\x05\x92?\x02\x38\x08\x12\x17\n\x0fposition_switch\x18\x05 \x01(\x08\x12\x18\n\tnode_name\x18\x06 \x01(\tB\x05\x92?\x02\x08\x10\x12\x16\n\x07\x63hannel\x18\x07 \x01(\x05\x42\x05\x92?\x02\x38\x08\"\x85\x01\n\rNodeHighlight\x12\x13\n\x0b\x63hat_switch\x18\x01 \x01(\x08\x12\x17\n\x0fposition_switch\x18\x02 \x01(\x08\x12\x18\n\x10telemetry_switch\x18\x03 \x01(\x08\x12\x12\n\niaq_switch\x18\x04 \x01(\x08\x12\x18\n\tnode_name\x18\x05 \x01(\tB\x05\x92?\x02\x08\x10\"D\n\x08GeoPoint\x12\x13\n\x04zoom\x18\x01 \x01(\x05\x42\x05\x92?\x02\x38\x08\x12\x10\n\x08latitude\x18\x02 \x01(\x05\x12\x11\n\tlongitude\x18\x03 \x01(\x05\"\\\n\x03Map\x12+\n\x04home\x18\x01 \x01(\x0b\x32\x1d.meshtastic.protobuf.GeoPoint\x12\x14\n\x05style\x18\x02 \x01(\tB\x05\x92?\x02\x08\x14\x12\x12\n\nfollow_gps\x18\x03 \x01(\x08*>\n\x0b\x43ompassMode\x12\x0b\n\x07\x44YNAMIC\x10\x00\x12\x0e\n\nFIXED_RING\x10\x01\x12\x12\n\x0e\x46REEZE_HEADING\x10\x02*%\n\x05Theme\x12\x08\n\x04\x44\x41RK\x10\x00\x12\t\n\x05LIGHT\x10\x01\x12\x07\n\x03RED\x10\x02*\xc0\x02\n\x08Language\x12\x0b\n\x07\x45NGLISH\x10\x00\x12\n\n\x06\x46RENCH\x10\x01\x12\n\n\x06GERMAN\x10\x02\x12\x0b\n\x07ITALIAN\x10\x03\x12\x0e\n\nPORTUGUESE\x10\x04\x12\x0b\n\x07SPANISH\x10\x05\x12\x0b\n\x07SWEDISH\x10\x06\x12\x0b\n\x07\x46INNISH\x10\x07\x12\n\n\x06POLISH\x10\x08\x12\x0b\n\x07TURKISH\x10\t\x12\x0b\n\x07SERBIAN\x10\n\x12\x0b\n\x07RUSSIAN\x10\x0b\x12\t\n\x05\x44UTCH\x10\x0c\x12\t\n\x05GREEK\x10\r\x12\r\n\tNORWEGIAN\x10\x0e\x12\r\n\tSLOVENIAN\x10\x0f\x12\r\n\tUKRAINIAN\x10\x10\x12\r\n\tBULGARIAN\x10\x11\x12\t\n\x05\x43ZECH\x10\x12\x12\n\n\x06\x44\x41NISH\x10\x13\x12\x16\n\x12SIMPLIFIED_CHINESE\x10\x1e\x12\x17\n\x13TRADITIONAL_CHINESE\x10\x1f\x42\x64\n\x14org.meshtastic.protoB\x0e\x44\x65viceUIProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -21,22 +22,46 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.device_ if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\016DeviceUIProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _globals['_COMPASSMODE']._serialized_start=1278 - _globals['_COMPASSMODE']._serialized_end=1340 - _globals['_THEME']._serialized_start=1342 - _globals['_THEME']._serialized_end=1379 - _globals['_LANGUAGE']._serialized_start=1382 - _globals['_LANGUAGE']._serialized_end=1702 - _globals['_DEVICEUICONFIG']._serialized_start=61 - _globals['_DEVICEUICONFIG']._serialized_end=828 - _globals['_DEVICEUICONFIG_GPSCOORDINATEFORMAT']._serialized_start=742 - _globals['_DEVICEUICONFIG_GPSCOORDINATEFORMAT']._serialized_end=828 - _globals['_NODEFILTER']._serialized_start=831 - _globals['_NODEFILTER']._serialized_end=998 - _globals['_NODEHIGHLIGHT']._serialized_start=1000 - _globals['_NODEHIGHLIGHT']._serialized_end=1126 - _globals['_GEOPOINT']._serialized_start=1128 - _globals['_GEOPOINT']._serialized_end=1189 - _globals['_MAP']._serialized_start=1191 - _globals['_MAP']._serialized_end=1276 + _DEVICEUICONFIG.fields_by_name['screen_brightness']._options = None + _DEVICEUICONFIG.fields_by_name['screen_brightness']._serialized_options = b'\222?\0028\010' + _DEVICEUICONFIG.fields_by_name['screen_timeout']._options = None + _DEVICEUICONFIG.fields_by_name['screen_timeout']._serialized_options = b'\222?\0028\020' + _DEVICEUICONFIG.fields_by_name['ring_tone_id']._options = None + _DEVICEUICONFIG.fields_by_name['ring_tone_id']._serialized_options = b'\222?\0028\010' + _DEVICEUICONFIG.fields_by_name['calibration_data']._options = None + _DEVICEUICONFIG.fields_by_name['calibration_data']._serialized_options = b'\222?\002\010\020' + _DEVICEUICONFIG.fields_by_name['compass_mode']._options = None + _DEVICEUICONFIG.fields_by_name['compass_mode']._serialized_options = b'\222?\0028\010' + _DEVICEUICONFIG.fields_by_name['gps_format']._options = None + _DEVICEUICONFIG.fields_by_name['gps_format']._serialized_options = b'\222?\0028\010' + _NODEFILTER.fields_by_name['hops_away']._options = None + _NODEFILTER.fields_by_name['hops_away']._serialized_options = b'\222?\0028\010' + _NODEFILTER.fields_by_name['node_name']._options = None + _NODEFILTER.fields_by_name['node_name']._serialized_options = b'\222?\002\010\020' + _NODEFILTER.fields_by_name['channel']._options = None + _NODEFILTER.fields_by_name['channel']._serialized_options = b'\222?\0028\010' + _NODEHIGHLIGHT.fields_by_name['node_name']._options = None + _NODEHIGHLIGHT.fields_by_name['node_name']._serialized_options = b'\222?\002\010\020' + _GEOPOINT.fields_by_name['zoom']._options = None + _GEOPOINT.fields_by_name['zoom']._serialized_options = b'\222?\0028\010' + _MAP.fields_by_name['style']._options = None + _MAP.fields_by_name['style']._serialized_options = b'\222?\002\010\024' + _globals['_COMPASSMODE']._serialized_start=1397 + _globals['_COMPASSMODE']._serialized_end=1459 + _globals['_THEME']._serialized_start=1461 + _globals['_THEME']._serialized_end=1498 + _globals['_LANGUAGE']._serialized_start=1501 + _globals['_LANGUAGE']._serialized_end=1821 + _globals['_DEVICEUICONFIG']._serialized_start=95 + _globals['_DEVICEUICONFIG']._serialized_end=904 + _globals['_DEVICEUICONFIG_GPSCOORDINATEFORMAT']._serialized_start=818 + _globals['_DEVICEUICONFIG_GPSCOORDINATEFORMAT']._serialized_end=904 + _globals['_NODEFILTER']._serialized_start=907 + _globals['_NODEFILTER']._serialized_end=1095 + _globals['_NODEHIGHLIGHT']._serialized_start=1098 + _globals['_NODEHIGHLIGHT']._serialized_end=1231 + _globals['_GEOPOINT']._serialized_start=1233 + _globals['_GEOPOINT']._serialized_end=1301 + _globals['_MAP']._serialized_start=1303 + _globals['_MAP']._serialized_end=1395 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/deviceonly_pb2.py b/meshtastic/protobuf/deviceonly_pb2.py index 06af5bc..59ded56 100644 --- a/meshtastic/protobuf/deviceonly_pb2.py +++ b/meshtastic/protobuf/deviceonly_pb2.py @@ -19,7 +19,7 @@ from meshtastic.protobuf import telemetry_pb2 as meshtastic_dot_protobuf_dot_tel from meshtastic.protobuf import nanopb_pb2 as meshtastic_dot_protobuf_dot_nanopb__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$meshtastic/protobuf/deviceonly.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a#meshtastic/protobuf/localonly.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/nanopb.proto\"\x99\x01\n\x0cPositionLite\x12\x12\n\nlatitude_i\x18\x01 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x02 \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x03 \x01(\x05\x12\x0c\n\x04time\x18\x04 \x01(\x07\x12@\n\x0flocation_source\x18\x05 \x01(\x0e\x32\'.meshtastic.protobuf.Position.LocSource\"\x94\x02\n\x08UserLite\x12\x13\n\x07macaddr\x18\x01 \x01(\x0c\x42\x02\x18\x01\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x34\n\x08hw_model\x18\x04 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x05 \x01(\x08\x12;\n\x04role\x18\x06 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x12\n\npublic_key\x18\x07 \x01(\x0c\x12\x1c\n\x0fis_unmessagable\x18\t \x01(\x08H\x00\x88\x01\x01\x42\x12\n\x10_is_unmessagable\"\xf0\x02\n\x0cNodeInfoLite\x12\x0b\n\x03num\x18\x01 \x01(\r\x12+\n\x04user\x18\x02 \x01(\x0b\x32\x1d.meshtastic.protobuf.UserLite\x12\x33\n\x08position\x18\x03 \x01(\x0b\x32!.meshtastic.protobuf.PositionLite\x12\x0b\n\x03snr\x18\x04 \x01(\x02\x12\x12\n\nlast_heard\x18\x05 \x01(\x07\x12:\n\x0e\x64\x65vice_metrics\x18\x06 \x01(\x0b\x32\".meshtastic.protobuf.DeviceMetrics\x12\x0f\n\x07\x63hannel\x18\x07 \x01(\r\x12\x10\n\x08via_mqtt\x18\x08 \x01(\x08\x12\x16\n\thops_away\x18\t \x01(\rH\x00\x88\x01\x01\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\x12\x12\n\nis_ignored\x18\x0b \x01(\x08\x12\x10\n\x08next_hop\x18\x0c \x01(\r\x12\x10\n\x08\x62itfield\x18\r \x01(\rB\x0c\n\n_hops_away\"\xa1\x03\n\x0b\x44\x65viceState\x12\x30\n\x07my_node\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfo\x12(\n\x05owner\x18\x03 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12\x36\n\rreceive_queue\x18\x05 \x03(\x0b\x32\x1f.meshtastic.protobuf.MeshPacket\x12\x0f\n\x07version\x18\x08 \x01(\r\x12\x38\n\x0frx_text_message\x18\x07 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacket\x12\x13\n\x07no_save\x18\t \x01(\x08\x42\x02\x18\x01\x12\x19\n\rdid_gps_reset\x18\x0b \x01(\x08\x42\x02\x18\x01\x12\x34\n\x0brx_waypoint\x18\x0c \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacket\x12M\n\x19node_remote_hardware_pins\x18\r \x03(\x0b\x32*.meshtastic.protobuf.NodeRemoteHardwarePin\"}\n\x0cNodeDatabase\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\\\n\x05nodes\x18\x02 \x03(\x0b\x32!.meshtastic.protobuf.NodeInfoLiteB*\x92?\'\x92\x01$std::vector\"N\n\x0b\x43hannelFile\x12.\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x1c.meshtastic.protobuf.Channel\x12\x0f\n\x07version\x18\x02 \x01(\r\"\x86\x02\n\x11\x42\x61\x63kupPreferences\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\x11\n\ttimestamp\x18\x02 \x01(\x07\x12\x30\n\x06\x63onfig\x18\x03 \x01(\x0b\x32 .meshtastic.protobuf.LocalConfig\x12=\n\rmodule_config\x18\x04 \x01(\x0b\x32&.meshtastic.protobuf.LocalModuleConfig\x12\x32\n\x08\x63hannels\x18\x05 \x01(\x0b\x32 .meshtastic.protobuf.ChannelFile\x12(\n\x05owner\x18\x06 \x01(\x0b\x32\x19.meshtastic.protobuf.UserBn\n\x14org.meshtastic.protoB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x92?\x0b\xc2\x01\x08b\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$meshtastic/protobuf/deviceonly.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a#meshtastic/protobuf/localonly.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/nanopb.proto\"\x99\x01\n\x0cPositionLite\x12\x12\n\nlatitude_i\x18\x01 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x02 \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x03 \x01(\x05\x12\x0c\n\x04time\x18\x04 \x01(\x07\x12@\n\x0flocation_source\x18\x05 \x01(\x0e\x32\'.meshtastic.protobuf.Position.LocSource\"\xb0\x02\n\x08UserLite\x12\x1a\n\x07macaddr\x18\x01 \x01(\x0c\x42\t\x18\x01\x92?\x04\x08\x06x\x01\x12\x18\n\tlong_name\x18\x02 \x01(\tB\x05\x92?\x02\x08(\x12\x19\n\nshort_name\x18\x03 \x01(\tB\x05\x92?\x02\x08\x05\x12\x34\n\x08hw_model\x18\x04 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x05 \x01(\x08\x12;\n\x04role\x18\x06 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x19\n\npublic_key\x18\x07 \x01(\x0c\x42\x05\x92?\x02\x08 \x12\x1c\n\x0fis_unmessagable\x18\t \x01(\x08H\x00\x88\x01\x01\x42\x12\n\x10_is_unmessagable\"\x85\x03\n\x0cNodeInfoLite\x12\x0b\n\x03num\x18\x01 \x01(\r\x12+\n\x04user\x18\x02 \x01(\x0b\x32\x1d.meshtastic.protobuf.UserLite\x12\x33\n\x08position\x18\x03 \x01(\x0b\x32!.meshtastic.protobuf.PositionLite\x12\x0b\n\x03snr\x18\x04 \x01(\x02\x12\x12\n\nlast_heard\x18\x05 \x01(\x07\x12:\n\x0e\x64\x65vice_metrics\x18\x06 \x01(\x0b\x32\".meshtastic.protobuf.DeviceMetrics\x12\x16\n\x07\x63hannel\x18\x07 \x01(\rB\x05\x92?\x02\x38\x08\x12\x10\n\x08via_mqtt\x18\x08 \x01(\x08\x12\x1d\n\thops_away\x18\t \x01(\rB\x05\x92?\x02\x38\x08H\x00\x88\x01\x01\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\x12\x12\n\nis_ignored\x18\x0b \x01(\x08\x12\x17\n\x08next_hop\x18\x0c \x01(\rB\x05\x92?\x02\x38\x08\x12\x10\n\x08\x62itfield\x18\r \x01(\rB\x0c\n\n_hops_away\"\xaf\x03\n\x0b\x44\x65viceState\x12\x30\n\x07my_node\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfo\x12(\n\x05owner\x18\x03 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12=\n\rreceive_queue\x18\x05 \x03(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketB\x05\x92?\x02\x10\x01\x12\x0f\n\x07version\x18\x08 \x01(\r\x12\x38\n\x0frx_text_message\x18\x07 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacket\x12\x13\n\x07no_save\x18\t \x01(\x08\x42\x02\x18\x01\x12\x19\n\rdid_gps_reset\x18\x0b \x01(\x08\x42\x02\x18\x01\x12\x34\n\x0brx_waypoint\x18\x0c \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacket\x12T\n\x19node_remote_hardware_pins\x18\r \x03(\x0b\x32*.meshtastic.protobuf.NodeRemoteHardwarePinB\x05\x92?\x02\x10\x0c\"}\n\x0cNodeDatabase\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\\\n\x05nodes\x18\x02 \x03(\x0b\x32!.meshtastic.protobuf.NodeInfoLiteB*\x92?\'\x92\x01$std::vector\"U\n\x0b\x43hannelFile\x12\x35\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x1c.meshtastic.protobuf.ChannelB\x05\x92?\x02\x10\x08\x12\x0f\n\x07version\x18\x02 \x01(\r\"\x86\x02\n\x11\x42\x61\x63kupPreferences\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\x11\n\ttimestamp\x18\x02 \x01(\x07\x12\x30\n\x06\x63onfig\x18\x03 \x01(\x0b\x32 .meshtastic.protobuf.LocalConfig\x12=\n\rmodule_config\x18\x04 \x01(\x0b\x32&.meshtastic.protobuf.LocalModuleConfig\x12\x32\n\x08\x63hannels\x18\x05 \x01(\x0b\x32 .meshtastic.protobuf.ChannelFile\x12(\n\x05owner\x18\x06 \x01(\x0b\x32\x19.meshtastic.protobuf.UserBn\n\x14org.meshtastic.protoB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x92?\x0b\xc2\x01\x08b\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -28,25 +28,43 @@ if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000\222?\013\302\001\010' _USERLITE.fields_by_name['macaddr']._options = None - _USERLITE.fields_by_name['macaddr']._serialized_options = b'\030\001' + _USERLITE.fields_by_name['macaddr']._serialized_options = b'\030\001\222?\004\010\006x\001' + _USERLITE.fields_by_name['long_name']._options = None + _USERLITE.fields_by_name['long_name']._serialized_options = b'\222?\002\010(' + _USERLITE.fields_by_name['short_name']._options = None + _USERLITE.fields_by_name['short_name']._serialized_options = b'\222?\002\010\005' + _USERLITE.fields_by_name['public_key']._options = None + _USERLITE.fields_by_name['public_key']._serialized_options = b'\222?\002\010 ' + _NODEINFOLITE.fields_by_name['channel']._options = None + _NODEINFOLITE.fields_by_name['channel']._serialized_options = b'\222?\0028\010' + _NODEINFOLITE.fields_by_name['hops_away']._options = None + _NODEINFOLITE.fields_by_name['hops_away']._serialized_options = b'\222?\0028\010' + _NODEINFOLITE.fields_by_name['next_hop']._options = None + _NODEINFOLITE.fields_by_name['next_hop']._serialized_options = b'\222?\0028\010' + _DEVICESTATE.fields_by_name['receive_queue']._options = None + _DEVICESTATE.fields_by_name['receive_queue']._serialized_options = b'\222?\002\020\001' _DEVICESTATE.fields_by_name['no_save']._options = None _DEVICESTATE.fields_by_name['no_save']._serialized_options = b'\030\001' _DEVICESTATE.fields_by_name['did_gps_reset']._options = None _DEVICESTATE.fields_by_name['did_gps_reset']._serialized_options = b'\030\001' + _DEVICESTATE.fields_by_name['node_remote_hardware_pins']._options = None + _DEVICESTATE.fields_by_name['node_remote_hardware_pins']._serialized_options = b'\222?\002\020\014' _NODEDATABASE.fields_by_name['nodes']._options = None _NODEDATABASE.fields_by_name['nodes']._serialized_options = b'\222?\'\222\001$std::vector' + _CHANNELFILE.fields_by_name['channels']._options = None + _CHANNELFILE.fields_by_name['channels']._serialized_options = b'\222?\002\020\010' _globals['_POSITIONLITE']._serialized_start=271 _globals['_POSITIONLITE']._serialized_end=424 _globals['_USERLITE']._serialized_start=427 - _globals['_USERLITE']._serialized_end=703 - _globals['_NODEINFOLITE']._serialized_start=706 - _globals['_NODEINFOLITE']._serialized_end=1074 - _globals['_DEVICESTATE']._serialized_start=1077 - _globals['_DEVICESTATE']._serialized_end=1494 - _globals['_NODEDATABASE']._serialized_start=1496 - _globals['_NODEDATABASE']._serialized_end=1621 - _globals['_CHANNELFILE']._serialized_start=1623 - _globals['_CHANNELFILE']._serialized_end=1701 - _globals['_BACKUPPREFERENCES']._serialized_start=1704 - _globals['_BACKUPPREFERENCES']._serialized_end=1966 + _globals['_USERLITE']._serialized_end=731 + _globals['_NODEINFOLITE']._serialized_start=734 + _globals['_NODEINFOLITE']._serialized_end=1123 + _globals['_DEVICESTATE']._serialized_start=1126 + _globals['_DEVICESTATE']._serialized_end=1557 + _globals['_NODEDATABASE']._serialized_start=1559 + _globals['_NODEDATABASE']._serialized_end=1684 + _globals['_CHANNELFILE']._serialized_start=1686 + _globals['_CHANNELFILE']._serialized_end=1771 + _globals['_BACKUPPREFERENCES']._serialized_start=1774 + _globals['_BACKUPPREFERENCES']._serialized_end=2036 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/interdevice_pb2.py b/meshtastic/protobuf/interdevice_pb2.py index dda2ad6..07b05e2 100644 --- a/meshtastic/protobuf/interdevice_pb2.py +++ b/meshtastic/protobuf/interdevice_pb2.py @@ -11,9 +11,10 @@ from google.protobuf.internal import builder as _builder _sym_db = _symbol_database.Default() +from meshtastic.protobuf import nanopb_pb2 as meshtastic_dot_protobuf_dot_nanopb__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n%meshtastic/protobuf/interdevice.proto\x12\x13meshtastic.protobuf\"s\n\nSensorData\x12.\n\x04type\x18\x01 \x01(\x0e\x32 .meshtastic.protobuf.MessageType\x12\x15\n\x0b\x66loat_value\x18\x02 \x01(\x02H\x00\x12\x16\n\x0cuint32_value\x18\x03 \x01(\rH\x00\x42\x06\n\x04\x64\x61ta\"_\n\x12InterdeviceMessage\x12\x0e\n\x04nmea\x18\x01 \x01(\tH\x00\x12\x31\n\x06sensor\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.SensorDataH\x00\x42\x06\n\x04\x64\x61ta*\xd5\x01\n\x0bMessageType\x12\x07\n\x03\x41\x43K\x10\x00\x12\x15\n\x10\x43OLLECT_INTERVAL\x10\xa0\x01\x12\x0c\n\x07\x42\x45\x45P_ON\x10\xa1\x01\x12\r\n\x08\x42\x45\x45P_OFF\x10\xa2\x01\x12\r\n\x08SHUTDOWN\x10\xa3\x01\x12\r\n\x08POWER_ON\x10\xa4\x01\x12\x0f\n\nSCD41_TEMP\x10\xb0\x01\x12\x13\n\x0eSCD41_HUMIDITY\x10\xb1\x01\x12\x0e\n\tSCD41_CO2\x10\xb2\x01\x12\x0f\n\nAHT20_TEMP\x10\xb3\x01\x12\x13\n\x0e\x41HT20_HUMIDITY\x10\xb4\x01\x12\x0f\n\nTVOC_INDEX\x10\xb5\x01\x42g\n\x14org.meshtastic.protoB\x11InterdeviceProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n%meshtastic/protobuf/interdevice.proto\x12\x13meshtastic.protobuf\x1a meshtastic/protobuf/nanopb.proto\"s\n\nSensorData\x12.\n\x04type\x18\x01 \x01(\x0e\x32 .meshtastic.protobuf.MessageType\x12\x15\n\x0b\x66loat_value\x18\x02 \x01(\x02H\x00\x12\x16\n\x0cuint32_value\x18\x03 \x01(\rH\x00\x42\x06\n\x04\x64\x61ta\"g\n\x12InterdeviceMessage\x12\x16\n\x04nmea\x18\x01 \x01(\tB\x06\x92?\x03\x08\x80\x08H\x00\x12\x31\n\x06sensor\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.SensorDataH\x00\x42\x06\n\x04\x64\x61ta*\xd5\x01\n\x0bMessageType\x12\x07\n\x03\x41\x43K\x10\x00\x12\x15\n\x10\x43OLLECT_INTERVAL\x10\xa0\x01\x12\x0c\n\x07\x42\x45\x45P_ON\x10\xa1\x01\x12\r\n\x08\x42\x45\x45P_OFF\x10\xa2\x01\x12\r\n\x08SHUTDOWN\x10\xa3\x01\x12\r\n\x08POWER_ON\x10\xa4\x01\x12\x0f\n\nSCD41_TEMP\x10\xb0\x01\x12\x13\n\x0eSCD41_HUMIDITY\x10\xb1\x01\x12\x0e\n\tSCD41_CO2\x10\xb2\x01\x12\x0f\n\nAHT20_TEMP\x10\xb3\x01\x12\x13\n\x0e\x41HT20_HUMIDITY\x10\xb4\x01\x12\x0f\n\nTVOC_INDEX\x10\xb5\x01\x42g\n\x14org.meshtastic.protoB\x11InterdeviceProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -21,10 +22,12 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.interde if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\021InterdeviceProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _globals['_MESSAGETYPE']._serialized_start=277 - _globals['_MESSAGETYPE']._serialized_end=490 - _globals['_SENSORDATA']._serialized_start=62 - _globals['_SENSORDATA']._serialized_end=177 - _globals['_INTERDEVICEMESSAGE']._serialized_start=179 - _globals['_INTERDEVICEMESSAGE']._serialized_end=274 + _INTERDEVICEMESSAGE.fields_by_name['nmea']._options = None + _INTERDEVICEMESSAGE.fields_by_name['nmea']._serialized_options = b'\222?\003\010\200\010' + _globals['_MESSAGETYPE']._serialized_start=319 + _globals['_MESSAGETYPE']._serialized_end=532 + _globals['_SENSORDATA']._serialized_start=96 + _globals['_SENSORDATA']._serialized_end=211 + _globals['_INTERDEVICEMESSAGE']._serialized_start=213 + _globals['_INTERDEVICEMESSAGE']._serialized_end=316 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/localonly_pb2.py b/meshtastic/protobuf/localonly_pb2.py index 70d7183..b9bb269 100644 --- a/meshtastic/protobuf/localonly_pb2.py +++ b/meshtastic/protobuf/localonly_pb2.py @@ -15,7 +15,7 @@ from meshtastic.protobuf import config_pb2 as meshtastic_dot_protobuf_dot_config from meshtastic.protobuf import module_config_pb2 as meshtastic_dot_protobuf_dot_module__config__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/localonly.proto\x12\x13meshtastic.protobuf\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\"\xfa\x03\n\x0bLocalConfig\x12\x38\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfig\x12<\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfig\x12\x36\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfig\x12:\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfig\x12:\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfig\x12\x34\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfig\x12>\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfig\x12\x0f\n\x07version\x18\x08 \x01(\r\x12<\n\x08security\x18\t \x01(\x0b\x32*.meshtastic.protobuf.Config.SecurityConfig\"\xbe\x08\n\x11LocalModuleConfig\x12:\n\x04mqtt\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.ModuleConfig.MQTTConfig\x12>\n\x06serial\x18\x02 \x01(\x0b\x32..meshtastic.protobuf.ModuleConfig.SerialConfig\x12[\n\x15\x65xternal_notification\x18\x03 \x01(\x0b\x32<.meshtastic.protobuf.ModuleConfig.ExternalNotificationConfig\x12K\n\rstore_forward\x18\x04 \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.StoreForwardConfig\x12\x45\n\nrange_test\x18\x05 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.RangeTestConfig\x12\x44\n\ttelemetry\x18\x06 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.TelemetryConfig\x12M\n\x0e\x63\x61nned_message\x18\x07 \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.CannedMessageConfig\x12<\n\x05\x61udio\x18\t \x01(\x0b\x32-.meshtastic.protobuf.ModuleConfig.AudioConfig\x12O\n\x0fremote_hardware\x18\n \x01(\x0b\x32\x36.meshtastic.protobuf.ModuleConfig.RemoteHardwareConfig\x12K\n\rneighbor_info\x18\x0b \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.NeighborInfoConfig\x12Q\n\x10\x61mbient_lighting\x18\x0c \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.AmbientLightingConfig\x12Q\n\x10\x64\x65tection_sensor\x18\r \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.DetectionSensorConfig\x12\x46\n\npaxcounter\x18\x0e \x01(\x0b\x32\x32.meshtastic.protobuf.ModuleConfig.PaxcounterConfig\x12L\n\rstatusmessage\x18\x0f \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.StatusMessageConfig\x12\x0f\n\x07version\x18\x08 \x01(\rBe\n\x14org.meshtastic.protoB\x0fLocalOnlyProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/localonly.proto\x12\x13meshtastic.protobuf\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\"\xfa\x03\n\x0bLocalConfig\x12\x38\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfig\x12<\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfig\x12\x36\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfig\x12:\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfig\x12:\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfig\x12\x34\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfig\x12>\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfig\x12\x0f\n\x07version\x18\x08 \x01(\r\x12<\n\x08security\x18\t \x01(\x0b\x32*.meshtastic.protobuf.Config.SecurityConfig\"\xcf\t\n\x11LocalModuleConfig\x12:\n\x04mqtt\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.ModuleConfig.MQTTConfig\x12>\n\x06serial\x18\x02 \x01(\x0b\x32..meshtastic.protobuf.ModuleConfig.SerialConfig\x12[\n\x15\x65xternal_notification\x18\x03 \x01(\x0b\x32<.meshtastic.protobuf.ModuleConfig.ExternalNotificationConfig\x12K\n\rstore_forward\x18\x04 \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.StoreForwardConfig\x12\x45\n\nrange_test\x18\x05 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.RangeTestConfig\x12\x44\n\ttelemetry\x18\x06 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.TelemetryConfig\x12M\n\x0e\x63\x61nned_message\x18\x07 \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.CannedMessageConfig\x12<\n\x05\x61udio\x18\t \x01(\x0b\x32-.meshtastic.protobuf.ModuleConfig.AudioConfig\x12O\n\x0fremote_hardware\x18\n \x01(\x0b\x32\x36.meshtastic.protobuf.ModuleConfig.RemoteHardwareConfig\x12K\n\rneighbor_info\x18\x0b \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.NeighborInfoConfig\x12Q\n\x10\x61mbient_lighting\x18\x0c \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.AmbientLightingConfig\x12Q\n\x10\x64\x65tection_sensor\x18\r \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.DetectionSensorConfig\x12\x46\n\npaxcounter\x18\x0e \x01(\x0b\x32\x32.meshtastic.protobuf.ModuleConfig.PaxcounterConfig\x12L\n\rstatusmessage\x18\x0f \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.StatusMessageConfig\x12U\n\x12traffic_management\x18\x10 \x01(\x0b\x32\x39.meshtastic.protobuf.ModuleConfig.TrafficManagementConfig\x12\x38\n\x03tak\x18\x11 \x01(\x0b\x32+.meshtastic.protobuf.ModuleConfig.TAKConfig\x12\x0f\n\x07version\x18\x08 \x01(\rBe\n\x14org.meshtastic.protoB\x0fLocalOnlyProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -26,5 +26,5 @@ if _descriptor._USE_C_DESCRIPTORS == False: _globals['_LOCALCONFIG']._serialized_start=136 _globals['_LOCALCONFIG']._serialized_end=642 _globals['_LOCALMODULECONFIG']._serialized_start=645 - _globals['_LOCALMODULECONFIG']._serialized_end=1731 + _globals['_LOCALMODULECONFIG']._serialized_end=1876 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/localonly_pb2.pyi b/meshtastic/protobuf/localonly_pb2.pyi index 8ed7cae..b5284ac 100644 --- a/meshtastic/protobuf/localonly_pb2.pyi +++ b/meshtastic/protobuf/localonly_pb2.pyi @@ -120,6 +120,8 @@ class LocalModuleConfig(google.protobuf.message.Message): DETECTION_SENSOR_FIELD_NUMBER: builtins.int PAXCOUNTER_FIELD_NUMBER: builtins.int STATUSMESSAGE_FIELD_NUMBER: builtins.int + TRAFFIC_MANAGEMENT_FIELD_NUMBER: builtins.int + TAK_FIELD_NUMBER: builtins.int VERSION_FIELD_NUMBER: builtins.int version: builtins.int """ @@ -211,6 +213,18 @@ class LocalModuleConfig(google.protobuf.message.Message): StatusMessage Config """ + @property + def traffic_management(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.TrafficManagementConfig: + """ + The part of the config that is specific to the Traffic Management module + """ + + @property + def tak(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.TAKConfig: + """ + TAK Config + """ + def __init__( self, *, @@ -228,9 +242,11 @@ class LocalModuleConfig(google.protobuf.message.Message): detection_sensor: meshtastic.protobuf.module_config_pb2.ModuleConfig.DetectionSensorConfig | None = ..., paxcounter: meshtastic.protobuf.module_config_pb2.ModuleConfig.PaxcounterConfig | None = ..., statusmessage: meshtastic.protobuf.module_config_pb2.ModuleConfig.StatusMessageConfig | None = ..., + traffic_management: meshtastic.protobuf.module_config_pb2.ModuleConfig.TrafficManagementConfig | None = ..., + tak: meshtastic.protobuf.module_config_pb2.ModuleConfig.TAKConfig | None = ..., version: builtins.int = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["ambient_lighting", b"ambient_lighting", "audio", b"audio", "canned_message", b"canned_message", "detection_sensor", b"detection_sensor", "external_notification", b"external_notification", "mqtt", b"mqtt", "neighbor_info", b"neighbor_info", "paxcounter", b"paxcounter", "range_test", b"range_test", "remote_hardware", b"remote_hardware", "serial", b"serial", "statusmessage", b"statusmessage", "store_forward", b"store_forward", "telemetry", b"telemetry"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["ambient_lighting", b"ambient_lighting", "audio", b"audio", "canned_message", b"canned_message", "detection_sensor", b"detection_sensor", "external_notification", b"external_notification", "mqtt", b"mqtt", "neighbor_info", b"neighbor_info", "paxcounter", b"paxcounter", "range_test", b"range_test", "remote_hardware", b"remote_hardware", "serial", b"serial", "statusmessage", b"statusmessage", "store_forward", b"store_forward", "telemetry", b"telemetry", "version", b"version"]) -> None: ... + def HasField(self, field_name: typing.Literal["ambient_lighting", b"ambient_lighting", "audio", b"audio", "canned_message", b"canned_message", "detection_sensor", b"detection_sensor", "external_notification", b"external_notification", "mqtt", b"mqtt", "neighbor_info", b"neighbor_info", "paxcounter", b"paxcounter", "range_test", b"range_test", "remote_hardware", b"remote_hardware", "serial", b"serial", "statusmessage", b"statusmessage", "store_forward", b"store_forward", "tak", b"tak", "telemetry", b"telemetry", "traffic_management", b"traffic_management"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["ambient_lighting", b"ambient_lighting", "audio", b"audio", "canned_message", b"canned_message", "detection_sensor", b"detection_sensor", "external_notification", b"external_notification", "mqtt", b"mqtt", "neighbor_info", b"neighbor_info", "paxcounter", b"paxcounter", "range_test", b"range_test", "remote_hardware", b"remote_hardware", "serial", b"serial", "statusmessage", b"statusmessage", "store_forward", b"store_forward", "tak", b"tak", "telemetry", b"telemetry", "traffic_management", b"traffic_management", "version", b"version"]) -> None: ... global___LocalModuleConfig = LocalModuleConfig diff --git a/meshtastic/protobuf/mesh_pb2.py b/meshtastic/protobuf/mesh_pb2.py index 31c3d63..ef13bd9 100644 --- a/meshtastic/protobuf/mesh_pb2.py +++ b/meshtastic/protobuf/mesh_pb2.py @@ -18,9 +18,10 @@ from meshtastic.protobuf import module_config_pb2 as meshtastic_dot_protobuf_dot from meshtastic.protobuf import portnums_pb2 as meshtastic_dot_protobuf_dot_portnums__pb2 from meshtastic.protobuf import telemetry_pb2 as meshtastic_dot_protobuf_dot_telemetry__pb2 from meshtastic.protobuf import xmodem_pb2 as meshtastic_dot_protobuf_dot_xmodem__pb2 +from meshtastic.protobuf import nanopb_pb2 as meshtastic_dot_protobuf_dot_nanopb__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mesh.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a#meshtastic/protobuf/device_ui.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a\"meshtastic/protobuf/portnums.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/xmodem.proto\"\x99\x07\n\x08Position\x12\x17\n\nlatitude_i\x18\x01 \x01(\x0fH\x00\x88\x01\x01\x12\x18\n\x0blongitude_i\x18\x02 \x01(\x0fH\x01\x88\x01\x01\x12\x15\n\x08\x61ltitude\x18\x03 \x01(\x05H\x02\x88\x01\x01\x12\x0c\n\x04time\x18\x04 \x01(\x07\x12@\n\x0flocation_source\x18\x05 \x01(\x0e\x32\'.meshtastic.protobuf.Position.LocSource\x12@\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\'.meshtastic.protobuf.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x19\n\x0c\x61ltitude_hae\x18\t \x01(\x11H\x03\x88\x01\x01\x12(\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11H\x04\x88\x01\x01\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x19\n\x0cground_speed\x18\x0f \x01(\rH\x05\x88\x01\x01\x12\x19\n\x0cground_track\x18\x10 \x01(\rH\x06\x88\x01\x01\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\x42\r\n\x0b_latitude_iB\x0e\n\x0c_longitude_iB\x0b\n\t_altitudeB\x0f\n\r_altitude_haeB\x1e\n\x1c_altitude_geoidal_separationB\x0f\n\r_ground_speedB\x0f\n\r_ground_track\"\x9c\x02\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x13\n\x07macaddr\x18\x04 \x01(\x0c\x42\x02\x18\x01\x12\x34\n\x08hw_model\x18\x05 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x12\n\npublic_key\x18\x08 \x01(\x0c\x12\x1c\n\x0fis_unmessagable\x18\t \x01(\x08H\x00\x88\x01\x01\x42\x12\n\x10_is_unmessagable\"Z\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x01 \x03(\x07\x12\x13\n\x0bsnr_towards\x18\x02 \x03(\x05\x12\x12\n\nroute_back\x18\x03 \x03(\x07\x12\x10\n\x08snr_back\x18\x04 \x03(\x05\"\xb4\x04\n\x07Routing\x12<\n\rroute_request\x18\x01 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0broute_reply\x18\x02 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\".meshtastic.protobuf.Routing.ErrorH\x00\"\xe7\x02\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!\x12\x0e\n\nPKI_FAILED\x10\"\x12\x16\n\x12PKI_UNKNOWN_PUBKEY\x10#\x12\x19\n\x15\x41\x44MIN_BAD_SESSION_KEY\x10$\x12!\n\x1d\x41\x44MIN_PUBLIC_KEY_UNAUTHORIZED\x10%\x12\x17\n\x13RATE_LIMIT_EXCEEDED\x10&\x12\x1c\n\x18PKI_SEND_FAIL_PUBLIC_KEY\x10\'B\t\n\x07variant\"\xd4\x01\n\x04\x44\x61ta\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\x12\x15\n\x08\x62itfield\x18\t \x01(\rH\x00\x88\x01\x01\x42\x0b\n\t_bitfield\">\n\x0fKeyVerification\x12\r\n\x05nonce\x18\x01 \x01(\x04\x12\r\n\x05hash1\x18\x02 \x01(\x0c\x12\r\n\x05hash2\x18\x03 \x01(\x0c\"\xd4\x03\n\x14StoreForwardPlusPlus\x12V\n\x11sfpp_message_type\x18\x01 \x01(\x0e\x32;.meshtastic.protobuf.StoreForwardPlusPlus.SFPP_message_type\x12\x14\n\x0cmessage_hash\x18\x02 \x01(\x0c\x12\x13\n\x0b\x63ommit_hash\x18\x03 \x01(\x0c\x12\x11\n\troot_hash\x18\x04 \x01(\x0c\x12\x0f\n\x07message\x18\x05 \x01(\x0c\x12\x17\n\x0f\x65ncapsulated_id\x18\x06 \x01(\r\x12\x17\n\x0f\x65ncapsulated_to\x18\x07 \x01(\r\x12\x19\n\x11\x65ncapsulated_from\x18\x08 \x01(\r\x12\x1b\n\x13\x65ncapsulated_rxtime\x18\t \x01(\r\x12\x13\n\x0b\x63hain_count\x18\n \x01(\r\"\x95\x01\n\x11SFPP_message_type\x12\x12\n\x0e\x43\x41NON_ANNOUNCE\x10\x00\x12\x0f\n\x0b\x43HAIN_QUERY\x10\x01\x12\x10\n\x0cLINK_REQUEST\x10\x03\x12\x10\n\x0cLINK_PROVIDE\x10\x04\x12\x1a\n\x16LINK_PROVIDE_FIRSTHALF\x10\x05\x12\x1b\n\x17LINK_PROVIDE_SECONDHALF\x10\x06\"\xbc\x01\n\x08Waypoint\x12\n\n\x02id\x18\x01 \x01(\r\x12\x17\n\nlatitude_i\x18\x02 \x01(\x0fH\x00\x88\x01\x01\x12\x18\n\x0blongitude_i\x18\x03 \x01(\x0fH\x01\x88\x01\x01\x12\x0e\n\x06\x65xpire\x18\x04 \x01(\r\x12\x11\n\tlocked_to\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x07 \x01(\t\x12\x0c\n\x04icon\x18\x08 \x01(\x07\x42\r\n\x0b_latitude_iB\x0e\n\x0c_longitude_i\"\x1f\n\rStatusMessage\x12\x0e\n\x06status\x18\x01 \x01(\t\"l\n\x16MqttClientProxyMessage\x12\r\n\x05topic\x18\x01 \x01(\t\x12\x0e\n\x04\x64\x61ta\x18\x02 \x01(\x0cH\x00\x12\x0e\n\x04text\x18\x03 \x01(\tH\x00\x12\x10\n\x08retained\x18\x04 \x01(\x08\x42\x11\n\x0fpayload_variant\"\xd9\x07\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\r\x12,\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.DataH\x00\x12\x13\n\tencrypted\x18\x05 \x01(\x0cH\x00\x12\n\n\x02id\x18\x06 \x01(\x07\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x11\n\thop_limit\x18\t \x01(\r\x12\x10\n\x08want_ack\x18\n \x01(\x08\x12:\n\x08priority\x18\x0b \x01(\x0e\x32(.meshtastic.protobuf.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\x0c \x01(\x05\x12<\n\x07\x64\x65layed\x18\r \x01(\x0e\x32\'.meshtastic.protobuf.MeshPacket.DelayedB\x02\x18\x01\x12\x10\n\x08via_mqtt\x18\x0e \x01(\x08\x12\x11\n\thop_start\x18\x0f \x01(\r\x12\x12\n\npublic_key\x18\x10 \x01(\x0c\x12\x15\n\rpki_encrypted\x18\x11 \x01(\x08\x12\x10\n\x08next_hop\x18\x12 \x01(\r\x12\x12\n\nrelay_node\x18\x13 \x01(\r\x12\x10\n\x08tx_after\x18\x14 \x01(\r\x12O\n\x13transport_mechanism\x18\x15 \x01(\x0e\x32\x32.meshtastic.protobuf.MeshPacket.TransportMechanism\"~\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x0c\n\x08RESPONSE\x10P\x12\x08\n\x04HIGH\x10\x64\x12\t\n\x05\x41LERT\x10n\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\"B\n\x07\x44\x65layed\x12\x0c\n\x08NO_DELAY\x10\x00\x12\x15\n\x11\x44\x45LAYED_BROADCAST\x10\x01\x12\x12\n\x0e\x44\x45LAYED_DIRECT\x10\x02\"\xcf\x01\n\x12TransportMechanism\x12\x16\n\x12TRANSPORT_INTERNAL\x10\x00\x12\x12\n\x0eTRANSPORT_LORA\x10\x01\x12\x17\n\x13TRANSPORT_LORA_ALT1\x10\x02\x12\x17\n\x13TRANSPORT_LORA_ALT2\x10\x03\x12\x17\n\x13TRANSPORT_LORA_ALT3\x10\x04\x12\x12\n\x0eTRANSPORT_MQTT\x10\x05\x12\x1b\n\x17TRANSPORT_MULTICAST_UDP\x10\x06\x12\x11\n\rTRANSPORT_API\x10\x07\x42\x11\n\x0fpayload_variant\"\xf4\x02\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12/\n\x08position\x18\x03 \x01(\x0b\x32\x1d.meshtastic.protobuf.Position\x12\x0b\n\x03snr\x18\x04 \x01(\x02\x12\x12\n\nlast_heard\x18\x05 \x01(\x07\x12:\n\x0e\x64\x65vice_metrics\x18\x06 \x01(\x0b\x32\".meshtastic.protobuf.DeviceMetrics\x12\x0f\n\x07\x63hannel\x18\x07 \x01(\r\x12\x10\n\x08via_mqtt\x18\x08 \x01(\x08\x12\x16\n\thops_away\x18\t \x01(\rH\x00\x88\x01\x01\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\x12\x12\n\nis_ignored\x18\x0b \x01(\x08\x12 \n\x18is_key_manually_verified\x18\x0c \x01(\x08\x12\x10\n\x08is_muted\x18\r \x01(\x08\x42\x0c\n\n_hops_away\"\xca\x01\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x14\n\x0creboot_count\x18\x08 \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0b \x01(\r\x12\x11\n\tdevice_id\x18\x0c \x01(\x0c\x12\x0f\n\x07pio_env\x18\r \x01(\t\x12>\n\x10\x66irmware_edition\x18\x0e \x01(\x0e\x32$.meshtastic.protobuf.FirmwareEdition\x12\x14\n\x0cnodedb_count\x18\x0f \x01(\r\"\xc9\x01\n\tLogRecord\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x0e\n\x06source\x18\x03 \x01(\t\x12\x33\n\x05level\x18\x04 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"P\n\x0bQueueStatus\x12\x0b\n\x03res\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ree\x18\x02 \x01(\r\x12\x0e\n\x06maxlen\x18\x03 \x01(\r\x12\x16\n\x0emesh_packet_id\x18\x04 \x01(\r\"\xf7\x06\n\tFromRadio\x12\n\n\x02id\x18\x01 \x01(\r\x12\x31\n\x06packet\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x32\n\x07my_info\x18\x03 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfoH\x00\x12\x32\n\tnode_info\x18\x04 \x01(\x0b\x32\x1d.meshtastic.protobuf.NodeInfoH\x00\x12-\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12\x34\n\nlog_record\x18\x06 \x01(\x0b\x32\x1e.meshtastic.protobuf.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x07 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\x08 \x01(\x08H\x00\x12\x39\n\x0cmoduleConfig\x18\t \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12/\n\x07\x63hannel\x18\n \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x37\n\x0bqueueStatus\x18\x0b \x01(\x0b\x32 .meshtastic.protobuf.QueueStatusH\x00\x12\x33\n\x0cxmodemPacket\x18\x0c \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12\x37\n\x08metadata\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12M\n\x16mqttClientProxyMessage\x18\x0e \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x31\n\x08\x66ileInfo\x18\x0f \x01(\x0b\x32\x1d.meshtastic.protobuf.FileInfoH\x00\x12\x45\n\x12\x63lientNotification\x18\x10 \x01(\x0b\x32\'.meshtastic.protobuf.ClientNotificationH\x00\x12=\n\x0e\x64\x65viceuiConfig\x18\x11 \x01(\x0b\x32#.meshtastic.protobuf.DeviceUIConfigH\x00\x42\x11\n\x0fpayload_variant\"\xb0\x04\n\x12\x43lientNotification\x12\x15\n\x08reply_id\x18\x01 \x01(\rH\x01\x88\x01\x01\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x33\n\x05level\x18\x03 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\x12\x0f\n\x07message\x18\x04 \x01(\t\x12Z\n\x1ekey_verification_number_inform\x18\x0b \x01(\x0b\x32\x30.meshtastic.protobuf.KeyVerificationNumberInformH\x00\x12\\\n\x1fkey_verification_number_request\x18\x0c \x01(\x0b\x32\x31.meshtastic.protobuf.KeyVerificationNumberRequestH\x00\x12K\n\x16key_verification_final\x18\r \x01(\x0b\x32).meshtastic.protobuf.KeyVerificationFinalH\x00\x12I\n\x15\x64uplicated_public_key\x18\x0e \x01(\x0b\x32(.meshtastic.protobuf.DuplicatedPublicKeyH\x00\x12=\n\x0flow_entropy_key\x18\x0f \x01(\x0b\x32\".meshtastic.protobuf.LowEntropyKeyH\x00\x42\x11\n\x0fpayload_variantB\x0b\n\t_reply_id\"^\n\x1bKeyVerificationNumberInform\x12\r\n\x05nonce\x18\x01 \x01(\x04\x12\x17\n\x0fremote_longname\x18\x02 \x01(\t\x12\x17\n\x0fsecurity_number\x18\x03 \x01(\r\"F\n\x1cKeyVerificationNumberRequest\x12\r\n\x05nonce\x18\x01 \x01(\x04\x12\x17\n\x0fremote_longname\x18\x02 \x01(\t\"q\n\x14KeyVerificationFinal\x12\r\n\x05nonce\x18\x01 \x01(\x04\x12\x17\n\x0fremote_longname\x18\x02 \x01(\t\x12\x10\n\x08isSender\x18\x03 \x01(\x08\x12\x1f\n\x17verification_characters\x18\x04 \x01(\t\"\x15\n\x13\x44uplicatedPublicKey\"\x0f\n\rLowEntropyKey\"1\n\x08\x46ileInfo\x12\x11\n\tfile_name\x18\x01 \x01(\t\x12\x12\n\nsize_bytes\x18\x02 \x01(\r\"\xb8\x02\n\x07ToRadio\x12\x31\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x03 \x01(\rH\x00\x12\x14\n\ndisconnect\x18\x04 \x01(\x08H\x00\x12\x33\n\x0cxmodemPacket\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12M\n\x16mqttClientProxyMessage\x18\x06 \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x33\n\theartbeat\x18\x07 \x01(\x0b\x32\x1e.meshtastic.protobuf.HeartbeatH\x00\x42\x11\n\x0fpayload_variant\"I\n\nCompressed\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"\x90\x01\n\x0cNeighborInfo\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x17\n\x0flast_sent_by_id\x18\x02 \x01(\r\x12$\n\x1cnode_broadcast_interval_secs\x18\x03 \x01(\r\x12\x30\n\tneighbors\x18\x04 \x03(\x0b\x32\x1d.meshtastic.protobuf.Neighbor\"d\n\x08Neighbor\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x0b\n\x03snr\x18\x02 \x01(\x02\x12\x14\n\x0clast_rx_time\x18\x03 \x01(\x07\x12$\n\x1cnode_broadcast_interval_secs\x18\x04 \x01(\r\"\xe9\x02\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12\x34\n\x08hw_model\x18\t \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x19\n\x11hasRemoteHardware\x18\n \x01(\x08\x12\x0e\n\x06hasPKC\x18\x0b \x01(\x08\x12\x18\n\x10\x65xcluded_modules\x18\x0c \x01(\r\"\x1a\n\tHeartbeat\x12\r\n\x05nonce\x18\x01 \x01(\r\"^\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\x33\n\x03pin\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\"e\n\x0e\x43hunkedPayload\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63hunk_count\x18\x02 \x01(\r\x12\x13\n\x0b\x63hunk_index\x18\x03 \x01(\r\x12\x15\n\rpayload_chunk\x18\x04 \x01(\x0c\"\x1f\n\rresend_chunks\x12\x0e\n\x06\x63hunks\x18\x01 \x03(\r\"\xb3\x01\n\x16\x43hunkedPayloadResponse\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x1a\n\x10request_transfer\x18\x02 \x01(\x08H\x00\x12\x19\n\x0f\x61\x63\x63\x65pt_transfer\x18\x03 \x01(\x08H\x00\x12;\n\rresend_chunks\x18\x04 \x01(\x0b\x32\".meshtastic.protobuf.resend_chunksH\x00\x42\x11\n\x0fpayload_variant*\xc3\x12\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1P6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\x0f\n\x0bHELTEC_V2_0\x10\x05\x12\x0e\n\nTBEAM_V0P7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1P3\x10\x08\x12\x0b\n\x07RAK4631\x10\t\x12\x0f\n\x0bHELTEC_V2_1\x10\n\x12\r\n\tHELTEC_V1\x10\x0b\x12\x18\n\x14LILYGO_TBEAM_S3_CORE\x10\x0c\x12\x0c\n\x08RAK11200\x10\r\x12\x0b\n\x07NANO_G1\x10\x0e\x12\x12\n\x0eTLORA_V2_1_1P8\x10\x0f\x12\x0f\n\x0bTLORA_T3_S3\x10\x10\x12\x14\n\x10NANO_G1_EXPLORER\x10\x11\x12\x11\n\rNANO_G2_ULTRA\x10\x12\x12\r\n\tLORA_TYPE\x10\x13\x12\x0b\n\x07WIPHONE\x10\x14\x12\x0e\n\nWIO_WM1110\x10\x15\x12\x0b\n\x07RAK2560\x10\x16\x12\x13\n\x0fHELTEC_HRU_3601\x10\x17\x12\x1a\n\x16HELTEC_WIRELESS_BRIDGE\x10\x18\x12\x0e\n\nSTATION_G1\x10\x19\x12\x0c\n\x08RAK11310\x10\x1a\x12\x14\n\x10SENSELORA_RP2040\x10\x1b\x12\x10\n\x0cSENSELORA_S3\x10\x1c\x12\r\n\tCANARYONE\x10\x1d\x12\x0f\n\x0bRP2040_LORA\x10\x1e\x12\x0e\n\nSTATION_G2\x10\x1f\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0f\n\x0bT_ECHO_PLUS\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&\x12\n\n\x06\x44IY_V1\x10\'\x12\x15\n\x11NRF52840_PCA10059\x10(\x12\n\n\x06\x44R_DEV\x10)\x12\x0b\n\x07M5STACK\x10*\x12\r\n\tHELTEC_V3\x10+\x12\x11\n\rHELTEC_WSL_V3\x10,\x12\x13\n\x0f\x42\x45TAFPV_2400_TX\x10-\x12\x17\n\x13\x42\x45TAFPV_900_NANO_TX\x10.\x12\x0c\n\x08RPI_PICO\x10/\x12\x1b\n\x17HELTEC_WIRELESS_TRACKER\x10\x30\x12\x19\n\x15HELTEC_WIRELESS_PAPER\x10\x31\x12\n\n\x06T_DECK\x10\x32\x12\x0e\n\nT_WATCH_S3\x10\x33\x12\x11\n\rPICOMPUTER_S3\x10\x34\x12\x0f\n\x0bHELTEC_HT62\x10\x35\x12\x12\n\x0e\x45\x42YTE_ESP32_S3\x10\x36\x12\x11\n\rESP32_S3_PICO\x10\x37\x12\r\n\tCHATTER_2\x10\x38\x12\x1e\n\x1aHELTEC_WIRELESS_PAPER_V1_0\x10\x39\x12 \n\x1cHELTEC_WIRELESS_TRACKER_V1_0\x10:\x12\x0b\n\x07UNPHONE\x10;\x12\x0c\n\x08TD_LORAC\x10<\x12\x13\n\x0f\x43\x44\x45\x42YTE_EORA_S3\x10=\x12\x0f\n\x0bTWC_MESH_V4\x10>\x12\x16\n\x12NRF52_PROMICRO_DIY\x10?\x12\x1f\n\x1bRADIOMASTER_900_BANDIT_NANO\x10@\x12\x1c\n\x18HELTEC_CAPSULE_SENSOR_V3\x10\x41\x12\x1d\n\x19HELTEC_VISION_MASTER_T190\x10\x42\x12\x1d\n\x19HELTEC_VISION_MASTER_E213\x10\x43\x12\x1d\n\x19HELTEC_VISION_MASTER_E290\x10\x44\x12\x19\n\x15HELTEC_MESH_NODE_T114\x10\x45\x12\x16\n\x12SENSECAP_INDICATOR\x10\x46\x12\x13\n\x0fTRACKER_T1000_E\x10G\x12\x0b\n\x07RAK3172\x10H\x12\n\n\x06WIO_E5\x10I\x12\x1a\n\x16RADIOMASTER_900_BANDIT\x10J\x12\x13\n\x0fME25LS01_4Y10TD\x10K\x12\x18\n\x14RP2040_FEATHER_RFM95\x10L\x12\x15\n\x11M5STACK_COREBASIC\x10M\x12\x11\n\rM5STACK_CORE2\x10N\x12\r\n\tRPI_PICO2\x10O\x12\x12\n\x0eM5STACK_CORES3\x10P\x12\x11\n\rSEEED_XIAO_S3\x10Q\x12\x0b\n\x07MS24SF1\x10R\x12\x0c\n\x08TLORA_C6\x10S\x12\x0f\n\x0bWISMESH_TAP\x10T\x12\r\n\tROUTASTIC\x10U\x12\x0c\n\x08MESH_TAB\x10V\x12\x0c\n\x08MESHLINK\x10W\x12\x12\n\x0eXIAO_NRF52_KIT\x10X\x12\x10\n\x0cTHINKNODE_M1\x10Y\x12\x10\n\x0cTHINKNODE_M2\x10Z\x12\x0f\n\x0bT_ETH_ELITE\x10[\x12\x15\n\x11HELTEC_SENSOR_HUB\x10\\\x12\r\n\tMUZI_BASE\x10]\x12\x16\n\x12HELTEC_MESH_POCKET\x10^\x12\x14\n\x10SEEED_SOLAR_NODE\x10_\x12\x18\n\x14NOMADSTAR_METEOR_PRO\x10`\x12\r\n\tCROWPANEL\x10\x61\x12\x0b\n\x07LINK_32\x10\x62\x12\x18\n\x14SEEED_WIO_TRACKER_L1\x10\x63\x12\x1d\n\x19SEEED_WIO_TRACKER_L1_EINK\x10\x64\x12\x0f\n\x0bMUZI_R1_NEO\x10\x65\x12\x0e\n\nT_DECK_PRO\x10\x66\x12\x10\n\x0cT_LORA_PAGER\x10g\x12\x14\n\x10M5STACK_RESERVED\x10h\x12\x0f\n\x0bWISMESH_TAG\x10i\x12\x0b\n\x07RAK3312\x10j\x12\x10\n\x0cTHINKNODE_M5\x10k\x12\x15\n\x11HELTEC_MESH_SOLAR\x10l\x12\x0f\n\x0bT_ECHO_LITE\x10m\x12\r\n\tHELTEC_V4\x10n\x12\x0f\n\x0bM5STACK_C6L\x10o\x12\x19\n\x15M5STACK_CARDPUTER_ADV\x10p\x12\x1e\n\x1aHELTEC_WIRELESS_TRACKER_V2\x10q\x12\x11\n\rT_WATCH_ULTRA\x10r\x12\x10\n\x0cTHINKNODE_M3\x10s\x12\x12\n\x0eWISMESH_TAP_V2\x10t\x12\x0b\n\x07RAK3401\x10u\x12\x0b\n\x07RAK6421\x10v\x12\x10\n\x0cTHINKNODE_M4\x10w\x12\x10\n\x0cTHINKNODE_M6\x10x\x12\x12\n\x0eMESHSTICK_1262\x10y\x12\x10\n\x0cTBEAM_1_WATT\x10z\x12\x14\n\x10T5_S3_EPAPER_PRO\x10{\x12\x0f\n\nPRIVATE_HW\x10\xff\x01*,\n\tConstants\x12\x08\n\x04ZERO\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xe9\x01*\xb4\x02\n\x11\x43riticalErrorCode\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\x0bTX_WATCHDOG\x10\x01\x12\x14\n\x10SLEEP_ENTER_WAIT\x10\x02\x12\x0c\n\x08NO_RADIO\x10\x03\x12\x0f\n\x0bUNSPECIFIED\x10\x04\x12\x15\n\x11UBLOX_UNIT_FAILED\x10\x05\x12\r\n\tNO_AXP192\x10\x06\x12\x19\n\x15INVALID_RADIO_SETTING\x10\x07\x12\x13\n\x0fTRANSMIT_FAILED\x10\x08\x12\x0c\n\x08\x42ROWNOUT\x10\t\x12\x12\n\x0eSX1262_FAILURE\x10\n\x12\x11\n\rRADIO_SPI_BUG\x10\x0b\x12 \n\x1c\x46LASH_CORRUPTION_RECOVERABLE\x10\x0c\x12\"\n\x1e\x46LASH_CORRUPTION_UNRECOVERABLE\x10\r*\x7f\n\x0f\x46irmwareEdition\x12\x0b\n\x07VANILLA\x10\x00\x12\x11\n\rSMART_CITIZEN\x10\x01\x12\x0e\n\nOPEN_SAUCE\x10\x10\x12\n\n\x06\x44\x45\x46\x43ON\x10\x11\x12\x0f\n\x0b\x42URNING_MAN\x10\x12\x12\x0e\n\nHAMVENTION\x10\x13\x12\x0f\n\x0b\x44IY_EDITION\x10\x7f*\x80\x03\n\x0f\x45xcludedModules\x12\x11\n\rEXCLUDED_NONE\x10\x00\x12\x0f\n\x0bMQTT_CONFIG\x10\x01\x12\x11\n\rSERIAL_CONFIG\x10\x02\x12\x13\n\x0f\x45XTNOTIF_CONFIG\x10\x04\x12\x17\n\x13STOREFORWARD_CONFIG\x10\x08\x12\x14\n\x10RANGETEST_CONFIG\x10\x10\x12\x14\n\x10TELEMETRY_CONFIG\x10 \x12\x14\n\x10\x43\x41NNEDMSG_CONFIG\x10@\x12\x11\n\x0c\x41UDIO_CONFIG\x10\x80\x01\x12\x1a\n\x15REMOTEHARDWARE_CONFIG\x10\x80\x02\x12\x18\n\x13NEIGHBORINFO_CONFIG\x10\x80\x04\x12\x1b\n\x16\x41MBIENTLIGHTING_CONFIG\x10\x80\x08\x12\x1b\n\x16\x44\x45TECTIONSENSOR_CONFIG\x10\x80\x10\x12\x16\n\x11PAXCOUNTER_CONFIG\x10\x80 \x12\x15\n\x10\x42LUETOOTH_CONFIG\x10\x80@\x12\x14\n\x0eNETWORK_CONFIG\x10\x80\x80\x01\x42`\n\x14org.meshtastic.protoB\nMeshProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mesh.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a#meshtastic/protobuf/device_ui.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a\"meshtastic/protobuf/portnums.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/xmodem.proto\x1a meshtastic/protobuf/nanopb.proto\"\x99\x07\n\x08Position\x12\x17\n\nlatitude_i\x18\x01 \x01(\x0fH\x00\x88\x01\x01\x12\x18\n\x0blongitude_i\x18\x02 \x01(\x0fH\x01\x88\x01\x01\x12\x15\n\x08\x61ltitude\x18\x03 \x01(\x05H\x02\x88\x01\x01\x12\x0c\n\x04time\x18\x04 \x01(\x07\x12@\n\x0flocation_source\x18\x05 \x01(\x0e\x32\'.meshtastic.protobuf.Position.LocSource\x12@\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\'.meshtastic.protobuf.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x19\n\x0c\x61ltitude_hae\x18\t \x01(\x11H\x03\x88\x01\x01\x12(\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11H\x04\x88\x01\x01\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x19\n\x0cground_speed\x18\x0f \x01(\rH\x05\x88\x01\x01\x12\x19\n\x0cground_track\x18\x10 \x01(\rH\x06\x88\x01\x01\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\x42\r\n\x0b_latitude_iB\x0e\n\x0c_longitude_iB\x0b\n\t_altitudeB\x0f\n\r_altitude_haeB\x1e\n\x1c_altitude_geoidal_separationB\x0f\n\r_ground_speedB\x0f\n\r_ground_track\"\xbf\x02\n\x04User\x12\x11\n\x02id\x18\x01 \x01(\tB\x05\x92?\x02\x08\x10\x12\x18\n\tlong_name\x18\x02 \x01(\tB\x05\x92?\x02\x08(\x12\x19\n\nshort_name\x18\x03 \x01(\tB\x05\x92?\x02\x08\x05\x12\x1a\n\x07macaddr\x18\x04 \x01(\x0c\x42\t\x18\x01\x92?\x04\x08\x06x\x01\x12\x34\n\x08hw_model\x18\x05 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x19\n\npublic_key\x18\x08 \x01(\x0c\x42\x05\x92?\x02\x08 \x12\x1c\n\x0fis_unmessagable\x18\t \x01(\x08H\x00\x88\x01\x01\x42\x12\n\x10_is_unmessagable\"z\n\x0eRouteDiscovery\x12\x14\n\x05route\x18\x01 \x03(\x07\x42\x05\x92?\x02\x10\x08\x12\x1c\n\x0bsnr_towards\x18\x02 \x03(\x05\x42\x07\x92?\x04\x10\x08\x38\x08\x12\x19\n\nroute_back\x18\x03 \x03(\x07\x42\x05\x92?\x02\x10\x08\x12\x19\n\x08snr_back\x18\x04 \x03(\x05\x42\x07\x92?\x04\x10\x08\x38\x08\"\xb4\x04\n\x07Routing\x12<\n\rroute_request\x18\x01 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0broute_reply\x18\x02 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\".meshtastic.protobuf.Routing.ErrorH\x00\"\xe7\x02\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!\x12\x0e\n\nPKI_FAILED\x10\"\x12\x16\n\x12PKI_UNKNOWN_PUBKEY\x10#\x12\x19\n\x15\x41\x44MIN_BAD_SESSION_KEY\x10$\x12!\n\x1d\x41\x44MIN_PUBLIC_KEY_UNAUTHORIZED\x10%\x12\x17\n\x13RATE_LIMIT_EXCEEDED\x10&\x12\x1c\n\x18PKI_SEND_FAIL_PUBLIC_KEY\x10\'B\t\n\x07variant\"\xe3\x01\n\x04\x44\x61ta\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x17\n\x07payload\x18\x02 \x01(\x0c\x42\x06\x92?\x03\x08\xe9\x01\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\x12\x1c\n\x08\x62itfield\x18\t \x01(\rB\x05\x92?\x02\x38\x08H\x00\x88\x01\x01\x42\x0b\n\t_bitfield\"L\n\x0fKeyVerification\x12\r\n\x05nonce\x18\x01 \x01(\x04\x12\x14\n\x05hash1\x18\x02 \x01(\x0c\x42\x05\x92?\x02\x08 \x12\x14\n\x05hash2\x18\x03 \x01(\x0c\x42\x05\x92?\x02\x08 \"\xf1\x03\n\x14StoreForwardPlusPlus\x12V\n\x11sfpp_message_type\x18\x01 \x01(\x0e\x32;.meshtastic.protobuf.StoreForwardPlusPlus.SFPP_message_type\x12\x1b\n\x0cmessage_hash\x18\x02 \x01(\x0c\x42\x05\x92?\x02\x08 \x12\x1a\n\x0b\x63ommit_hash\x18\x03 \x01(\x0c\x42\x05\x92?\x02\x08 \x12\x18\n\troot_hash\x18\x04 \x01(\x0c\x42\x05\x92?\x02\x08 \x12\x17\n\x07message\x18\x05 \x01(\x0c\x42\x06\x92?\x03\x08\xf0\x01\x12\x17\n\x0f\x65ncapsulated_id\x18\x06 \x01(\r\x12\x17\n\x0f\x65ncapsulated_to\x18\x07 \x01(\r\x12\x19\n\x11\x65ncapsulated_from\x18\x08 \x01(\r\x12\x1b\n\x13\x65ncapsulated_rxtime\x18\t \x01(\r\x12\x13\n\x0b\x63hain_count\x18\n \x01(\r\"\x95\x01\n\x11SFPP_message_type\x12\x12\n\x0e\x43\x41NON_ANNOUNCE\x10\x00\x12\x0f\n\x0b\x43HAIN_QUERY\x10\x01\x12\x10\n\x0cLINK_REQUEST\x10\x03\x12\x10\n\x0cLINK_PROVIDE\x10\x04\x12\x1a\n\x16LINK_PROVIDE_FIRSTHALF\x10\x05\x12\x1b\n\x17LINK_PROVIDE_SECONDHALF\x10\x06\"\xf4\x02\n\x0bRemoteShell\x12\x33\n\x02op\x18\x01 \x01(\x0e\x32\'.meshtastic.protobuf.RemoteShell.OpCode\x12\x12\n\nsession_id\x18\x02 \x01(\r\x12\x0b\n\x03seq\x18\x03 \x01(\r\x12\x0f\n\x07\x61\x63k_seq\x18\x04 \x01(\r\x12\x17\n\x07payload\x18\x05 \x01(\x0c\x42\x06\x92?\x03\x08\xc8\x01\x12\x0c\n\x04\x63ols\x18\x06 \x01(\r\x12\x0c\n\x04rows\x18\x07 \x01(\r\x12\r\n\x05\x66lags\x18\x08 \x01(\r\x12\x13\n\x0blast_tx_seq\x18\t \x01(\r\x12\x13\n\x0blast_rx_seq\x18\n \x01(\r\"\x8f\x01\n\x06OpCode\x12\x0c\n\x08OP_UNSET\x10\x00\x12\x08\n\x04OPEN\x10\x01\x12\t\n\x05INPUT\x10\x02\x12\n\n\x06RESIZE\x10\x03\x12\t\n\x05\x43LOSE\x10\x04\x12\x08\n\x04PING\x10\x05\x12\x07\n\x03\x41\x43K\x10\x06\x12\x0b\n\x07OPEN_OK\x10@\x12\n\n\x06OUTPUT\x10\x41\x12\n\n\x06\x43LOSED\x10\x42\x12\t\n\x05\x45RROR\x10\x43\x12\x08\n\x04PONG\x10\x44\"\xd1\x01\n\x08Waypoint\x12\x11\n\x02id\x18\x01 \x01(\rB\x05\x92?\x02\x08\x10\x12\x17\n\nlatitude_i\x18\x02 \x01(\x0fH\x00\x88\x01\x01\x12\x18\n\x0blongitude_i\x18\x03 \x01(\x0fH\x01\x88\x01\x01\x12\x0e\n\x06\x65xpire\x18\x04 \x01(\r\x12\x11\n\tlocked_to\x18\x05 \x01(\r\x12\x13\n\x04name\x18\x06 \x01(\tB\x05\x92?\x02\x08\x1e\x12\x1a\n\x0b\x64\x65scription\x18\x07 \x01(\tB\x05\x92?\x02\x08\x64\x12\x0c\n\x04icon\x18\x08 \x01(\x07\x42\r\n\x0b_latitude_iB\x0e\n\x0c_longitude_i\"&\n\rStatusMessage\x12\x15\n\x06status\x18\x01 \x01(\tB\x05\x92?\x02\x08P\"\x83\x01\n\x16MqttClientProxyMessage\x12\x14\n\x05topic\x18\x01 \x01(\tB\x05\x92?\x02\x08<\x12\x16\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x42\x06\x92?\x03\x08\xb3\x03H\x00\x12\x16\n\x04text\x18\x03 \x01(\tB\x06\x92?\x03\x08\xb3\x03H\x00\x12\x10\n\x08retained\x18\x04 \x01(\x08\x42\x11\n\x0fpayload_variant\"\x92\x08\n\nMeshPacket\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x07\x12\n\n\x02to\x18\x02 \x01(\x07\x12\x16\n\x07\x63hannel\x18\x03 \x01(\rB\x05\x92?\x02\x38\x08\x12,\n\x07\x64\x65\x63oded\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.DataH\x00\x12\x1b\n\tencrypted\x18\x05 \x01(\x0c\x42\x06\x92?\x03\x08\x80\x02H\x00\x12\x11\n\x02id\x18\x06 \x01(\x07\x42\x05\x92?\x02\x08\x10\x12\x0f\n\x07rx_time\x18\x07 \x01(\x07\x12\x0e\n\x06rx_snr\x18\x08 \x01(\x02\x12\x18\n\thop_limit\x18\t \x01(\rB\x05\x92?\x02\x38\x08\x12\x10\n\x08want_ack\x18\n \x01(\x08\x12:\n\x08priority\x18\x0b \x01(\x0e\x32(.meshtastic.protobuf.MeshPacket.Priority\x12\x0f\n\x07rx_rssi\x18\x0c \x01(\x05\x12<\n\x07\x64\x65layed\x18\r \x01(\x0e\x32\'.meshtastic.protobuf.MeshPacket.DelayedB\x02\x18\x01\x12\x10\n\x08via_mqtt\x18\x0e \x01(\x08\x12\x18\n\thop_start\x18\x0f \x01(\rB\x05\x92?\x02\x38\x08\x12\x19\n\npublic_key\x18\x10 \x01(\x0c\x42\x05\x92?\x02\x08 \x12\x15\n\rpki_encrypted\x18\x11 \x01(\x08\x12\x17\n\x08next_hop\x18\x12 \x01(\rB\x05\x92?\x02\x38\x08\x12\x19\n\nrelay_node\x18\x13 \x01(\rB\x05\x92?\x02\x38\x08\x12\x10\n\x08tx_after\x18\x14 \x01(\r\x12O\n\x13transport_mechanism\x18\x15 \x01(\x0e\x32\x32.meshtastic.protobuf.MeshPacket.TransportMechanism\"~\n\x08Priority\x12\t\n\x05UNSET\x10\x00\x12\x07\n\x03MIN\x10\x01\x12\x0e\n\nBACKGROUND\x10\n\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10@\x12\x0c\n\x08RELIABLE\x10\x46\x12\x0c\n\x08RESPONSE\x10P\x12\x08\n\x04HIGH\x10\x64\x12\t\n\x05\x41LERT\x10n\x12\x07\n\x03\x41\x43K\x10x\x12\x07\n\x03MAX\x10\x7f\"B\n\x07\x44\x65layed\x12\x0c\n\x08NO_DELAY\x10\x00\x12\x15\n\x11\x44\x45LAYED_BROADCAST\x10\x01\x12\x12\n\x0e\x44\x45LAYED_DIRECT\x10\x02\"\xcf\x01\n\x12TransportMechanism\x12\x16\n\x12TRANSPORT_INTERNAL\x10\x00\x12\x12\n\x0eTRANSPORT_LORA\x10\x01\x12\x17\n\x13TRANSPORT_LORA_ALT1\x10\x02\x12\x17\n\x13TRANSPORT_LORA_ALT2\x10\x03\x12\x17\n\x13TRANSPORT_LORA_ALT3\x10\x04\x12\x12\n\x0eTRANSPORT_MQTT\x10\x05\x12\x1b\n\x17TRANSPORT_MULTICAST_UDP\x10\x06\x12\x11\n\rTRANSPORT_API\x10\x07\x42\x11\n\x0fpayload_variant\"\x82\x03\n\x08NodeInfo\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\'\n\x04user\x18\x02 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12/\n\x08position\x18\x03 \x01(\x0b\x32\x1d.meshtastic.protobuf.Position\x12\x0b\n\x03snr\x18\x04 \x01(\x02\x12\x12\n\nlast_heard\x18\x05 \x01(\x07\x12:\n\x0e\x64\x65vice_metrics\x18\x06 \x01(\x0b\x32\".meshtastic.protobuf.DeviceMetrics\x12\x16\n\x07\x63hannel\x18\x07 \x01(\rB\x05\x92?\x02\x38\x08\x12\x10\n\x08via_mqtt\x18\x08 \x01(\x08\x12\x1d\n\thops_away\x18\t \x01(\rB\x05\x92?\x02\x38\x08H\x00\x88\x01\x01\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\x12\x12\n\nis_ignored\x18\x0b \x01(\x08\x12 \n\x18is_key_manually_verified\x18\x0c \x01(\x08\x12\x10\n\x08is_muted\x18\r \x01(\x08\x42\x0c\n\n_hops_away\"\xe6\x01\n\nMyNodeInfo\x12\x13\n\x0bmy_node_num\x18\x01 \x01(\r\x12\x14\n\x0creboot_count\x18\x08 \x01(\r\x12\x17\n\x0fmin_app_version\x18\x0b \x01(\r\x12\x18\n\tdevice_id\x18\x0c \x01(\x0c\x42\x05\x92?\x02\x08\x10\x12\x16\n\x07pio_env\x18\r \x01(\tB\x05\x92?\x02\x08(\x12\x45\n\x10\x66irmware_edition\x18\x0e \x01(\x0e\x32$.meshtastic.protobuf.FirmwareEditionB\x05\x92?\x02\x38\x08\x12\x1b\n\x0cnodedb_count\x18\x0f \x01(\rB\x05\x92?\x02\x38\x10\"\xd8\x01\n\tLogRecord\x12\x17\n\x07message\x18\x01 \x01(\tB\x06\x92?\x03\x08\x80\x03\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x15\n\x06source\x18\x03 \x01(\tB\x05\x92?\x02\x08 \x12\x33\n\x05level\x18\x04 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\"X\n\x05Level\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x43RITICAL\x10\x32\x12\t\n\x05\x45RROR\x10(\x12\x0b\n\x07WARNING\x10\x1e\x12\x08\n\x04INFO\x10\x14\x12\t\n\x05\x44\x45\x42UG\x10\n\x12\t\n\x05TRACE\x10\x05\"e\n\x0bQueueStatus\x12\x12\n\x03res\x18\x01 \x01(\x05\x42\x05\x92?\x02\x38\x08\x12\x13\n\x04\x66ree\x18\x02 \x01(\rB\x05\x92?\x02\x38\x08\x12\x15\n\x06maxlen\x18\x03 \x01(\rB\x05\x92?\x02\x38\x08\x12\x16\n\x0emesh_packet_id\x18\x04 \x01(\r\"\xbe\x07\n\tFromRadio\x12\x11\n\x02id\x18\x01 \x01(\rB\x05\x92?\x02\x08\x10\x12\x31\n\x06packet\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x32\n\x07my_info\x18\x03 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfoH\x00\x12\x32\n\tnode_info\x18\x04 \x01(\x0b\x32\x1d.meshtastic.protobuf.NodeInfoH\x00\x12-\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12\x34\n\nlog_record\x18\x06 \x01(\x0b\x32\x1e.meshtastic.protobuf.LogRecordH\x00\x12\x1c\n\x12\x63onfig_complete_id\x18\x07 \x01(\rH\x00\x12\x12\n\x08rebooted\x18\x08 \x01(\x08H\x00\x12\x39\n\x0cmoduleConfig\x18\t \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12/\n\x07\x63hannel\x18\n \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x37\n\x0bqueueStatus\x18\x0b \x01(\x0b\x32 .meshtastic.protobuf.QueueStatusH\x00\x12\x33\n\x0cxmodemPacket\x18\x0c \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12\x37\n\x08metadata\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12M\n\x16mqttClientProxyMessage\x18\x0e \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x31\n\x08\x66ileInfo\x18\x0f \x01(\x0b\x32\x1d.meshtastic.protobuf.FileInfoH\x00\x12\x45\n\x12\x63lientNotification\x18\x10 \x01(\x0b\x32\'.meshtastic.protobuf.ClientNotificationH\x00\x12=\n\x0e\x64\x65viceuiConfig\x18\x11 \x01(\x0b\x32#.meshtastic.protobuf.DeviceUIConfigH\x00\x12>\n\x0flockdown_status\x18\x12 \x01(\x0b\x32#.meshtastic.protobuf.LockdownStatusH\x00\x42\x11\n\x0fpayload_variant\"\x95\x02\n\x0eLockdownStatus\x12\x38\n\x05state\x18\x01 \x01(\x0e\x32).meshtastic.protobuf.LockdownStatus.State\x12\x1a\n\x0block_reason\x18\x02 \x01(\tB\x05\x92?\x02\x08 \x12\x17\n\x0f\x62oots_remaining\x18\x03 \x01(\r\x12\x19\n\x11valid_until_epoch\x18\x04 \x01(\r\x12\x17\n\x0f\x62\x61\x63koff_seconds\x18\x05 \x01(\r\"`\n\x05State\x12\x15\n\x11STATE_UNSPECIFIED\x10\x00\x12\x13\n\x0fNEEDS_PROVISION\x10\x01\x12\n\n\x06LOCKED\x10\x02\x12\x0c\n\x08UNLOCKED\x10\x03\x12\x11\n\rUNLOCK_FAILED\x10\x04\"\xb8\x04\n\x12\x43lientNotification\x12\x15\n\x08reply_id\x18\x01 \x01(\rH\x01\x88\x01\x01\x12\x0c\n\x04time\x18\x02 \x01(\x07\x12\x33\n\x05level\x18\x03 \x01(\x0e\x32$.meshtastic.protobuf.LogRecord.Level\x12\x17\n\x07message\x18\x04 \x01(\tB\x06\x92?\x03\x08\x90\x03\x12Z\n\x1ekey_verification_number_inform\x18\x0b \x01(\x0b\x32\x30.meshtastic.protobuf.KeyVerificationNumberInformH\x00\x12\\\n\x1fkey_verification_number_request\x18\x0c \x01(\x0b\x32\x31.meshtastic.protobuf.KeyVerificationNumberRequestH\x00\x12K\n\x16key_verification_final\x18\r \x01(\x0b\x32).meshtastic.protobuf.KeyVerificationFinalH\x00\x12I\n\x15\x64uplicated_public_key\x18\x0e \x01(\x0b\x32(.meshtastic.protobuf.DuplicatedPublicKeyH\x00\x12=\n\x0flow_entropy_key\x18\x0f \x01(\x0b\x32\".meshtastic.protobuf.LowEntropyKeyH\x00\x42\x11\n\x0fpayload_variantB\x0b\n\t_reply_id\"e\n\x1bKeyVerificationNumberInform\x12\r\n\x05nonce\x18\x01 \x01(\x04\x12\x1e\n\x0fremote_longname\x18\x02 \x01(\tB\x05\x92?\x02\x08(\x12\x17\n\x0fsecurity_number\x18\x03 \x01(\r\"M\n\x1cKeyVerificationNumberRequest\x12\r\n\x05nonce\x18\x01 \x01(\x04\x12\x1e\n\x0fremote_longname\x18\x02 \x01(\tB\x05\x92?\x02\x08(\"\x7f\n\x14KeyVerificationFinal\x12\r\n\x05nonce\x18\x01 \x01(\x04\x12\x1e\n\x0fremote_longname\x18\x02 \x01(\tB\x05\x92?\x02\x08(\x12\x10\n\x08isSender\x18\x03 \x01(\x08\x12&\n\x17verification_characters\x18\x04 \x01(\tB\x05\x92?\x02\x08\n\"\x15\n\x13\x44uplicatedPublicKey\"\x0f\n\rLowEntropyKey\"9\n\x08\x46ileInfo\x12\x19\n\tfile_name\x18\x01 \x01(\tB\x06\x92?\x03\x08\xe4\x01\x12\x12\n\nsize_bytes\x18\x02 \x01(\r\"\xb8\x02\n\x07ToRadio\x12\x31\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacketH\x00\x12\x18\n\x0ewant_config_id\x18\x03 \x01(\rH\x00\x12\x14\n\ndisconnect\x18\x04 \x01(\x08H\x00\x12\x33\n\x0cxmodemPacket\x18\x05 \x01(\x0b\x32\x1b.meshtastic.protobuf.XModemH\x00\x12M\n\x16mqttClientProxyMessage\x18\x06 \x01(\x0b\x32+.meshtastic.protobuf.MqttClientProxyMessageH\x00\x12\x33\n\theartbeat\x18\x07 \x01(\x0b\x32\x1e.meshtastic.protobuf.HeartbeatH\x00\x42\x11\n\x0fpayload_variant\"Q\n\nCompressed\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x14\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x42\x06\x92?\x03\x08\xe9\x01\"\x97\x01\n\x0cNeighborInfo\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x17\n\x0flast_sent_by_id\x18\x02 \x01(\r\x12$\n\x1cnode_broadcast_interval_secs\x18\x03 \x01(\r\x12\x37\n\tneighbors\x18\x04 \x03(\x0b\x32\x1d.meshtastic.protobuf.NeighborB\x05\x92?\x02\x10\n\"d\n\x08Neighbor\x12\x0f\n\x07node_id\x18\x01 \x01(\r\x12\x0b\n\x03snr\x18\x02 \x01(\x02\x12\x14\n\x0clast_rx_time\x18\x03 \x01(\x07\x12$\n\x1cnode_broadcast_interval_secs\x18\x04 \x01(\r\"\xf0\x02\n\x0e\x44\x65viceMetadata\x12\x1f\n\x10\x66irmware_version\x18\x01 \x01(\tB\x05\x92?\x02\x08\x12\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12\x34\n\x08hw_model\x18\t \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x19\n\x11hasRemoteHardware\x18\n \x01(\x08\x12\x0e\n\x06hasPKC\x18\x0b \x01(\x08\x12\x18\n\x10\x65xcluded_modules\x18\x0c \x01(\r\"\x1a\n\tHeartbeat\x12\r\n\x05nonce\x18\x01 \x01(\r\"^\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\x33\n\x03pin\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\"{\n\x0e\x43hunkedPayload\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x1a\n\x0b\x63hunk_count\x18\x02 \x01(\rB\x05\x92?\x02\x38\x10\x12\x1a\n\x0b\x63hunk_index\x18\x03 \x01(\rB\x05\x92?\x02\x38\x10\x12\x1d\n\rpayload_chunk\x18\x04 \x01(\x0c\x42\x06\x92?\x03\x08\xe4\x01\"\x1f\n\rresend_chunks\x12\x0e\n\x06\x63hunks\x18\x01 \x03(\r\"\xb3\x01\n\x16\x43hunkedPayloadResponse\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x1a\n\x10request_transfer\x18\x02 \x01(\x08H\x00\x12\x19\n\x0f\x61\x63\x63\x65pt_transfer\x18\x03 \x01(\x08H\x00\x12;\n\rresend_chunks\x18\x04 \x01(\x0b\x32\".meshtastic.protobuf.resend_chunksH\x00\x42\x11\n\x0fpayload_variant*\xce\x14\n\rHardwareModel\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08TLORA_V2\x10\x01\x12\x0c\n\x08TLORA_V1\x10\x02\x12\x12\n\x0eTLORA_V2_1_1P6\x10\x03\x12\t\n\x05TBEAM\x10\x04\x12\x0f\n\x0bHELTEC_V2_0\x10\x05\x12\x0e\n\nTBEAM_V0P7\x10\x06\x12\n\n\x06T_ECHO\x10\x07\x12\x10\n\x0cTLORA_V1_1P3\x10\x08\x12\x0b\n\x07RAK4631\x10\t\x12\x0f\n\x0bHELTEC_V2_1\x10\n\x12\r\n\tHELTEC_V1\x10\x0b\x12\x18\n\x14LILYGO_TBEAM_S3_CORE\x10\x0c\x12\x0c\n\x08RAK11200\x10\r\x12\x0b\n\x07NANO_G1\x10\x0e\x12\x12\n\x0eTLORA_V2_1_1P8\x10\x0f\x12\x0f\n\x0bTLORA_T3_S3\x10\x10\x12\x14\n\x10NANO_G1_EXPLORER\x10\x11\x12\x11\n\rNANO_G2_ULTRA\x10\x12\x12\r\n\tLORA_TYPE\x10\x13\x12\x0b\n\x07WIPHONE\x10\x14\x12\x0e\n\nWIO_WM1110\x10\x15\x12\x0b\n\x07RAK2560\x10\x16\x12\x13\n\x0fHELTEC_HRU_3601\x10\x17\x12\x1a\n\x16HELTEC_WIRELESS_BRIDGE\x10\x18\x12\x0e\n\nSTATION_G1\x10\x19\x12\x0c\n\x08RAK11310\x10\x1a\x12\x14\n\x10SENSELORA_RP2040\x10\x1b\x12\x10\n\x0cSENSELORA_S3\x10\x1c\x12\r\n\tCANARYONE\x10\x1d\x12\x0f\n\x0bRP2040_LORA\x10\x1e\x12\x0e\n\nSTATION_G2\x10\x1f\x12\x11\n\rLORA_RELAY_V1\x10 \x12\x0f\n\x0bT_ECHO_PLUS\x10!\x12\x07\n\x03PPR\x10\"\x12\x0f\n\x0bGENIEBLOCKS\x10#\x12\x11\n\rNRF52_UNKNOWN\x10$\x12\r\n\tPORTDUINO\x10%\x12\x0f\n\x0b\x41NDROID_SIM\x10&\x12\n\n\x06\x44IY_V1\x10\'\x12\x15\n\x11NRF52840_PCA10059\x10(\x12\n\n\x06\x44R_DEV\x10)\x12\x0b\n\x07M5STACK\x10*\x12\r\n\tHELTEC_V3\x10+\x12\x11\n\rHELTEC_WSL_V3\x10,\x12\x13\n\x0f\x42\x45TAFPV_2400_TX\x10-\x12\x17\n\x13\x42\x45TAFPV_900_NANO_TX\x10.\x12\x0c\n\x08RPI_PICO\x10/\x12\x1b\n\x17HELTEC_WIRELESS_TRACKER\x10\x30\x12\x19\n\x15HELTEC_WIRELESS_PAPER\x10\x31\x12\n\n\x06T_DECK\x10\x32\x12\x0e\n\nT_WATCH_S3\x10\x33\x12\x11\n\rPICOMPUTER_S3\x10\x34\x12\x0f\n\x0bHELTEC_HT62\x10\x35\x12\x12\n\x0e\x45\x42YTE_ESP32_S3\x10\x36\x12\x11\n\rESP32_S3_PICO\x10\x37\x12\r\n\tCHATTER_2\x10\x38\x12\x1e\n\x1aHELTEC_WIRELESS_PAPER_V1_0\x10\x39\x12 \n\x1cHELTEC_WIRELESS_TRACKER_V1_0\x10:\x12\x0b\n\x07UNPHONE\x10;\x12\x0c\n\x08TD_LORAC\x10<\x12\x13\n\x0f\x43\x44\x45\x42YTE_EORA_S3\x10=\x12\x0f\n\x0bTWC_MESH_V4\x10>\x12\x16\n\x12NRF52_PROMICRO_DIY\x10?\x12\x1f\n\x1bRADIOMASTER_900_BANDIT_NANO\x10@\x12\x1c\n\x18HELTEC_CAPSULE_SENSOR_V3\x10\x41\x12\x1d\n\x19HELTEC_VISION_MASTER_T190\x10\x42\x12\x1d\n\x19HELTEC_VISION_MASTER_E213\x10\x43\x12\x1d\n\x19HELTEC_VISION_MASTER_E290\x10\x44\x12\x19\n\x15HELTEC_MESH_NODE_T114\x10\x45\x12\x16\n\x12SENSECAP_INDICATOR\x10\x46\x12\x13\n\x0fTRACKER_T1000_E\x10G\x12\x0b\n\x07RAK3172\x10H\x12\n\n\x06WIO_E5\x10I\x12\x1a\n\x16RADIOMASTER_900_BANDIT\x10J\x12\x13\n\x0fME25LS01_4Y10TD\x10K\x12\x18\n\x14RP2040_FEATHER_RFM95\x10L\x12\x15\n\x11M5STACK_COREBASIC\x10M\x12\x11\n\rM5STACK_CORE2\x10N\x12\r\n\tRPI_PICO2\x10O\x12\x12\n\x0eM5STACK_CORES3\x10P\x12\x11\n\rSEEED_XIAO_S3\x10Q\x12\x0b\n\x07MS24SF1\x10R\x12\x0c\n\x08TLORA_C6\x10S\x12\x0f\n\x0bWISMESH_TAP\x10T\x12\r\n\tROUTASTIC\x10U\x12\x0c\n\x08MESH_TAB\x10V\x12\x0c\n\x08MESHLINK\x10W\x12\x12\n\x0eXIAO_NRF52_KIT\x10X\x12\x10\n\x0cTHINKNODE_M1\x10Y\x12\x10\n\x0cTHINKNODE_M2\x10Z\x12\x0f\n\x0bT_ETH_ELITE\x10[\x12\x15\n\x11HELTEC_SENSOR_HUB\x10\\\x12\r\n\tMUZI_BASE\x10]\x12\x16\n\x12HELTEC_MESH_POCKET\x10^\x12\x14\n\x10SEEED_SOLAR_NODE\x10_\x12\x18\n\x14NOMADSTAR_METEOR_PRO\x10`\x12\r\n\tCROWPANEL\x10\x61\x12\x0b\n\x07LINK_32\x10\x62\x12\x18\n\x14SEEED_WIO_TRACKER_L1\x10\x63\x12\x1d\n\x19SEEED_WIO_TRACKER_L1_EINK\x10\x64\x12\x0f\n\x0bMUZI_R1_NEO\x10\x65\x12\x0e\n\nT_DECK_PRO\x10\x66\x12\x10\n\x0cT_LORA_PAGER\x10g\x12\x14\n\x10M5STACK_RESERVED\x10h\x12\x0f\n\x0bWISMESH_TAG\x10i\x12\x0b\n\x07RAK3312\x10j\x12\x10\n\x0cTHINKNODE_M5\x10k\x12\x15\n\x11HELTEC_MESH_SOLAR\x10l\x12\x0f\n\x0bT_ECHO_LITE\x10m\x12\r\n\tHELTEC_V4\x10n\x12\x0f\n\x0bM5STACK_C6L\x10o\x12\x19\n\x15M5STACK_CARDPUTER_ADV\x10p\x12\x1e\n\x1aHELTEC_WIRELESS_TRACKER_V2\x10q\x12\x11\n\rT_WATCH_ULTRA\x10r\x12\x10\n\x0cTHINKNODE_M3\x10s\x12\x12\n\x0eWISMESH_TAP_V2\x10t\x12\x0b\n\x07RAK3401\x10u\x12\x0b\n\x07RAK6421\x10v\x12\x10\n\x0cTHINKNODE_M4\x10w\x12\x10\n\x0cTHINKNODE_M6\x10x\x12\x12\n\x0eMESHSTICK_1262\x10y\x12\x10\n\x0cTBEAM_1_WATT\x10z\x12\x14\n\x10T5_S3_EPAPER_PRO\x10{\x12\r\n\tTBEAM_BPF\x10|\x12\x12\n\x0eMINI_EPAPER_S3\x10}\x12\x13\n\x0fTDISPLAY_S3_PRO\x10~\x12\x19\n\x15HELTEC_MESH_NODE_T096\x10\x7f\x12\x18\n\x13TRACKER_T1000_E_PRO\x10\x80\x01\x12\x11\n\x0cTHINKNODE_M7\x10\x81\x01\x12\x11\n\x0cTHINKNODE_M8\x10\x82\x01\x12\x11\n\x0cTHINKNODE_M9\x10\x83\x01\x12\x11\n\x0cHELTEC_V4_R8\x10\x84\x01\x12\x18\n\x13HELTEC_MESH_NODE_T1\x10\x85\x01\x12\x0f\n\nSTATION_G3\x10\x86\x01\x12\x13\n\x0eT_IMPULSE_PLUS\x10\x87\x01\x12\x10\n\x0bT_ECHO_CARD\x10\x88\x01\x12\x0f\n\nPRIVATE_HW\x10\xff\x01*,\n\tConstants\x12\x08\n\x04ZERO\x10\x00\x12\x15\n\x10\x44\x41TA_PAYLOAD_LEN\x10\xe9\x01*\xb4\x02\n\x11\x43riticalErrorCode\x12\x08\n\x04NONE\x10\x00\x12\x0f\n\x0bTX_WATCHDOG\x10\x01\x12\x14\n\x10SLEEP_ENTER_WAIT\x10\x02\x12\x0c\n\x08NO_RADIO\x10\x03\x12\x0f\n\x0bUNSPECIFIED\x10\x04\x12\x15\n\x11UBLOX_UNIT_FAILED\x10\x05\x12\r\n\tNO_AXP192\x10\x06\x12\x19\n\x15INVALID_RADIO_SETTING\x10\x07\x12\x13\n\x0fTRANSMIT_FAILED\x10\x08\x12\x0c\n\x08\x42ROWNOUT\x10\t\x12\x12\n\x0eSX1262_FAILURE\x10\n\x12\x11\n\rRADIO_SPI_BUG\x10\x0b\x12 \n\x1c\x46LASH_CORRUPTION_RECOVERABLE\x10\x0c\x12\"\n\x1e\x46LASH_CORRUPTION_UNRECOVERABLE\x10\r*\x7f\n\x0f\x46irmwareEdition\x12\x0b\n\x07VANILLA\x10\x00\x12\x11\n\rSMART_CITIZEN\x10\x01\x12\x0e\n\nOPEN_SAUCE\x10\x10\x12\n\n\x06\x44\x45\x46\x43ON\x10\x11\x12\x0f\n\x0b\x42URNING_MAN\x10\x12\x12\x0e\n\nHAMVENTION\x10\x13\x12\x0f\n\x0b\x44IY_EDITION\x10\x7f*\x80\x03\n\x0f\x45xcludedModules\x12\x11\n\rEXCLUDED_NONE\x10\x00\x12\x0f\n\x0bMQTT_CONFIG\x10\x01\x12\x11\n\rSERIAL_CONFIG\x10\x02\x12\x13\n\x0f\x45XTNOTIF_CONFIG\x10\x04\x12\x17\n\x13STOREFORWARD_CONFIG\x10\x08\x12\x14\n\x10RANGETEST_CONFIG\x10\x10\x12\x14\n\x10TELEMETRY_CONFIG\x10 \x12\x14\n\x10\x43\x41NNEDMSG_CONFIG\x10@\x12\x11\n\x0c\x41UDIO_CONFIG\x10\x80\x01\x12\x1a\n\x15REMOTEHARDWARE_CONFIG\x10\x80\x02\x12\x18\n\x13NEIGHBORINFO_CONFIG\x10\x80\x04\x12\x1b\n\x16\x41MBIENTLIGHTING_CONFIG\x10\x80\x08\x12\x1b\n\x16\x44\x45TECTIONSENSOR_CONFIG\x10\x80\x10\x12\x16\n\x11PAXCOUNTER_CONFIG\x10\x80 \x12\x15\n\x10\x42LUETOOTH_CONFIG\x10\x80@\x12\x14\n\x0eNETWORK_CONFIG\x10\x80\x80\x01\x42`\n\x14org.meshtastic.protoB\nMeshProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -28,100 +29,222 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.mesh_pb if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\nMeshProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' + _USER.fields_by_name['id']._options = None + _USER.fields_by_name['id']._serialized_options = b'\222?\002\010\020' + _USER.fields_by_name['long_name']._options = None + _USER.fields_by_name['long_name']._serialized_options = b'\222?\002\010(' + _USER.fields_by_name['short_name']._options = None + _USER.fields_by_name['short_name']._serialized_options = b'\222?\002\010\005' _USER.fields_by_name['macaddr']._options = None - _USER.fields_by_name['macaddr']._serialized_options = b'\030\001' + _USER.fields_by_name['macaddr']._serialized_options = b'\030\001\222?\004\010\006x\001' + _USER.fields_by_name['public_key']._options = None + _USER.fields_by_name['public_key']._serialized_options = b'\222?\002\010 ' + _ROUTEDISCOVERY.fields_by_name['route']._options = None + _ROUTEDISCOVERY.fields_by_name['route']._serialized_options = b'\222?\002\020\010' + _ROUTEDISCOVERY.fields_by_name['snr_towards']._options = None + _ROUTEDISCOVERY.fields_by_name['snr_towards']._serialized_options = b'\222?\004\020\0108\010' + _ROUTEDISCOVERY.fields_by_name['route_back']._options = None + _ROUTEDISCOVERY.fields_by_name['route_back']._serialized_options = b'\222?\002\020\010' + _ROUTEDISCOVERY.fields_by_name['snr_back']._options = None + _ROUTEDISCOVERY.fields_by_name['snr_back']._serialized_options = b'\222?\004\020\0108\010' + _DATA.fields_by_name['payload']._options = None + _DATA.fields_by_name['payload']._serialized_options = b'\222?\003\010\351\001' + _DATA.fields_by_name['bitfield']._options = None + _DATA.fields_by_name['bitfield']._serialized_options = b'\222?\0028\010' + _KEYVERIFICATION.fields_by_name['hash1']._options = None + _KEYVERIFICATION.fields_by_name['hash1']._serialized_options = b'\222?\002\010 ' + _KEYVERIFICATION.fields_by_name['hash2']._options = None + _KEYVERIFICATION.fields_by_name['hash2']._serialized_options = b'\222?\002\010 ' + _STOREFORWARDPLUSPLUS.fields_by_name['message_hash']._options = None + _STOREFORWARDPLUSPLUS.fields_by_name['message_hash']._serialized_options = b'\222?\002\010 ' + _STOREFORWARDPLUSPLUS.fields_by_name['commit_hash']._options = None + _STOREFORWARDPLUSPLUS.fields_by_name['commit_hash']._serialized_options = b'\222?\002\010 ' + _STOREFORWARDPLUSPLUS.fields_by_name['root_hash']._options = None + _STOREFORWARDPLUSPLUS.fields_by_name['root_hash']._serialized_options = b'\222?\002\010 ' + _STOREFORWARDPLUSPLUS.fields_by_name['message']._options = None + _STOREFORWARDPLUSPLUS.fields_by_name['message']._serialized_options = b'\222?\003\010\360\001' + _REMOTESHELL.fields_by_name['payload']._options = None + _REMOTESHELL.fields_by_name['payload']._serialized_options = b'\222?\003\010\310\001' + _WAYPOINT.fields_by_name['id']._options = None + _WAYPOINT.fields_by_name['id']._serialized_options = b'\222?\002\010\020' + _WAYPOINT.fields_by_name['name']._options = None + _WAYPOINT.fields_by_name['name']._serialized_options = b'\222?\002\010\036' + _WAYPOINT.fields_by_name['description']._options = None + _WAYPOINT.fields_by_name['description']._serialized_options = b'\222?\002\010d' + _STATUSMESSAGE.fields_by_name['status']._options = None + _STATUSMESSAGE.fields_by_name['status']._serialized_options = b'\222?\002\010P' + _MQTTCLIENTPROXYMESSAGE.fields_by_name['topic']._options = None + _MQTTCLIENTPROXYMESSAGE.fields_by_name['topic']._serialized_options = b'\222?\002\010<' + _MQTTCLIENTPROXYMESSAGE.fields_by_name['data']._options = None + _MQTTCLIENTPROXYMESSAGE.fields_by_name['data']._serialized_options = b'\222?\003\010\263\003' + _MQTTCLIENTPROXYMESSAGE.fields_by_name['text']._options = None + _MQTTCLIENTPROXYMESSAGE.fields_by_name['text']._serialized_options = b'\222?\003\010\263\003' + _MESHPACKET.fields_by_name['channel']._options = None + _MESHPACKET.fields_by_name['channel']._serialized_options = b'\222?\0028\010' + _MESHPACKET.fields_by_name['encrypted']._options = None + _MESHPACKET.fields_by_name['encrypted']._serialized_options = b'\222?\003\010\200\002' + _MESHPACKET.fields_by_name['id']._options = None + _MESHPACKET.fields_by_name['id']._serialized_options = b'\222?\002\010\020' + _MESHPACKET.fields_by_name['hop_limit']._options = None + _MESHPACKET.fields_by_name['hop_limit']._serialized_options = b'\222?\0028\010' _MESHPACKET.fields_by_name['delayed']._options = None _MESHPACKET.fields_by_name['delayed']._serialized_options = b'\030\001' - _globals['_HARDWAREMODEL']._serialized_start=8390 - _globals['_HARDWAREMODEL']._serialized_end=10761 - _globals['_CONSTANTS']._serialized_start=10763 - _globals['_CONSTANTS']._serialized_end=10807 - _globals['_CRITICALERRORCODE']._serialized_start=10810 - _globals['_CRITICALERRORCODE']._serialized_end=11118 - _globals['_FIRMWAREEDITION']._serialized_start=11120 - _globals['_FIRMWAREEDITION']._serialized_end=11247 - _globals['_EXCLUDEDMODULES']._serialized_start=11250 - _globals['_EXCLUDEDMODULES']._serialized_end=11634 - _globals['_POSITION']._serialized_start=310 - _globals['_POSITION']._serialized_end=1231 - _globals['_POSITION_LOCSOURCE']._serialized_start=926 - _globals['_POSITION_LOCSOURCE']._serialized_end=1004 - _globals['_POSITION_ALTSOURCE']._serialized_start=1006 - _globals['_POSITION_ALTSOURCE']._serialized_end=1104 - _globals['_USER']._serialized_start=1234 - _globals['_USER']._serialized_end=1518 - _globals['_ROUTEDISCOVERY']._serialized_start=1520 - _globals['_ROUTEDISCOVERY']._serialized_end=1610 - _globals['_ROUTING']._serialized_start=1613 - _globals['_ROUTING']._serialized_end=2177 - _globals['_ROUTING_ERROR']._serialized_start=1807 - _globals['_ROUTING_ERROR']._serialized_end=2166 - _globals['_DATA']._serialized_start=2180 - _globals['_DATA']._serialized_end=2392 - _globals['_KEYVERIFICATION']._serialized_start=2394 - _globals['_KEYVERIFICATION']._serialized_end=2456 - _globals['_STOREFORWARDPLUSPLUS']._serialized_start=2459 - _globals['_STOREFORWARDPLUSPLUS']._serialized_end=2927 - _globals['_STOREFORWARDPLUSPLUS_SFPP_MESSAGE_TYPE']._serialized_start=2778 - _globals['_STOREFORWARDPLUSPLUS_SFPP_MESSAGE_TYPE']._serialized_end=2927 - _globals['_WAYPOINT']._serialized_start=2930 - _globals['_WAYPOINT']._serialized_end=3118 - _globals['_STATUSMESSAGE']._serialized_start=3120 - _globals['_STATUSMESSAGE']._serialized_end=3151 - _globals['_MQTTCLIENTPROXYMESSAGE']._serialized_start=3153 - _globals['_MQTTCLIENTPROXYMESSAGE']._serialized_end=3261 - _globals['_MESHPACKET']._serialized_start=3264 - _globals['_MESHPACKET']._serialized_end=4249 - _globals['_MESHPACKET_PRIORITY']._serialized_start=3826 - _globals['_MESHPACKET_PRIORITY']._serialized_end=3952 - _globals['_MESHPACKET_DELAYED']._serialized_start=3954 - _globals['_MESHPACKET_DELAYED']._serialized_end=4020 - _globals['_MESHPACKET_TRANSPORTMECHANISM']._serialized_start=4023 - _globals['_MESHPACKET_TRANSPORTMECHANISM']._serialized_end=4230 - _globals['_NODEINFO']._serialized_start=4252 - _globals['_NODEINFO']._serialized_end=4624 - _globals['_MYNODEINFO']._serialized_start=4627 - _globals['_MYNODEINFO']._serialized_end=4829 - _globals['_LOGRECORD']._serialized_start=4832 - _globals['_LOGRECORD']._serialized_end=5033 - _globals['_LOGRECORD_LEVEL']._serialized_start=4945 - _globals['_LOGRECORD_LEVEL']._serialized_end=5033 - _globals['_QUEUESTATUS']._serialized_start=5035 - _globals['_QUEUESTATUS']._serialized_end=5115 - _globals['_FROMRADIO']._serialized_start=5118 - _globals['_FROMRADIO']._serialized_end=6005 - _globals['_CLIENTNOTIFICATION']._serialized_start=6008 - _globals['_CLIENTNOTIFICATION']._serialized_end=6568 - _globals['_KEYVERIFICATIONNUMBERINFORM']._serialized_start=6570 - _globals['_KEYVERIFICATIONNUMBERINFORM']._serialized_end=6664 - _globals['_KEYVERIFICATIONNUMBERREQUEST']._serialized_start=6666 - _globals['_KEYVERIFICATIONNUMBERREQUEST']._serialized_end=6736 - _globals['_KEYVERIFICATIONFINAL']._serialized_start=6738 - _globals['_KEYVERIFICATIONFINAL']._serialized_end=6851 - _globals['_DUPLICATEDPUBLICKEY']._serialized_start=6853 - _globals['_DUPLICATEDPUBLICKEY']._serialized_end=6874 - _globals['_LOWENTROPYKEY']._serialized_start=6876 - _globals['_LOWENTROPYKEY']._serialized_end=6891 - _globals['_FILEINFO']._serialized_start=6893 - _globals['_FILEINFO']._serialized_end=6942 - _globals['_TORADIO']._serialized_start=6945 - _globals['_TORADIO']._serialized_end=7257 - _globals['_COMPRESSED']._serialized_start=7259 - _globals['_COMPRESSED']._serialized_end=7332 - _globals['_NEIGHBORINFO']._serialized_start=7335 - _globals['_NEIGHBORINFO']._serialized_end=7479 - _globals['_NEIGHBOR']._serialized_start=7481 - _globals['_NEIGHBOR']._serialized_end=7581 - _globals['_DEVICEMETADATA']._serialized_start=7584 - _globals['_DEVICEMETADATA']._serialized_end=7945 - _globals['_HEARTBEAT']._serialized_start=7947 - _globals['_HEARTBEAT']._serialized_end=7973 - _globals['_NODEREMOTEHARDWAREPIN']._serialized_start=7975 - _globals['_NODEREMOTEHARDWAREPIN']._serialized_end=8069 - _globals['_CHUNKEDPAYLOAD']._serialized_start=8071 - _globals['_CHUNKEDPAYLOAD']._serialized_end=8172 - _globals['_RESEND_CHUNKS']._serialized_start=8174 - _globals['_RESEND_CHUNKS']._serialized_end=8205 - _globals['_CHUNKEDPAYLOADRESPONSE']._serialized_start=8208 - _globals['_CHUNKEDPAYLOADRESPONSE']._serialized_end=8387 + _MESHPACKET.fields_by_name['hop_start']._options = None + _MESHPACKET.fields_by_name['hop_start']._serialized_options = b'\222?\0028\010' + _MESHPACKET.fields_by_name['public_key']._options = None + _MESHPACKET.fields_by_name['public_key']._serialized_options = b'\222?\002\010 ' + _MESHPACKET.fields_by_name['next_hop']._options = None + _MESHPACKET.fields_by_name['next_hop']._serialized_options = b'\222?\0028\010' + _MESHPACKET.fields_by_name['relay_node']._options = None + _MESHPACKET.fields_by_name['relay_node']._serialized_options = b'\222?\0028\010' + _NODEINFO.fields_by_name['channel']._options = None + _NODEINFO.fields_by_name['channel']._serialized_options = b'\222?\0028\010' + _NODEINFO.fields_by_name['hops_away']._options = None + _NODEINFO.fields_by_name['hops_away']._serialized_options = b'\222?\0028\010' + _MYNODEINFO.fields_by_name['device_id']._options = None + _MYNODEINFO.fields_by_name['device_id']._serialized_options = b'\222?\002\010\020' + _MYNODEINFO.fields_by_name['pio_env']._options = None + _MYNODEINFO.fields_by_name['pio_env']._serialized_options = b'\222?\002\010(' + _MYNODEINFO.fields_by_name['firmware_edition']._options = None + _MYNODEINFO.fields_by_name['firmware_edition']._serialized_options = b'\222?\0028\010' + _MYNODEINFO.fields_by_name['nodedb_count']._options = None + _MYNODEINFO.fields_by_name['nodedb_count']._serialized_options = b'\222?\0028\020' + _LOGRECORD.fields_by_name['message']._options = None + _LOGRECORD.fields_by_name['message']._serialized_options = b'\222?\003\010\200\003' + _LOGRECORD.fields_by_name['source']._options = None + _LOGRECORD.fields_by_name['source']._serialized_options = b'\222?\002\010 ' + _QUEUESTATUS.fields_by_name['res']._options = None + _QUEUESTATUS.fields_by_name['res']._serialized_options = b'\222?\0028\010' + _QUEUESTATUS.fields_by_name['free']._options = None + _QUEUESTATUS.fields_by_name['free']._serialized_options = b'\222?\0028\010' + _QUEUESTATUS.fields_by_name['maxlen']._options = None + _QUEUESTATUS.fields_by_name['maxlen']._serialized_options = b'\222?\0028\010' + _FROMRADIO.fields_by_name['id']._options = None + _FROMRADIO.fields_by_name['id']._serialized_options = b'\222?\002\010\020' + _LOCKDOWNSTATUS.fields_by_name['lock_reason']._options = None + _LOCKDOWNSTATUS.fields_by_name['lock_reason']._serialized_options = b'\222?\002\010 ' + _CLIENTNOTIFICATION.fields_by_name['message']._options = None + _CLIENTNOTIFICATION.fields_by_name['message']._serialized_options = b'\222?\003\010\220\003' + _KEYVERIFICATIONNUMBERINFORM.fields_by_name['remote_longname']._options = None + _KEYVERIFICATIONNUMBERINFORM.fields_by_name['remote_longname']._serialized_options = b'\222?\002\010(' + _KEYVERIFICATIONNUMBERREQUEST.fields_by_name['remote_longname']._options = None + _KEYVERIFICATIONNUMBERREQUEST.fields_by_name['remote_longname']._serialized_options = b'\222?\002\010(' + _KEYVERIFICATIONFINAL.fields_by_name['remote_longname']._options = None + _KEYVERIFICATIONFINAL.fields_by_name['remote_longname']._serialized_options = b'\222?\002\010(' + _KEYVERIFICATIONFINAL.fields_by_name['verification_characters']._options = None + _KEYVERIFICATIONFINAL.fields_by_name['verification_characters']._serialized_options = b'\222?\002\010\n' + _FILEINFO.fields_by_name['file_name']._options = None + _FILEINFO.fields_by_name['file_name']._serialized_options = b'\222?\003\010\344\001' + _COMPRESSED.fields_by_name['data']._options = None + _COMPRESSED.fields_by_name['data']._serialized_options = b'\222?\003\010\351\001' + _NEIGHBORINFO.fields_by_name['neighbors']._options = None + _NEIGHBORINFO.fields_by_name['neighbors']._serialized_options = b'\222?\002\020\n' + _DEVICEMETADATA.fields_by_name['firmware_version']._options = None + _DEVICEMETADATA.fields_by_name['firmware_version']._serialized_options = b'\222?\002\010\022' + _CHUNKEDPAYLOAD.fields_by_name['chunk_count']._options = None + _CHUNKEDPAYLOAD.fields_by_name['chunk_count']._serialized_options = b'\222?\0028\020' + _CHUNKEDPAYLOAD.fields_by_name['chunk_index']._options = None + _CHUNKEDPAYLOAD.fields_by_name['chunk_index']._serialized_options = b'\222?\0028\020' + _CHUNKEDPAYLOAD.fields_by_name['payload_chunk']._options = None + _CHUNKEDPAYLOAD.fields_by_name['payload_chunk']._serialized_options = b'\222?\003\010\344\001' + _globals['_HARDWAREMODEL']._serialized_start=9550 + _globals['_HARDWAREMODEL']._serialized_end=12188 + _globals['_CONSTANTS']._serialized_start=12190 + _globals['_CONSTANTS']._serialized_end=12234 + _globals['_CRITICALERRORCODE']._serialized_start=12237 + _globals['_CRITICALERRORCODE']._serialized_end=12545 + _globals['_FIRMWAREEDITION']._serialized_start=12547 + _globals['_FIRMWAREEDITION']._serialized_end=12674 + _globals['_EXCLUDEDMODULES']._serialized_start=12677 + _globals['_EXCLUDEDMODULES']._serialized_end=13061 + _globals['_POSITION']._serialized_start=344 + _globals['_POSITION']._serialized_end=1265 + _globals['_POSITION_LOCSOURCE']._serialized_start=960 + _globals['_POSITION_LOCSOURCE']._serialized_end=1038 + _globals['_POSITION_ALTSOURCE']._serialized_start=1040 + _globals['_POSITION_ALTSOURCE']._serialized_end=1138 + _globals['_USER']._serialized_start=1268 + _globals['_USER']._serialized_end=1587 + _globals['_ROUTEDISCOVERY']._serialized_start=1589 + _globals['_ROUTEDISCOVERY']._serialized_end=1711 + _globals['_ROUTING']._serialized_start=1714 + _globals['_ROUTING']._serialized_end=2278 + _globals['_ROUTING_ERROR']._serialized_start=1908 + _globals['_ROUTING_ERROR']._serialized_end=2267 + _globals['_DATA']._serialized_start=2281 + _globals['_DATA']._serialized_end=2508 + _globals['_KEYVERIFICATION']._serialized_start=2510 + _globals['_KEYVERIFICATION']._serialized_end=2586 + _globals['_STOREFORWARDPLUSPLUS']._serialized_start=2589 + _globals['_STOREFORWARDPLUSPLUS']._serialized_end=3086 + _globals['_STOREFORWARDPLUSPLUS_SFPP_MESSAGE_TYPE']._serialized_start=2937 + _globals['_STOREFORWARDPLUSPLUS_SFPP_MESSAGE_TYPE']._serialized_end=3086 + _globals['_REMOTESHELL']._serialized_start=3089 + _globals['_REMOTESHELL']._serialized_end=3461 + _globals['_REMOTESHELL_OPCODE']._serialized_start=3318 + _globals['_REMOTESHELL_OPCODE']._serialized_end=3461 + _globals['_WAYPOINT']._serialized_start=3464 + _globals['_WAYPOINT']._serialized_end=3673 + _globals['_STATUSMESSAGE']._serialized_start=3675 + _globals['_STATUSMESSAGE']._serialized_end=3713 + _globals['_MQTTCLIENTPROXYMESSAGE']._serialized_start=3716 + _globals['_MQTTCLIENTPROXYMESSAGE']._serialized_end=3847 + _globals['_MESHPACKET']._serialized_start=3850 + _globals['_MESHPACKET']._serialized_end=4892 + _globals['_MESHPACKET_PRIORITY']._serialized_start=4469 + _globals['_MESHPACKET_PRIORITY']._serialized_end=4595 + _globals['_MESHPACKET_DELAYED']._serialized_start=4597 + _globals['_MESHPACKET_DELAYED']._serialized_end=4663 + _globals['_MESHPACKET_TRANSPORTMECHANISM']._serialized_start=4666 + _globals['_MESHPACKET_TRANSPORTMECHANISM']._serialized_end=4873 + _globals['_NODEINFO']._serialized_start=4895 + _globals['_NODEINFO']._serialized_end=5281 + _globals['_MYNODEINFO']._serialized_start=5284 + _globals['_MYNODEINFO']._serialized_end=5514 + _globals['_LOGRECORD']._serialized_start=5517 + _globals['_LOGRECORD']._serialized_end=5733 + _globals['_LOGRECORD_LEVEL']._serialized_start=5645 + _globals['_LOGRECORD_LEVEL']._serialized_end=5733 + _globals['_QUEUESTATUS']._serialized_start=5735 + _globals['_QUEUESTATUS']._serialized_end=5836 + _globals['_FROMRADIO']._serialized_start=5839 + _globals['_FROMRADIO']._serialized_end=6797 + _globals['_LOCKDOWNSTATUS']._serialized_start=6800 + _globals['_LOCKDOWNSTATUS']._serialized_end=7077 + _globals['_LOCKDOWNSTATUS_STATE']._serialized_start=6981 + _globals['_LOCKDOWNSTATUS_STATE']._serialized_end=7077 + _globals['_CLIENTNOTIFICATION']._serialized_start=7080 + _globals['_CLIENTNOTIFICATION']._serialized_end=7648 + _globals['_KEYVERIFICATIONNUMBERINFORM']._serialized_start=7650 + _globals['_KEYVERIFICATIONNUMBERINFORM']._serialized_end=7751 + _globals['_KEYVERIFICATIONNUMBERREQUEST']._serialized_start=7753 + _globals['_KEYVERIFICATIONNUMBERREQUEST']._serialized_end=7830 + _globals['_KEYVERIFICATIONFINAL']._serialized_start=7832 + _globals['_KEYVERIFICATIONFINAL']._serialized_end=7959 + _globals['_DUPLICATEDPUBLICKEY']._serialized_start=7961 + _globals['_DUPLICATEDPUBLICKEY']._serialized_end=7982 + _globals['_LOWENTROPYKEY']._serialized_start=7984 + _globals['_LOWENTROPYKEY']._serialized_end=7999 + _globals['_FILEINFO']._serialized_start=8001 + _globals['_FILEINFO']._serialized_end=8058 + _globals['_TORADIO']._serialized_start=8061 + _globals['_TORADIO']._serialized_end=8373 + _globals['_COMPRESSED']._serialized_start=8375 + _globals['_COMPRESSED']._serialized_end=8456 + _globals['_NEIGHBORINFO']._serialized_start=8459 + _globals['_NEIGHBORINFO']._serialized_end=8610 + _globals['_NEIGHBOR']._serialized_start=8612 + _globals['_NEIGHBOR']._serialized_end=8712 + _globals['_DEVICEMETADATA']._serialized_start=8715 + _globals['_DEVICEMETADATA']._serialized_end=9083 + _globals['_HEARTBEAT']._serialized_start=9085 + _globals['_HEARTBEAT']._serialized_end=9111 + _globals['_NODEREMOTEHARDWAREPIN']._serialized_start=9113 + _globals['_NODEREMOTEHARDWAREPIN']._serialized_end=9207 + _globals['_CHUNKEDPAYLOAD']._serialized_start=9209 + _globals['_CHUNKEDPAYLOAD']._serialized_end=9332 + _globals['_RESEND_CHUNKS']._serialized_start=9334 + _globals['_RESEND_CHUNKS']._serialized_end=9365 + _globals['_CHUNKEDPAYLOADRESPONSE']._serialized_start=9368 + _globals['_CHUNKEDPAYLOADRESPONSE']._serialized_end=9547 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/mesh_pb2.pyi b/meshtastic/protobuf/mesh_pb2.pyi index a640226..506e788 100644 --- a/meshtastic/protobuf/mesh_pb2.pyi +++ b/meshtastic/protobuf/mesh_pb2.pyi @@ -547,6 +547,53 @@ class _HardwareModelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._ """ LilyGo T5 S3 ePaper Pro (V1 and V2) """ + TBEAM_BPF: _HardwareModel.ValueType # 124 + """ + LilyGo T-Beam BPF (144-148Mhz) + """ + MINI_EPAPER_S3: _HardwareModel.ValueType # 125 + """ + LilyGo T-Mini E-paper S3 Kit + """ + TDISPLAY_S3_PRO: _HardwareModel.ValueType # 126 + """ + LilyGo T-Display S3 Pro LR1121 + """ + HELTEC_MESH_NODE_T096: _HardwareModel.ValueType # 127 + """ + Heltec Mesh Node T096 board features an nRF52840 CPU and a TFT screen. + """ + TRACKER_T1000_E_PRO: _HardwareModel.ValueType # 128 + """ + Seeed studio T1000-E Pro tracker card. NRF52840 w/ LR2021 radio, + GPS, button, buzzer, and sensors. + """ + THINKNODE_M7: _HardwareModel.ValueType # 129 + """ + Elecrow ThinkNode M7, M8 and M9 + """ + THINKNODE_M8: _HardwareModel.ValueType # 130 + THINKNODE_M9: _HardwareModel.ValueType # 131 + HELTEC_V4_R8: _HardwareModel.ValueType # 132 + """ + The Heltec-V4-R8 uses an ESP32S3R8 chip, plus an SX1262. + """ + HELTEC_MESH_NODE_T1: _HardwareModel.ValueType # 133 + """ + The HELTEC_MESH_NODE_T1 uses an NRF52840 chip, plus an SX1262. + """ + STATION_G3: _HardwareModel.ValueType # 134 + """ + B&Q Consulting Station G3: TBD + """ + T_IMPULSE_PLUS: _HardwareModel.ValueType # 135 + """ + Lilygo T-Impulse-Plus + """ + T_ECHO_CARD: _HardwareModel.ValueType # 136 + """ + Lilygo T-Echo Card + """ PRIVATE_HW: _HardwareModel.ValueType # 255 """ ------------------------------------------------------------------------------------------------------------------------------------------ @@ -1077,6 +1124,53 @@ T5_S3_EPAPER_PRO: HardwareModel.ValueType # 123 """ LilyGo T5 S3 ePaper Pro (V1 and V2) """ +TBEAM_BPF: HardwareModel.ValueType # 124 +""" +LilyGo T-Beam BPF (144-148Mhz) +""" +MINI_EPAPER_S3: HardwareModel.ValueType # 125 +""" +LilyGo T-Mini E-paper S3 Kit +""" +TDISPLAY_S3_PRO: HardwareModel.ValueType # 126 +""" +LilyGo T-Display S3 Pro LR1121 +""" +HELTEC_MESH_NODE_T096: HardwareModel.ValueType # 127 +""" +Heltec Mesh Node T096 board features an nRF52840 CPU and a TFT screen. +""" +TRACKER_T1000_E_PRO: HardwareModel.ValueType # 128 +""" +Seeed studio T1000-E Pro tracker card. NRF52840 w/ LR2021 radio, +GPS, button, buzzer, and sensors. +""" +THINKNODE_M7: HardwareModel.ValueType # 129 +""" +Elecrow ThinkNode M7, M8 and M9 +""" +THINKNODE_M8: HardwareModel.ValueType # 130 +THINKNODE_M9: HardwareModel.ValueType # 131 +HELTEC_V4_R8: HardwareModel.ValueType # 132 +""" +The Heltec-V4-R8 uses an ESP32S3R8 chip, plus an SX1262. +""" +HELTEC_MESH_NODE_T1: HardwareModel.ValueType # 133 +""" +The HELTEC_MESH_NODE_T1 uses an NRF52840 chip, plus an SX1262. +""" +STATION_G3: HardwareModel.ValueType # 134 +""" +B&Q Consulting Station G3: TBD +""" +T_IMPULSE_PLUS: HardwareModel.ValueType # 135 +""" +Lilygo T-Impulse-Plus +""" +T_ECHO_CARD: HardwareModel.ValueType # 136 +""" +Lilygo T-Echo Card +""" PRIVATE_HW: HardwareModel.ValueType # 255 """ ------------------------------------------------------------------------------------------------------------------------------------------ @@ -2374,6 +2468,126 @@ class StoreForwardPlusPlus(google.protobuf.message.Message): global___StoreForwardPlusPlus = StoreForwardPlusPlus +@typing.final +class RemoteShell(google.protobuf.message.Message): + """ + The actual over-the-mesh message doing RemoteShell + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _OpCode: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _OpCodeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[RemoteShell._OpCode.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + OP_UNSET: RemoteShell._OpCode.ValueType # 0 + OPEN: RemoteShell._OpCode.ValueType # 1 + """Client -> server""" + INPUT: RemoteShell._OpCode.ValueType # 2 + RESIZE: RemoteShell._OpCode.ValueType # 3 + CLOSE: RemoteShell._OpCode.ValueType # 4 + PING: RemoteShell._OpCode.ValueType # 5 + ACK: RemoteShell._OpCode.ValueType # 6 + OPEN_OK: RemoteShell._OpCode.ValueType # 64 + """Server -> client""" + OUTPUT: RemoteShell._OpCode.ValueType # 65 + CLOSED: RemoteShell._OpCode.ValueType # 66 + ERROR: RemoteShell._OpCode.ValueType # 67 + PONG: RemoteShell._OpCode.ValueType # 68 + + class OpCode(_OpCode, metaclass=_OpCodeEnumTypeWrapper): + """ + 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. + """ + + OP_UNSET: RemoteShell.OpCode.ValueType # 0 + OPEN: RemoteShell.OpCode.ValueType # 1 + """Client -> server""" + INPUT: RemoteShell.OpCode.ValueType # 2 + RESIZE: RemoteShell.OpCode.ValueType # 3 + CLOSE: RemoteShell.OpCode.ValueType # 4 + PING: RemoteShell.OpCode.ValueType # 5 + ACK: RemoteShell.OpCode.ValueType # 6 + OPEN_OK: RemoteShell.OpCode.ValueType # 64 + """Server -> client""" + OUTPUT: RemoteShell.OpCode.ValueType # 65 + CLOSED: RemoteShell.OpCode.ValueType # 66 + ERROR: RemoteShell.OpCode.ValueType # 67 + PONG: RemoteShell.OpCode.ValueType # 68 + + OP_FIELD_NUMBER: builtins.int + SESSION_ID_FIELD_NUMBER: builtins.int + SEQ_FIELD_NUMBER: builtins.int + ACK_SEQ_FIELD_NUMBER: builtins.int + PAYLOAD_FIELD_NUMBER: builtins.int + COLS_FIELD_NUMBER: builtins.int + ROWS_FIELD_NUMBER: builtins.int + FLAGS_FIELD_NUMBER: builtins.int + LAST_TX_SEQ_FIELD_NUMBER: builtins.int + LAST_RX_SEQ_FIELD_NUMBER: builtins.int + op: global___RemoteShell.OpCode.ValueType + """ + Structured frame operation. + """ + session_id: builtins.int + """ + Logical PTY session identifier. + """ + seq: builtins.int + """ + Monotonic sequence number for this frame. + """ + ack_seq: builtins.int + """ + Cumulative ack sequence number. + """ + payload: builtins.bytes + """ + Opaque bytes payload for INPUT/OUTPUT/ERROR and other frame bodies. + """ + cols: builtins.int + """ + Terminal size columns used for OPEN/RESIZE signaling. + """ + rows: builtins.int + """ + Terminal size rows used for OPEN/RESIZE signaling. + """ + flags: builtins.int + """ + Bit flags for protocol extensions. + """ + last_tx_seq: builtins.int + """ + The last sequence number TX'd. + """ + last_rx_seq: builtins.int + """ + The last sequence number RX'd. + """ + def __init__( + self, + *, + op: global___RemoteShell.OpCode.ValueType = ..., + session_id: builtins.int = ..., + seq: builtins.int = ..., + ack_seq: builtins.int = ..., + payload: builtins.bytes = ..., + cols: builtins.int = ..., + rows: builtins.int = ..., + flags: builtins.int = ..., + last_tx_seq: builtins.int = ..., + last_rx_seq: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["ack_seq", b"ack_seq", "cols", b"cols", "flags", b"flags", "last_rx_seq", b"last_rx_seq", "last_tx_seq", b"last_tx_seq", "op", b"op", "payload", b"payload", "rows", b"rows", "seq", b"seq", "session_id", b"session_id"]) -> None: ... + +global___RemoteShell = RemoteShell + @typing.final class Waypoint(google.protobuf.message.Message): """ @@ -3282,6 +3496,7 @@ class FromRadio(google.protobuf.message.Message): FILEINFO_FIELD_NUMBER: builtins.int CLIENTNOTIFICATION_FIELD_NUMBER: builtins.int DEVICEUICONFIG_FIELD_NUMBER: builtins.int + LOCKDOWN_STATUS_FIELD_NUMBER: builtins.int id: builtins.int """ The packet id, used to allow the phone to request missing read packets from the FIFO, @@ -3387,6 +3602,16 @@ class FromRadio(google.protobuf.message.Message): Persistent data for device-ui """ + @property + def lockdown_status(self) -> global___LockdownStatus: + """ + Lockdown state notification for hardened firmware builds. + Sent post-config (so unauthorized clients learn they must + provision/unlock) and after each LockdownAuth admin command + to report success or failure. Replaces the earlier scheme of + encoding state as magic-string prefixes inside ClientNotification. + """ + def __init__( self, *, @@ -3407,13 +3632,133 @@ class FromRadio(google.protobuf.message.Message): fileInfo: global___FileInfo | None = ..., clientNotification: global___ClientNotification | None = ..., deviceuiConfig: meshtastic.protobuf.device_ui_pb2.DeviceUIConfig | None = ..., + lockdown_status: global___LockdownStatus | None = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["channel", b"channel", "clientNotification", b"clientNotification", "config", b"config", "config_complete_id", b"config_complete_id", "deviceuiConfig", b"deviceuiConfig", "fileInfo", b"fileInfo", "log_record", b"log_record", "metadata", b"metadata", "moduleConfig", b"moduleConfig", "mqttClientProxyMessage", b"mqttClientProxyMessage", "my_info", b"my_info", "node_info", b"node_info", "packet", b"packet", "payload_variant", b"payload_variant", "queueStatus", b"queueStatus", "rebooted", b"rebooted", "xmodemPacket", b"xmodemPacket"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["channel", b"channel", "clientNotification", b"clientNotification", "config", b"config", "config_complete_id", b"config_complete_id", "deviceuiConfig", b"deviceuiConfig", "fileInfo", b"fileInfo", "id", b"id", "log_record", b"log_record", "metadata", b"metadata", "moduleConfig", b"moduleConfig", "mqttClientProxyMessage", b"mqttClientProxyMessage", "my_info", b"my_info", "node_info", b"node_info", "packet", b"packet", "payload_variant", b"payload_variant", "queueStatus", b"queueStatus", "rebooted", b"rebooted", "xmodemPacket", b"xmodemPacket"]) -> None: ... - def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["packet", "my_info", "node_info", "config", "log_record", "config_complete_id", "rebooted", "moduleConfig", "channel", "queueStatus", "xmodemPacket", "metadata", "mqttClientProxyMessage", "fileInfo", "clientNotification", "deviceuiConfig"] | None: ... + def HasField(self, field_name: typing.Literal["channel", b"channel", "clientNotification", b"clientNotification", "config", b"config", "config_complete_id", b"config_complete_id", "deviceuiConfig", b"deviceuiConfig", "fileInfo", b"fileInfo", "lockdown_status", b"lockdown_status", "log_record", b"log_record", "metadata", b"metadata", "moduleConfig", b"moduleConfig", "mqttClientProxyMessage", b"mqttClientProxyMessage", "my_info", b"my_info", "node_info", b"node_info", "packet", b"packet", "payload_variant", b"payload_variant", "queueStatus", b"queueStatus", "rebooted", b"rebooted", "xmodemPacket", b"xmodemPacket"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["channel", b"channel", "clientNotification", b"clientNotification", "config", b"config", "config_complete_id", b"config_complete_id", "deviceuiConfig", b"deviceuiConfig", "fileInfo", b"fileInfo", "id", b"id", "lockdown_status", b"lockdown_status", "log_record", b"log_record", "metadata", b"metadata", "moduleConfig", b"moduleConfig", "mqttClientProxyMessage", b"mqttClientProxyMessage", "my_info", b"my_info", "node_info", b"node_info", "packet", b"packet", "payload_variant", b"payload_variant", "queueStatus", b"queueStatus", "rebooted", b"rebooted", "xmodemPacket", b"xmodemPacket"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["packet", "my_info", "node_info", "config", "log_record", "config_complete_id", "rebooted", "moduleConfig", "channel", "queueStatus", "xmodemPacket", "metadata", "mqttClientProxyMessage", "fileInfo", "clientNotification", "deviceuiConfig", "lockdown_status"] | None: ... global___FromRadio = FromRadio +@typing.final +class LockdownStatus(google.protobuf.message.Message): + """ + Lockdown state report from firmware to client (for hardened builds + with MESHTASTIC_LOCKDOWN). Sent immediately after config_complete_id + to inform a freshly-connected unauthorized client what it must do, + and again in response to each LockdownAuth admin command. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _State: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _StateEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[LockdownStatus._State.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + STATE_UNSPECIFIED: LockdownStatus._State.ValueType # 0 + """Default; should not be sent.""" + NEEDS_PROVISION: LockdownStatus._State.ValueType # 1 + """ + No passphrase has ever been provisioned on this device. + Client should prompt the operator to set one. + """ + LOCKED: LockdownStatus._State.ValueType # 2 + """ + Storage is locked or this client has not authenticated yet. + lock_reason carries a machine-readable detail string. + Client should present (or auto-replay) a passphrase via + AdminMessage.lockdown_auth. + """ + UNLOCKED: LockdownStatus._State.ValueType # 3 + """ + Passphrase accepted; client is now authorized for this connection. + boots_remaining and valid_until_epoch describe the active session + token's TTL. + """ + UNLOCK_FAILED: LockdownStatus._State.ValueType # 4 + """ + Passphrase rejected. backoff_seconds is non-zero when rate-limited. + """ + + class State(_State, metaclass=_StateEnumTypeWrapper): ... + STATE_UNSPECIFIED: LockdownStatus.State.ValueType # 0 + """Default; should not be sent.""" + NEEDS_PROVISION: LockdownStatus.State.ValueType # 1 + """ + No passphrase has ever been provisioned on this device. + Client should prompt the operator to set one. + """ + LOCKED: LockdownStatus.State.ValueType # 2 + """ + Storage is locked or this client has not authenticated yet. + lock_reason carries a machine-readable detail string. + Client should present (or auto-replay) a passphrase via + AdminMessage.lockdown_auth. + """ + UNLOCKED: LockdownStatus.State.ValueType # 3 + """ + Passphrase accepted; client is now authorized for this connection. + boots_remaining and valid_until_epoch describe the active session + token's TTL. + """ + UNLOCK_FAILED: LockdownStatus.State.ValueType # 4 + """ + Passphrase rejected. backoff_seconds is non-zero when rate-limited. + """ + + STATE_FIELD_NUMBER: builtins.int + LOCK_REASON_FIELD_NUMBER: builtins.int + BOOTS_REMAINING_FIELD_NUMBER: builtins.int + VALID_UNTIL_EPOCH_FIELD_NUMBER: builtins.int + BACKOFF_SECONDS_FIELD_NUMBER: builtins.int + state: global___LockdownStatus.State.ValueType + """Current lockdown state being reported.""" + lock_reason: builtins.str + """ + For LOCKED: machine-readable reason. Known values: + "needs_auth" — storage already unlocked, client must auth + "token_missing" — no boot token on flash + "token_expired" — boot token wall-clock TTL elapsed + "token_boots_zero" — boot token boot-count TTL exhausted + "token_hmac_fail" — token tampered or wrong device + "token_dek_fail" — token DEK decrypt failed + "token_wrong_size" — token file corrupted + "token_bad_magic" — token file corrupted + "not_provisioned" — should generally use NEEDS_PROVISION state instead + Other values may be added; clients should treat unknown values as + "locked, ask for passphrase". + """ + boots_remaining: builtins.int + """ + For UNLOCKED: remaining boots on the issued session token. + Decrements by 1 on each subsequent boot. + """ + valid_until_epoch: builtins.int + """ + For UNLOCKED: wall-clock expiry of the issued session token, + absolute Unix-epoch seconds. 0 = no time limit. + """ + backoff_seconds: builtins.int + """ + For UNLOCK_FAILED: seconds the client must wait before another + passphrase attempt will be accepted. 0 = wrong passphrase, no + backoff (immediate retry allowed but advisable to prompt user). + """ + def __init__( + self, + *, + state: global___LockdownStatus.State.ValueType = ..., + lock_reason: builtins.str = ..., + boots_remaining: builtins.int = ..., + valid_until_epoch: builtins.int = ..., + backoff_seconds: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["backoff_seconds", b"backoff_seconds", "boots_remaining", b"boots_remaining", "lock_reason", b"lock_reason", "state", b"state", "valid_until_epoch", b"valid_until_epoch"]) -> None: ... + +global___LockdownStatus = LockdownStatus + @typing.final class ClientNotification(google.protobuf.message.Message): """ diff --git a/meshtastic/protobuf/module_config_pb2.py b/meshtastic/protobuf/module_config_pb2.py index dc9f5c8..0bebf1a 100644 --- a/meshtastic/protobuf/module_config_pb2.py +++ b/meshtastic/protobuf/module_config_pb2.py @@ -11,9 +11,11 @@ from google.protobuf.internal import builder as _builder _sym_db = _symbol_database.Default() +from meshtastic.protobuf import atak_pb2 as meshtastic_dot_protobuf_dot_atak__pb2 +from meshtastic.protobuf import nanopb_pb2 as meshtastic_dot_protobuf_dot_nanopb__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\'meshtastic/protobuf/module_config.proto\x12\x13meshtastic.protobuf\"\xb2)\n\x0cModuleConfig\x12<\n\x04mqtt\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.ModuleConfig.MQTTConfigH\x00\x12@\n\x06serial\x18\x02 \x01(\x0b\x32..meshtastic.protobuf.ModuleConfig.SerialConfigH\x00\x12]\n\x15\x65xternal_notification\x18\x03 \x01(\x0b\x32<.meshtastic.protobuf.ModuleConfig.ExternalNotificationConfigH\x00\x12M\n\rstore_forward\x18\x04 \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.StoreForwardConfigH\x00\x12G\n\nrange_test\x18\x05 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.RangeTestConfigH\x00\x12\x46\n\ttelemetry\x18\x06 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.TelemetryConfigH\x00\x12O\n\x0e\x63\x61nned_message\x18\x07 \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.CannedMessageConfigH\x00\x12>\n\x05\x61udio\x18\x08 \x01(\x0b\x32-.meshtastic.protobuf.ModuleConfig.AudioConfigH\x00\x12Q\n\x0fremote_hardware\x18\t \x01(\x0b\x32\x36.meshtastic.protobuf.ModuleConfig.RemoteHardwareConfigH\x00\x12M\n\rneighbor_info\x18\n \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.NeighborInfoConfigH\x00\x12S\n\x10\x61mbient_lighting\x18\x0b \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.AmbientLightingConfigH\x00\x12S\n\x10\x64\x65tection_sensor\x18\x0c \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.DetectionSensorConfigH\x00\x12H\n\npaxcounter\x18\r \x01(\x0b\x32\x32.meshtastic.protobuf.ModuleConfig.PaxcounterConfigH\x00\x12N\n\rstatusmessage\x18\x0e \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.StatusMessageConfigH\x00\x1a\xb9\x02\n\nMQTTConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0f\n\x07\x61\x64\x64ress\x18\x02 \x01(\t\x12\x10\n\x08username\x18\x03 \x01(\t\x12\x10\n\x08password\x18\x04 \x01(\t\x12\x1a\n\x12\x65ncryption_enabled\x18\x05 \x01(\x08\x12\x14\n\x0cjson_enabled\x18\x06 \x01(\x08\x12\x13\n\x0btls_enabled\x18\x07 \x01(\x08\x12\x0c\n\x04root\x18\x08 \x01(\t\x12\x1f\n\x17proxy_to_client_enabled\x18\t \x01(\x08\x12\x1d\n\x15map_reporting_enabled\x18\n \x01(\x08\x12P\n\x13map_report_settings\x18\x0b \x01(\x0b\x32\x33.meshtastic.protobuf.ModuleConfig.MapReportSettings\x1an\n\x11MapReportSettings\x12\x1d\n\x15publish_interval_secs\x18\x01 \x01(\r\x12\x1a\n\x12position_precision\x18\x02 \x01(\r\x12\x1e\n\x16should_report_location\x18\x03 \x01(\x08\x1a\x8b\x01\n\x14RemoteHardwareConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\"\n\x1a\x61llow_undefined_pin_access\x18\x02 \x01(\x08\x12>\n\x0e\x61vailable_pins\x18\x03 \x03(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\x1aZ\n\x12NeighborInfoConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x17\n\x0fupdate_interval\x18\x02 \x01(\r\x12\x1a\n\x12transmit_over_lora\x18\x03 \x01(\x08\x1a\xa0\x03\n\x15\x44\x65tectionSensorConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x1e\n\x16minimum_broadcast_secs\x18\x02 \x01(\r\x12\x1c\n\x14state_broadcast_secs\x18\x03 \x01(\r\x12\x11\n\tsend_bell\x18\x04 \x01(\x08\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\x13\n\x0bmonitor_pin\x18\x06 \x01(\r\x12\x63\n\x16\x64\x65tection_trigger_type\x18\x07 \x01(\x0e\x32\x43.meshtastic.protobuf.ModuleConfig.DetectionSensorConfig.TriggerType\x12\x12\n\nuse_pullup\x18\x08 \x01(\x08\"\x88\x01\n\x0bTriggerType\x12\r\n\tLOGIC_LOW\x10\x00\x12\x0e\n\nLOGIC_HIGH\x10\x01\x12\x10\n\x0c\x46\x41LLING_EDGE\x10\x02\x12\x0f\n\x0bRISING_EDGE\x10\x03\x12\x1a\n\x16\x45ITHER_EDGE_ACTIVE_LOW\x10\x04\x12\x1b\n\x17\x45ITHER_EDGE_ACTIVE_HIGH\x10\x05\x1a\xed\x02\n\x0b\x41udioConfig\x12\x16\n\x0e\x63odec2_enabled\x18\x01 \x01(\x08\x12\x0f\n\x07ptt_pin\x18\x02 \x01(\r\x12I\n\x07\x62itrate\x18\x03 \x01(\x0e\x32\x38.meshtastic.protobuf.ModuleConfig.AudioConfig.Audio_Baud\x12\x0e\n\x06i2s_ws\x18\x04 \x01(\r\x12\x0e\n\x06i2s_sd\x18\x05 \x01(\r\x12\x0f\n\x07i2s_din\x18\x06 \x01(\r\x12\x0f\n\x07i2s_sck\x18\x07 \x01(\r\"\xa7\x01\n\nAudio_Baud\x12\x12\n\x0e\x43ODEC2_DEFAULT\x10\x00\x12\x0f\n\x0b\x43ODEC2_3200\x10\x01\x12\x0f\n\x0b\x43ODEC2_2400\x10\x02\x12\x0f\n\x0b\x43ODEC2_1600\x10\x03\x12\x0f\n\x0b\x43ODEC2_1400\x10\x04\x12\x0f\n\x0b\x43ODEC2_1300\x10\x05\x12\x0f\n\x0b\x43ODEC2_1200\x10\x06\x12\x0e\n\nCODEC2_700\x10\x07\x12\x0f\n\x0b\x43ODEC2_700B\x10\x08\x1av\n\x10PaxcounterConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\"\n\x1apaxcounter_update_interval\x18\x02 \x01(\r\x12\x16\n\x0ewifi_threshold\x18\x03 \x01(\x05\x12\x15\n\rble_threshold\x18\x04 \x01(\x05\x1a\xb5\x05\n\x0cSerialConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0c\n\x04\x65\x63ho\x18\x02 \x01(\x08\x12\x0b\n\x03rxd\x18\x03 \x01(\r\x12\x0b\n\x03txd\x18\x04 \x01(\r\x12H\n\x04\x62\x61ud\x18\x05 \x01(\x0e\x32:.meshtastic.protobuf.ModuleConfig.SerialConfig.Serial_Baud\x12\x0f\n\x07timeout\x18\x06 \x01(\r\x12H\n\x04mode\x18\x07 \x01(\x0e\x32:.meshtastic.protobuf.ModuleConfig.SerialConfig.Serial_Mode\x12$\n\x1coverride_console_serial_port\x18\x08 \x01(\x08\"\x8a\x02\n\x0bSerial_Baud\x12\x10\n\x0c\x42\x41UD_DEFAULT\x10\x00\x12\x0c\n\x08\x42\x41UD_110\x10\x01\x12\x0c\n\x08\x42\x41UD_300\x10\x02\x12\x0c\n\x08\x42\x41UD_600\x10\x03\x12\r\n\tBAUD_1200\x10\x04\x12\r\n\tBAUD_2400\x10\x05\x12\r\n\tBAUD_4800\x10\x06\x12\r\n\tBAUD_9600\x10\x07\x12\x0e\n\nBAUD_19200\x10\x08\x12\x0e\n\nBAUD_38400\x10\t\x12\x0e\n\nBAUD_57600\x10\n\x12\x0f\n\x0b\x42\x41UD_115200\x10\x0b\x12\x0f\n\x0b\x42\x41UD_230400\x10\x0c\x12\x0f\n\x0b\x42\x41UD_460800\x10\r\x12\x0f\n\x0b\x42\x41UD_576000\x10\x0e\x12\x0f\n\x0b\x42\x41UD_921600\x10\x0f\"\x93\x01\n\x0bSerial_Mode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\n\n\x06SIMPLE\x10\x01\x12\t\n\x05PROTO\x10\x02\x12\x0b\n\x07TEXTMSG\x10\x03\x12\x08\n\x04NMEA\x10\x04\x12\x0b\n\x07\x43\x41LTOPO\x10\x05\x12\x08\n\x04WS85\x10\x06\x12\r\n\tVE_DIRECT\x10\x07\x12\r\n\tMS_CONFIG\x10\x08\x12\x07\n\x03LOG\x10\t\x12\x0b\n\x07LOGTEXT\x10\n\x1a\xe9\x02\n\x1a\x45xternalNotificationConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x11\n\toutput_ms\x18\x02 \x01(\r\x12\x0e\n\x06output\x18\x03 \x01(\r\x12\x14\n\x0coutput_vibra\x18\x08 \x01(\r\x12\x15\n\routput_buzzer\x18\t \x01(\r\x12\x0e\n\x06\x61\x63tive\x18\x04 \x01(\x08\x12\x15\n\ralert_message\x18\x05 \x01(\x08\x12\x1b\n\x13\x61lert_message_vibra\x18\n \x01(\x08\x12\x1c\n\x14\x61lert_message_buzzer\x18\x0b \x01(\x08\x12\x12\n\nalert_bell\x18\x06 \x01(\x08\x12\x18\n\x10\x61lert_bell_vibra\x18\x0c \x01(\x08\x12\x19\n\x11\x61lert_bell_buzzer\x18\r \x01(\x08\x12\x0f\n\x07use_pwm\x18\x07 \x01(\x08\x12\x13\n\x0bnag_timeout\x18\x0e \x01(\r\x12\x19\n\x11use_i2s_as_buzzer\x18\x0f \x01(\x08\x1a\x97\x01\n\x12StoreForwardConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x11\n\theartbeat\x18\x02 \x01(\x08\x12\x0f\n\x07records\x18\x03 \x01(\r\x12\x1a\n\x12history_return_max\x18\x04 \x01(\r\x12\x1d\n\x15history_return_window\x18\x05 \x01(\r\x12\x11\n\tis_server\x18\x06 \x01(\x08\x1aY\n\x0fRangeTestConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0e\n\x06sender\x18\x02 \x01(\r\x12\x0c\n\x04save\x18\x03 \x01(\x08\x12\x17\n\x0f\x63lear_on_reboot\x18\x04 \x01(\x08\x1a\x8f\x04\n\x0fTelemetryConfig\x12\x1e\n\x16\x64\x65vice_update_interval\x18\x01 \x01(\r\x12#\n\x1b\x65nvironment_update_interval\x18\x02 \x01(\r\x12\'\n\x1f\x65nvironment_measurement_enabled\x18\x03 \x01(\x08\x12\"\n\x1a\x65nvironment_screen_enabled\x18\x04 \x01(\x08\x12&\n\x1e\x65nvironment_display_fahrenheit\x18\x05 \x01(\x08\x12\x1b\n\x13\x61ir_quality_enabled\x18\x06 \x01(\x08\x12\x1c\n\x14\x61ir_quality_interval\x18\x07 \x01(\r\x12!\n\x19power_measurement_enabled\x18\x08 \x01(\x08\x12\x1d\n\x15power_update_interval\x18\t \x01(\r\x12\x1c\n\x14power_screen_enabled\x18\n \x01(\x08\x12\"\n\x1ahealth_measurement_enabled\x18\x0b \x01(\x08\x12\x1e\n\x16health_update_interval\x18\x0c \x01(\r\x12\x1d\n\x15health_screen_enabled\x18\r \x01(\x08\x12 \n\x18\x64\x65vice_telemetry_enabled\x18\x0e \x01(\x08\x12\"\n\x1a\x61ir_quality_screen_enabled\x18\x0f \x01(\x08\x1a\xf9\x04\n\x13\x43\x61nnedMessageConfig\x12\x17\n\x0frotary1_enabled\x18\x01 \x01(\x08\x12\x19\n\x11inputbroker_pin_a\x18\x02 \x01(\r\x12\x19\n\x11inputbroker_pin_b\x18\x03 \x01(\r\x12\x1d\n\x15inputbroker_pin_press\x18\x04 \x01(\r\x12\x62\n\x14inputbroker_event_cw\x18\x05 \x01(\x0e\x32\x44.meshtastic.protobuf.ModuleConfig.CannedMessageConfig.InputEventChar\x12\x63\n\x15inputbroker_event_ccw\x18\x06 \x01(\x0e\x32\x44.meshtastic.protobuf.ModuleConfig.CannedMessageConfig.InputEventChar\x12\x65\n\x17inputbroker_event_press\x18\x07 \x01(\x0e\x32\x44.meshtastic.protobuf.ModuleConfig.CannedMessageConfig.InputEventChar\x12\x17\n\x0fupdown1_enabled\x18\x08 \x01(\x08\x12\x13\n\x07\x65nabled\x18\t \x01(\x08\x42\x02\x18\x01\x12\x1e\n\x12\x61llow_input_source\x18\n \x01(\tB\x02\x18\x01\x12\x11\n\tsend_bell\x18\x0b \x01(\x08\"c\n\x0eInputEventChar\x12\x08\n\x04NONE\x10\x00\x12\x06\n\x02UP\x10\x11\x12\x08\n\x04\x44OWN\x10\x12\x12\x08\n\x04LEFT\x10\x13\x12\t\n\x05RIGHT\x10\x14\x12\n\n\x06SELECT\x10\n\x12\x08\n\x04\x42\x41\x43K\x10\x1b\x12\n\n\x06\x43\x41NCEL\x10\x18\x1a\x65\n\x15\x41mbientLightingConfig\x12\x11\n\tled_state\x18\x01 \x01(\x08\x12\x0f\n\x07\x63urrent\x18\x02 \x01(\r\x12\x0b\n\x03red\x18\x03 \x01(\r\x12\r\n\x05green\x18\x04 \x01(\r\x12\x0c\n\x04\x62lue\x18\x05 \x01(\r\x1a*\n\x13StatusMessageConfig\x12\x13\n\x0bnode_status\x18\x01 \x01(\tB\x11\n\x0fpayload_variant\"m\n\x11RemoteHardwarePin\x12\x10\n\x08gpio_pin\x18\x01 \x01(\r\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x38\n\x04type\x18\x03 \x01(\x0e\x32*.meshtastic.protobuf.RemoteHardwarePinType*I\n\x15RemoteHardwarePinType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x10\n\x0c\x44IGITAL_READ\x10\x01\x12\x11\n\rDIGITAL_WRITE\x10\x02\x42h\n\x14org.meshtastic.protoB\x12ModuleConfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\'meshtastic/protobuf/module_config.proto\x12\x13meshtastic.protobuf\x1a\x1emeshtastic/protobuf/atak.proto\x1a meshtastic/protobuf/nanopb.proto\"\x9f\x30\n\x0cModuleConfig\x12<\n\x04mqtt\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.ModuleConfig.MQTTConfigH\x00\x12@\n\x06serial\x18\x02 \x01(\x0b\x32..meshtastic.protobuf.ModuleConfig.SerialConfigH\x00\x12]\n\x15\x65xternal_notification\x18\x03 \x01(\x0b\x32<.meshtastic.protobuf.ModuleConfig.ExternalNotificationConfigH\x00\x12M\n\rstore_forward\x18\x04 \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.StoreForwardConfigH\x00\x12G\n\nrange_test\x18\x05 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.RangeTestConfigH\x00\x12\x46\n\ttelemetry\x18\x06 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.TelemetryConfigH\x00\x12O\n\x0e\x63\x61nned_message\x18\x07 \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.CannedMessageConfigH\x00\x12>\n\x05\x61udio\x18\x08 \x01(\x0b\x32-.meshtastic.protobuf.ModuleConfig.AudioConfigH\x00\x12Q\n\x0fremote_hardware\x18\t \x01(\x0b\x32\x36.meshtastic.protobuf.ModuleConfig.RemoteHardwareConfigH\x00\x12M\n\rneighbor_info\x18\n \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.NeighborInfoConfigH\x00\x12S\n\x10\x61mbient_lighting\x18\x0b \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.AmbientLightingConfigH\x00\x12S\n\x10\x64\x65tection_sensor\x18\x0c \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.DetectionSensorConfigH\x00\x12H\n\npaxcounter\x18\r \x01(\x0b\x32\x32.meshtastic.protobuf.ModuleConfig.PaxcounterConfigH\x00\x12N\n\rstatusmessage\x18\x0e \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.StatusMessageConfigH\x00\x12W\n\x12traffic_management\x18\x0f \x01(\x0b\x32\x39.meshtastic.protobuf.ModuleConfig.TrafficManagementConfigH\x00\x12:\n\x03tak\x18\x10 \x01(\x0b\x32+.meshtastic.protobuf.ModuleConfig.TAKConfigH\x00\x1a\xd9\x02\n\nMQTTConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x16\n\x07\x61\x64\x64ress\x18\x02 \x01(\tB\x05\x92?\x02\x08@\x12\x17\n\x08username\x18\x03 \x01(\tB\x05\x92?\x02\x08@\x12\x17\n\x08password\x18\x04 \x01(\tB\x05\x92?\x02\x08 \x12\x1a\n\x12\x65ncryption_enabled\x18\x05 \x01(\x08\x12\x18\n\x0cjson_enabled\x18\x06 \x01(\x08\x42\x02\x18\x01\x12\x13\n\x0btls_enabled\x18\x07 \x01(\x08\x12\x13\n\x04root\x18\x08 \x01(\tB\x05\x92?\x02\x08 \x12\x1f\n\x17proxy_to_client_enabled\x18\t \x01(\x08\x12\x1d\n\x15map_reporting_enabled\x18\n \x01(\x08\x12P\n\x13map_report_settings\x18\x0b \x01(\x0b\x32\x33.meshtastic.protobuf.ModuleConfig.MapReportSettings\x1an\n\x11MapReportSettings\x12\x1d\n\x15publish_interval_secs\x18\x01 \x01(\r\x12\x1a\n\x12position_precision\x18\x02 \x01(\r\x12\x1e\n\x16should_report_location\x18\x03 \x01(\x08\x1a\x92\x01\n\x14RemoteHardwareConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\"\n\x1a\x61llow_undefined_pin_access\x18\x02 \x01(\x08\x12\x45\n\x0e\x61vailable_pins\x18\x03 \x03(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePinB\x05\x92?\x02\x10\x04\x1aZ\n\x12NeighborInfoConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x17\n\x0fupdate_interval\x18\x02 \x01(\r\x12\x1a\n\x12transmit_over_lora\x18\x03 \x01(\x08\x1a\xb5\x03\n\x15\x44\x65tectionSensorConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x1e\n\x16minimum_broadcast_secs\x18\x02 \x01(\r\x12\x1c\n\x14state_broadcast_secs\x18\x03 \x01(\r\x12\x11\n\tsend_bell\x18\x04 \x01(\x08\x12\x13\n\x04name\x18\x05 \x01(\tB\x05\x92?\x02\x08\x14\x12\x1a\n\x0bmonitor_pin\x18\x06 \x01(\rB\x05\x92?\x02\x38\x08\x12j\n\x16\x64\x65tection_trigger_type\x18\x07 \x01(\x0e\x32\x43.meshtastic.protobuf.ModuleConfig.DetectionSensorConfig.TriggerTypeB\x05\x92?\x02\x08\x08\x12\x12\n\nuse_pullup\x18\x08 \x01(\x08\"\x88\x01\n\x0bTriggerType\x12\r\n\tLOGIC_LOW\x10\x00\x12\x0e\n\nLOGIC_HIGH\x10\x01\x12\x10\n\x0c\x46\x41LLING_EDGE\x10\x02\x12\x0f\n\x0bRISING_EDGE\x10\x03\x12\x1a\n\x16\x45ITHER_EDGE_ACTIVE_LOW\x10\x04\x12\x1b\n\x17\x45ITHER_EDGE_ACTIVE_HIGH\x10\x05\x1a\x90\x03\n\x0b\x41udioConfig\x12\x16\n\x0e\x63odec2_enabled\x18\x01 \x01(\x08\x12\x16\n\x07ptt_pin\x18\x02 \x01(\rB\x05\x92?\x02\x38\x08\x12I\n\x07\x62itrate\x18\x03 \x01(\x0e\x32\x38.meshtastic.protobuf.ModuleConfig.AudioConfig.Audio_Baud\x12\x15\n\x06i2s_ws\x18\x04 \x01(\rB\x05\x92?\x02\x38\x08\x12\x15\n\x06i2s_sd\x18\x05 \x01(\rB\x05\x92?\x02\x38\x08\x12\x16\n\x07i2s_din\x18\x06 \x01(\rB\x05\x92?\x02\x38\x08\x12\x16\n\x07i2s_sck\x18\x07 \x01(\rB\x05\x92?\x02\x38\x08\"\xa7\x01\n\nAudio_Baud\x12\x12\n\x0e\x43ODEC2_DEFAULT\x10\x00\x12\x0f\n\x0b\x43ODEC2_3200\x10\x01\x12\x0f\n\x0b\x43ODEC2_2400\x10\x02\x12\x0f\n\x0b\x43ODEC2_1600\x10\x03\x12\x0f\n\x0b\x43ODEC2_1400\x10\x04\x12\x0f\n\x0b\x43ODEC2_1300\x10\x05\x12\x0f\n\x0b\x43ODEC2_1200\x10\x06\x12\x0e\n\nCODEC2_700\x10\x07\x12\x0f\n\x0b\x43ODEC2_700B\x10\x08\x1av\n\x10PaxcounterConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\"\n\x1apaxcounter_update_interval\x18\x02 \x01(\r\x12\x16\n\x0ewifi_threshold\x18\x03 \x01(\x05\x12\x15\n\rble_threshold\x18\x04 \x01(\x05\x1a\xd3\x03\n\x17TrafficManagementConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x1e\n\x16position_dedup_enabled\x18\x02 \x01(\x08\x12\x1f\n\x17position_precision_bits\x18\x03 \x01(\r\x12\"\n\x1aposition_min_interval_secs\x18\x04 \x01(\r\x12 \n\x18nodeinfo_direct_response\x18\x05 \x01(\x08\x12)\n!nodeinfo_direct_response_max_hops\x18\x06 \x01(\r\x12\x1a\n\x12rate_limit_enabled\x18\x07 \x01(\x08\x12\x1e\n\x16rate_limit_window_secs\x18\x08 \x01(\r\x12\x1e\n\x16rate_limit_max_packets\x18\t \x01(\r\x12\x1c\n\x14\x64rop_unknown_enabled\x18\n \x01(\x08\x12 \n\x18unknown_packet_threshold\x18\x0b \x01(\r\x12\x1d\n\x15\x65xhaust_hop_telemetry\x18\x0c \x01(\x08\x12\x1c\n\x14\x65xhaust_hop_position\x18\r \x01(\x08\x12\x1c\n\x14router_preserve_hops\x18\x0e \x01(\x08\x1a\xb5\x05\n\x0cSerialConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0c\n\x04\x65\x63ho\x18\x02 \x01(\x08\x12\x0b\n\x03rxd\x18\x03 \x01(\r\x12\x0b\n\x03txd\x18\x04 \x01(\r\x12H\n\x04\x62\x61ud\x18\x05 \x01(\x0e\x32:.meshtastic.protobuf.ModuleConfig.SerialConfig.Serial_Baud\x12\x0f\n\x07timeout\x18\x06 \x01(\r\x12H\n\x04mode\x18\x07 \x01(\x0e\x32:.meshtastic.protobuf.ModuleConfig.SerialConfig.Serial_Mode\x12$\n\x1coverride_console_serial_port\x18\x08 \x01(\x08\"\x8a\x02\n\x0bSerial_Baud\x12\x10\n\x0c\x42\x41UD_DEFAULT\x10\x00\x12\x0c\n\x08\x42\x41UD_110\x10\x01\x12\x0c\n\x08\x42\x41UD_300\x10\x02\x12\x0c\n\x08\x42\x41UD_600\x10\x03\x12\r\n\tBAUD_1200\x10\x04\x12\r\n\tBAUD_2400\x10\x05\x12\r\n\tBAUD_4800\x10\x06\x12\r\n\tBAUD_9600\x10\x07\x12\x0e\n\nBAUD_19200\x10\x08\x12\x0e\n\nBAUD_38400\x10\t\x12\x0e\n\nBAUD_57600\x10\n\x12\x0f\n\x0b\x42\x41UD_115200\x10\x0b\x12\x0f\n\x0b\x42\x41UD_230400\x10\x0c\x12\x0f\n\x0b\x42\x41UD_460800\x10\r\x12\x0f\n\x0b\x42\x41UD_576000\x10\x0e\x12\x0f\n\x0b\x42\x41UD_921600\x10\x0f\"\x93\x01\n\x0bSerial_Mode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\n\n\x06SIMPLE\x10\x01\x12\t\n\x05PROTO\x10\x02\x12\x0b\n\x07TEXTMSG\x10\x03\x12\x08\n\x04NMEA\x10\x04\x12\x0b\n\x07\x43\x41LTOPO\x10\x05\x12\x08\n\x04WS85\x10\x06\x12\r\n\tVE_DIRECT\x10\x07\x12\r\n\tMS_CONFIG\x10\x08\x12\x07\n\x03LOG\x10\t\x12\x0b\n\x07LOGTEXT\x10\n\x1a\xfe\x02\n\x1a\x45xternalNotificationConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x11\n\toutput_ms\x18\x02 \x01(\r\x12\x0e\n\x06output\x18\x03 \x01(\r\x12\x1b\n\x0coutput_vibra\x18\x08 \x01(\rB\x05\x92?\x02\x38\x08\x12\x1c\n\routput_buzzer\x18\t \x01(\rB\x05\x92?\x02\x38\x08\x12\x0e\n\x06\x61\x63tive\x18\x04 \x01(\x08\x12\x15\n\ralert_message\x18\x05 \x01(\x08\x12\x1b\n\x13\x61lert_message_vibra\x18\n \x01(\x08\x12\x1c\n\x14\x61lert_message_buzzer\x18\x0b \x01(\x08\x12\x12\n\nalert_bell\x18\x06 \x01(\x08\x12\x18\n\x10\x61lert_bell_vibra\x18\x0c \x01(\x08\x12\x19\n\x11\x61lert_bell_buzzer\x18\r \x01(\x08\x12\x0f\n\x07use_pwm\x18\x07 \x01(\x08\x12\x1a\n\x0bnag_timeout\x18\x0e \x01(\rB\x05\x92?\x02\x38\x10\x12\x19\n\x11use_i2s_as_buzzer\x18\x0f \x01(\x08\x1a\x97\x01\n\x12StoreForwardConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x11\n\theartbeat\x18\x02 \x01(\x08\x12\x0f\n\x07records\x18\x03 \x01(\r\x12\x1a\n\x12history_return_max\x18\x04 \x01(\r\x12\x1d\n\x15history_return_window\x18\x05 \x01(\r\x12\x11\n\tis_server\x18\x06 \x01(\x08\x1aY\n\x0fRangeTestConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0e\n\x06sender\x18\x02 \x01(\r\x12\x0c\n\x04save\x18\x03 \x01(\x08\x12\x17\n\x0f\x63lear_on_reboot\x18\x04 \x01(\x08\x1a\x8f\x04\n\x0fTelemetryConfig\x12\x1e\n\x16\x64\x65vice_update_interval\x18\x01 \x01(\r\x12#\n\x1b\x65nvironment_update_interval\x18\x02 \x01(\r\x12\'\n\x1f\x65nvironment_measurement_enabled\x18\x03 \x01(\x08\x12\"\n\x1a\x65nvironment_screen_enabled\x18\x04 \x01(\x08\x12&\n\x1e\x65nvironment_display_fahrenheit\x18\x05 \x01(\x08\x12\x1b\n\x13\x61ir_quality_enabled\x18\x06 \x01(\x08\x12\x1c\n\x14\x61ir_quality_interval\x18\x07 \x01(\r\x12!\n\x19power_measurement_enabled\x18\x08 \x01(\x08\x12\x1d\n\x15power_update_interval\x18\t \x01(\r\x12\x1c\n\x14power_screen_enabled\x18\n \x01(\x08\x12\"\n\x1ahealth_measurement_enabled\x18\x0b \x01(\x08\x12\x1e\n\x16health_update_interval\x18\x0c \x01(\r\x12\x1d\n\x15health_screen_enabled\x18\r \x01(\x08\x12 \n\x18\x64\x65vice_telemetry_enabled\x18\x0e \x01(\x08\x12\"\n\x1a\x61ir_quality_screen_enabled\x18\x0f \x01(\x08\x1a\xfe\x04\n\x13\x43\x61nnedMessageConfig\x12\x17\n\x0frotary1_enabled\x18\x01 \x01(\x08\x12\x19\n\x11inputbroker_pin_a\x18\x02 \x01(\r\x12\x19\n\x11inputbroker_pin_b\x18\x03 \x01(\r\x12\x1d\n\x15inputbroker_pin_press\x18\x04 \x01(\r\x12\x62\n\x14inputbroker_event_cw\x18\x05 \x01(\x0e\x32\x44.meshtastic.protobuf.ModuleConfig.CannedMessageConfig.InputEventChar\x12\x63\n\x15inputbroker_event_ccw\x18\x06 \x01(\x0e\x32\x44.meshtastic.protobuf.ModuleConfig.CannedMessageConfig.InputEventChar\x12\x65\n\x17inputbroker_event_press\x18\x07 \x01(\x0e\x32\x44.meshtastic.protobuf.ModuleConfig.CannedMessageConfig.InputEventChar\x12\x17\n\x0fupdown1_enabled\x18\x08 \x01(\x08\x12\x13\n\x07\x65nabled\x18\t \x01(\x08\x42\x02\x18\x01\x12#\n\x12\x61llow_input_source\x18\n \x01(\tB\x07\x18\x01\x92?\x02\x08\x10\x12\x11\n\tsend_bell\x18\x0b \x01(\x08\"c\n\x0eInputEventChar\x12\x08\n\x04NONE\x10\x00\x12\x06\n\x02UP\x10\x11\x12\x08\n\x04\x44OWN\x10\x12\x12\x08\n\x04LEFT\x10\x13\x12\t\n\x05RIGHT\x10\x14\x12\n\n\x06SELECT\x10\n\x12\x08\n\x04\x42\x41\x43K\x10\x1b\x12\n\n\x06\x43\x41NCEL\x10\x18\x1a\x81\x01\n\x15\x41mbientLightingConfig\x12\x11\n\tled_state\x18\x01 \x01(\x08\x12\x16\n\x07\x63urrent\x18\x02 \x01(\rB\x05\x92?\x02\x38\x08\x12\x12\n\x03red\x18\x03 \x01(\rB\x05\x92?\x02\x38\x08\x12\x14\n\x05green\x18\x04 \x01(\rB\x05\x92?\x02\x38\x08\x12\x13\n\x04\x62lue\x18\x05 \x01(\rB\x05\x92?\x02\x38\x08\x1a\x31\n\x13StatusMessageConfig\x12\x1a\n\x0bnode_status\x18\x01 \x01(\tB\x05\x92?\x02\x08P\x1a\x63\n\tTAKConfig\x12\'\n\x04team\x18\x01 \x01(\x0e\x32\x19.meshtastic.protobuf.Team\x12-\n\x04role\x18\x02 \x01(\x0e\x32\x1f.meshtastic.protobuf.MemberRoleB\x11\n\x0fpayload_variant\"{\n\x11RemoteHardwarePin\x12\x17\n\x08gpio_pin\x18\x01 \x01(\rB\x05\x92?\x02\x38\x08\x12\x13\n\x04name\x18\x02 \x01(\tB\x05\x92?\x02\x08\x0f\x12\x38\n\x04type\x18\x03 \x01(\x0e\x32*.meshtastic.protobuf.RemoteHardwarePinType*I\n\x15RemoteHardwarePinType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x10\n\x0c\x44IGITAL_READ\x10\x01\x12\x11\n\rDIGITAL_WRITE\x10\x02\x42h\n\x14org.meshtastic.protoB\x12ModuleConfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -21,54 +23,106 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.module_ if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\022ModuleConfigProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' + _MODULECONFIG_MQTTCONFIG.fields_by_name['address']._options = None + _MODULECONFIG_MQTTCONFIG.fields_by_name['address']._serialized_options = b'\222?\002\010@' + _MODULECONFIG_MQTTCONFIG.fields_by_name['username']._options = None + _MODULECONFIG_MQTTCONFIG.fields_by_name['username']._serialized_options = b'\222?\002\010@' + _MODULECONFIG_MQTTCONFIG.fields_by_name['password']._options = None + _MODULECONFIG_MQTTCONFIG.fields_by_name['password']._serialized_options = b'\222?\002\010 ' + _MODULECONFIG_MQTTCONFIG.fields_by_name['json_enabled']._options = None + _MODULECONFIG_MQTTCONFIG.fields_by_name['json_enabled']._serialized_options = b'\030\001' + _MODULECONFIG_MQTTCONFIG.fields_by_name['root']._options = None + _MODULECONFIG_MQTTCONFIG.fields_by_name['root']._serialized_options = b'\222?\002\010 ' + _MODULECONFIG_REMOTEHARDWARECONFIG.fields_by_name['available_pins']._options = None + _MODULECONFIG_REMOTEHARDWARECONFIG.fields_by_name['available_pins']._serialized_options = b'\222?\002\020\004' + _MODULECONFIG_DETECTIONSENSORCONFIG.fields_by_name['name']._options = None + _MODULECONFIG_DETECTIONSENSORCONFIG.fields_by_name['name']._serialized_options = b'\222?\002\010\024' + _MODULECONFIG_DETECTIONSENSORCONFIG.fields_by_name['monitor_pin']._options = None + _MODULECONFIG_DETECTIONSENSORCONFIG.fields_by_name['monitor_pin']._serialized_options = b'\222?\0028\010' + _MODULECONFIG_DETECTIONSENSORCONFIG.fields_by_name['detection_trigger_type']._options = None + _MODULECONFIG_DETECTIONSENSORCONFIG.fields_by_name['detection_trigger_type']._serialized_options = b'\222?\002\010\010' + _MODULECONFIG_AUDIOCONFIG.fields_by_name['ptt_pin']._options = None + _MODULECONFIG_AUDIOCONFIG.fields_by_name['ptt_pin']._serialized_options = b'\222?\0028\010' + _MODULECONFIG_AUDIOCONFIG.fields_by_name['i2s_ws']._options = None + _MODULECONFIG_AUDIOCONFIG.fields_by_name['i2s_ws']._serialized_options = b'\222?\0028\010' + _MODULECONFIG_AUDIOCONFIG.fields_by_name['i2s_sd']._options = None + _MODULECONFIG_AUDIOCONFIG.fields_by_name['i2s_sd']._serialized_options = b'\222?\0028\010' + _MODULECONFIG_AUDIOCONFIG.fields_by_name['i2s_din']._options = None + _MODULECONFIG_AUDIOCONFIG.fields_by_name['i2s_din']._serialized_options = b'\222?\0028\010' + _MODULECONFIG_AUDIOCONFIG.fields_by_name['i2s_sck']._options = None + _MODULECONFIG_AUDIOCONFIG.fields_by_name['i2s_sck']._serialized_options = b'\222?\0028\010' + _MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['output_vibra']._options = None + _MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['output_vibra']._serialized_options = b'\222?\0028\010' + _MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['output_buzzer']._options = None + _MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['output_buzzer']._serialized_options = b'\222?\0028\010' + _MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['nag_timeout']._options = None + _MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['nag_timeout']._serialized_options = b'\222?\0028\020' _MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['enabled']._options = None _MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['enabled']._serialized_options = b'\030\001' _MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['allow_input_source']._options = None - _MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['allow_input_source']._serialized_options = b'\030\001' - _globals['_REMOTEHARDWAREPINTYPE']._serialized_start=5476 - _globals['_REMOTEHARDWAREPINTYPE']._serialized_end=5549 - _globals['_MODULECONFIG']._serialized_start=65 - _globals['_MODULECONFIG']._serialized_end=5363 - _globals['_MODULECONFIG_MQTTCONFIG']._serialized_start=1160 - _globals['_MODULECONFIG_MQTTCONFIG']._serialized_end=1473 - _globals['_MODULECONFIG_MAPREPORTSETTINGS']._serialized_start=1475 - _globals['_MODULECONFIG_MAPREPORTSETTINGS']._serialized_end=1585 - _globals['_MODULECONFIG_REMOTEHARDWARECONFIG']._serialized_start=1588 - _globals['_MODULECONFIG_REMOTEHARDWARECONFIG']._serialized_end=1727 - _globals['_MODULECONFIG_NEIGHBORINFOCONFIG']._serialized_start=1729 - _globals['_MODULECONFIG_NEIGHBORINFOCONFIG']._serialized_end=1819 - _globals['_MODULECONFIG_DETECTIONSENSORCONFIG']._serialized_start=1822 - _globals['_MODULECONFIG_DETECTIONSENSORCONFIG']._serialized_end=2238 - _globals['_MODULECONFIG_DETECTIONSENSORCONFIG_TRIGGERTYPE']._serialized_start=2102 - _globals['_MODULECONFIG_DETECTIONSENSORCONFIG_TRIGGERTYPE']._serialized_end=2238 - _globals['_MODULECONFIG_AUDIOCONFIG']._serialized_start=2241 - _globals['_MODULECONFIG_AUDIOCONFIG']._serialized_end=2606 - _globals['_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD']._serialized_start=2439 - _globals['_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD']._serialized_end=2606 - _globals['_MODULECONFIG_PAXCOUNTERCONFIG']._serialized_start=2608 - _globals['_MODULECONFIG_PAXCOUNTERCONFIG']._serialized_end=2726 - _globals['_MODULECONFIG_SERIALCONFIG']._serialized_start=2729 - _globals['_MODULECONFIG_SERIALCONFIG']._serialized_end=3422 - _globals['_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD']._serialized_start=3006 - _globals['_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD']._serialized_end=3272 - _globals['_MODULECONFIG_SERIALCONFIG_SERIAL_MODE']._serialized_start=3275 - _globals['_MODULECONFIG_SERIALCONFIG_SERIAL_MODE']._serialized_end=3422 - _globals['_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG']._serialized_start=3425 - _globals['_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG']._serialized_end=3786 - _globals['_MODULECONFIG_STOREFORWARDCONFIG']._serialized_start=3789 - _globals['_MODULECONFIG_STOREFORWARDCONFIG']._serialized_end=3940 - _globals['_MODULECONFIG_RANGETESTCONFIG']._serialized_start=3942 - _globals['_MODULECONFIG_RANGETESTCONFIG']._serialized_end=4031 - _globals['_MODULECONFIG_TELEMETRYCONFIG']._serialized_start=4034 - _globals['_MODULECONFIG_TELEMETRYCONFIG']._serialized_end=4561 - _globals['_MODULECONFIG_CANNEDMESSAGECONFIG']._serialized_start=4564 - _globals['_MODULECONFIG_CANNEDMESSAGECONFIG']._serialized_end=5197 - _globals['_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR']._serialized_start=5098 - _globals['_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR']._serialized_end=5197 - _globals['_MODULECONFIG_AMBIENTLIGHTINGCONFIG']._serialized_start=5199 - _globals['_MODULECONFIG_AMBIENTLIGHTINGCONFIG']._serialized_end=5300 - _globals['_MODULECONFIG_STATUSMESSAGECONFIG']._serialized_start=5302 - _globals['_MODULECONFIG_STATUSMESSAGECONFIG']._serialized_end=5344 - _globals['_REMOTEHARDWAREPIN']._serialized_start=5365 - _globals['_REMOTEHARDWAREPIN']._serialized_end=5474 + _MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['allow_input_source']._serialized_options = b'\030\001\222?\002\010\020' + _MODULECONFIG_AMBIENTLIGHTINGCONFIG.fields_by_name['current']._options = None + _MODULECONFIG_AMBIENTLIGHTINGCONFIG.fields_by_name['current']._serialized_options = b'\222?\0028\010' + _MODULECONFIG_AMBIENTLIGHTINGCONFIG.fields_by_name['red']._options = None + _MODULECONFIG_AMBIENTLIGHTINGCONFIG.fields_by_name['red']._serialized_options = b'\222?\0028\010' + _MODULECONFIG_AMBIENTLIGHTINGCONFIG.fields_by_name['green']._options = None + _MODULECONFIG_AMBIENTLIGHTINGCONFIG.fields_by_name['green']._serialized_options = b'\222?\0028\010' + _MODULECONFIG_AMBIENTLIGHTINGCONFIG.fields_by_name['blue']._options = None + _MODULECONFIG_AMBIENTLIGHTINGCONFIG.fields_by_name['blue']._serialized_options = b'\222?\0028\010' + _MODULECONFIG_STATUSMESSAGECONFIG.fields_by_name['node_status']._options = None + _MODULECONFIG_STATUSMESSAGECONFIG.fields_by_name['node_status']._serialized_options = b'\222?\002\010P' + _REMOTEHARDWAREPIN.fields_by_name['gpio_pin']._options = None + _REMOTEHARDWAREPIN.fields_by_name['gpio_pin']._serialized_options = b'\222?\0028\010' + _REMOTEHARDWAREPIN.fields_by_name['name']._options = None + _REMOTEHARDWAREPIN.fields_by_name['name']._serialized_options = b'\222?\002\010\017' + _globals['_REMOTEHARDWAREPINTYPE']._serialized_start=6433 + _globals['_REMOTEHARDWAREPINTYPE']._serialized_end=6506 + _globals['_MODULECONFIG']._serialized_start=131 + _globals['_MODULECONFIG']._serialized_end=6306 + _globals['_MODULECONFIG_MQTTCONFIG']._serialized_start=1375 + _globals['_MODULECONFIG_MQTTCONFIG']._serialized_end=1720 + _globals['_MODULECONFIG_MAPREPORTSETTINGS']._serialized_start=1722 + _globals['_MODULECONFIG_MAPREPORTSETTINGS']._serialized_end=1832 + _globals['_MODULECONFIG_REMOTEHARDWARECONFIG']._serialized_start=1835 + _globals['_MODULECONFIG_REMOTEHARDWARECONFIG']._serialized_end=1981 + _globals['_MODULECONFIG_NEIGHBORINFOCONFIG']._serialized_start=1983 + _globals['_MODULECONFIG_NEIGHBORINFOCONFIG']._serialized_end=2073 + _globals['_MODULECONFIG_DETECTIONSENSORCONFIG']._serialized_start=2076 + _globals['_MODULECONFIG_DETECTIONSENSORCONFIG']._serialized_end=2513 + _globals['_MODULECONFIG_DETECTIONSENSORCONFIG_TRIGGERTYPE']._serialized_start=2377 + _globals['_MODULECONFIG_DETECTIONSENSORCONFIG_TRIGGERTYPE']._serialized_end=2513 + _globals['_MODULECONFIG_AUDIOCONFIG']._serialized_start=2516 + _globals['_MODULECONFIG_AUDIOCONFIG']._serialized_end=2916 + _globals['_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD']._serialized_start=2749 + _globals['_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD']._serialized_end=2916 + _globals['_MODULECONFIG_PAXCOUNTERCONFIG']._serialized_start=2918 + _globals['_MODULECONFIG_PAXCOUNTERCONFIG']._serialized_end=3036 + _globals['_MODULECONFIG_TRAFFICMANAGEMENTCONFIG']._serialized_start=3039 + _globals['_MODULECONFIG_TRAFFICMANAGEMENTCONFIG']._serialized_end=3506 + _globals['_MODULECONFIG_SERIALCONFIG']._serialized_start=3509 + _globals['_MODULECONFIG_SERIALCONFIG']._serialized_end=4202 + _globals['_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD']._serialized_start=3786 + _globals['_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD']._serialized_end=4052 + _globals['_MODULECONFIG_SERIALCONFIG_SERIAL_MODE']._serialized_start=4055 + _globals['_MODULECONFIG_SERIALCONFIG_SERIAL_MODE']._serialized_end=4202 + _globals['_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG']._serialized_start=4205 + _globals['_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG']._serialized_end=4587 + _globals['_MODULECONFIG_STOREFORWARDCONFIG']._serialized_start=4590 + _globals['_MODULECONFIG_STOREFORWARDCONFIG']._serialized_end=4741 + _globals['_MODULECONFIG_RANGETESTCONFIG']._serialized_start=4743 + _globals['_MODULECONFIG_RANGETESTCONFIG']._serialized_end=4832 + _globals['_MODULECONFIG_TELEMETRYCONFIG']._serialized_start=4835 + _globals['_MODULECONFIG_TELEMETRYCONFIG']._serialized_end=5362 + _globals['_MODULECONFIG_CANNEDMESSAGECONFIG']._serialized_start=5365 + _globals['_MODULECONFIG_CANNEDMESSAGECONFIG']._serialized_end=6003 + _globals['_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR']._serialized_start=5904 + _globals['_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR']._serialized_end=6003 + _globals['_MODULECONFIG_AMBIENTLIGHTINGCONFIG']._serialized_start=6006 + _globals['_MODULECONFIG_AMBIENTLIGHTINGCONFIG']._serialized_end=6135 + _globals['_MODULECONFIG_STATUSMESSAGECONFIG']._serialized_start=6137 + _globals['_MODULECONFIG_STATUSMESSAGECONFIG']._serialized_end=6186 + _globals['_MODULECONFIG_TAKCONFIG']._serialized_start=6188 + _globals['_MODULECONFIG_TAKCONFIG']._serialized_end=6287 + _globals['_REMOTEHARDWAREPIN']._serialized_start=6308 + _globals['_REMOTEHARDWAREPIN']._serialized_end=6431 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/module_config_pb2.pyi b/meshtastic/protobuf/module_config_pb2.pyi index 00062b7..b9d8a5a 100644 --- a/meshtastic/protobuf/module_config_pb2.pyi +++ b/meshtastic/protobuf/module_config_pb2.pyi @@ -9,6 +9,7 @@ import google.protobuf.descriptor import google.protobuf.internal.containers import google.protobuf.internal.enum_type_wrapper import google.protobuf.message +import meshtastic.protobuf.atak_pb2 import sys import typing @@ -112,7 +113,7 @@ class ModuleConfig(google.protobuf.message.Message): """ json_enabled: builtins.bool """ - Whether to send / consume json packets on MQTT + Deprecated: JSON packet support on MQTT was removed, and this field is ignored. """ tls_enabled: builtins.bool """ @@ -492,6 +493,105 @@ class ModuleConfig(google.protobuf.message.Message): ) -> None: ... def ClearField(self, field_name: typing.Literal["ble_threshold", b"ble_threshold", "enabled", b"enabled", "paxcounter_update_interval", b"paxcounter_update_interval", "wifi_threshold", b"wifi_threshold"]) -> None: ... + @typing.final + class TrafficManagementConfig(google.protobuf.message.Message): + """ + Config for the Traffic Management module. + Provides packet inspection and traffic shaping to help reduce channel utilization + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ENABLED_FIELD_NUMBER: builtins.int + POSITION_DEDUP_ENABLED_FIELD_NUMBER: builtins.int + POSITION_PRECISION_BITS_FIELD_NUMBER: builtins.int + POSITION_MIN_INTERVAL_SECS_FIELD_NUMBER: builtins.int + NODEINFO_DIRECT_RESPONSE_FIELD_NUMBER: builtins.int + NODEINFO_DIRECT_RESPONSE_MAX_HOPS_FIELD_NUMBER: builtins.int + RATE_LIMIT_ENABLED_FIELD_NUMBER: builtins.int + RATE_LIMIT_WINDOW_SECS_FIELD_NUMBER: builtins.int + RATE_LIMIT_MAX_PACKETS_FIELD_NUMBER: builtins.int + DROP_UNKNOWN_ENABLED_FIELD_NUMBER: builtins.int + UNKNOWN_PACKET_THRESHOLD_FIELD_NUMBER: builtins.int + EXHAUST_HOP_TELEMETRY_FIELD_NUMBER: builtins.int + EXHAUST_HOP_POSITION_FIELD_NUMBER: builtins.int + ROUTER_PRESERVE_HOPS_FIELD_NUMBER: builtins.int + enabled: builtins.bool + """ + Master enable for traffic management module + """ + position_dedup_enabled: builtins.bool + """ + Enable position deduplication to drop redundant position broadcasts + """ + position_precision_bits: builtins.int + """ + Number of bits of precision for position deduplication (0-32) + """ + position_min_interval_secs: builtins.int + """ + Minimum interval in seconds between position updates from the same node + """ + nodeinfo_direct_response: builtins.bool + """ + Enable direct response to NodeInfo requests from local cache + """ + nodeinfo_direct_response_max_hops: builtins.int + """ + Minimum hop distance from requestor before responding to NodeInfo requests + """ + rate_limit_enabled: builtins.bool + """ + Enable per-node rate limiting to throttle chatty nodes + """ + rate_limit_window_secs: builtins.int + """ + Time window in seconds for rate limiting calculations + """ + rate_limit_max_packets: builtins.int + """ + Maximum packets allowed per node within the rate limit window + """ + drop_unknown_enabled: builtins.bool + """ + Enable dropping of unknown/undecryptable packets per rate_limit_window_secs + """ + unknown_packet_threshold: builtins.int + """ + Number of unknown packets before dropping from a node + """ + exhaust_hop_telemetry: builtins.bool + """ + Set hop_limit to 0 for relayed telemetry broadcasts (own packets unaffected) + """ + exhaust_hop_position: builtins.bool + """ + Set hop_limit to 0 for relayed position broadcasts (own packets unaffected) + """ + router_preserve_hops: builtins.bool + """ + Preserve hop_limit for router-to-router traffic + """ + def __init__( + self, + *, + enabled: builtins.bool = ..., + position_dedup_enabled: builtins.bool = ..., + position_precision_bits: builtins.int = ..., + position_min_interval_secs: builtins.int = ..., + nodeinfo_direct_response: builtins.bool = ..., + nodeinfo_direct_response_max_hops: builtins.int = ..., + rate_limit_enabled: builtins.bool = ..., + rate_limit_window_secs: builtins.int = ..., + rate_limit_max_packets: builtins.int = ..., + drop_unknown_enabled: builtins.bool = ..., + unknown_packet_threshold: builtins.int = ..., + exhaust_hop_telemetry: builtins.bool = ..., + exhaust_hop_position: builtins.bool = ..., + router_preserve_hops: builtins.bool = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["drop_unknown_enabled", b"drop_unknown_enabled", "enabled", b"enabled", "exhaust_hop_position", b"exhaust_hop_position", "exhaust_hop_telemetry", b"exhaust_hop_telemetry", "nodeinfo_direct_response", b"nodeinfo_direct_response", "nodeinfo_direct_response_max_hops", b"nodeinfo_direct_response_max_hops", "position_dedup_enabled", b"position_dedup_enabled", "position_min_interval_secs", b"position_min_interval_secs", "position_precision_bits", b"position_precision_bits", "rate_limit_enabled", b"rate_limit_enabled", "rate_limit_max_packets", b"rate_limit_max_packets", "rate_limit_window_secs", b"rate_limit_window_secs", "router_preserve_hops", b"router_preserve_hops", "unknown_packet_threshold", b"unknown_packet_threshold"]) -> None: ... + @typing.final class SerialConfig(google.protobuf.message.Message): """ @@ -1202,6 +1302,34 @@ class ModuleConfig(google.protobuf.message.Message): ) -> None: ... def ClearField(self, field_name: typing.Literal["node_status", b"node_status"]) -> None: ... + @typing.final + class TAKConfig(google.protobuf.message.Message): + """ + TAK team/role configuration + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TEAM_FIELD_NUMBER: builtins.int + ROLE_FIELD_NUMBER: builtins.int + team: meshtastic.protobuf.atak_pb2.Team.ValueType + """ + Team color. + Default Unspecifed_Color -> firmware uses Cyan + """ + role: meshtastic.protobuf.atak_pb2.MemberRole.ValueType + """ + Member role. + Default Unspecifed -> firmware uses TeamMember + """ + def __init__( + self, + *, + team: meshtastic.protobuf.atak_pb2.Team.ValueType = ..., + role: meshtastic.protobuf.atak_pb2.MemberRole.ValueType = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["role", b"role", "team", b"team"]) -> None: ... + MQTT_FIELD_NUMBER: builtins.int SERIAL_FIELD_NUMBER: builtins.int EXTERNAL_NOTIFICATION_FIELD_NUMBER: builtins.int @@ -1216,6 +1344,8 @@ class ModuleConfig(google.protobuf.message.Message): DETECTION_SENSOR_FIELD_NUMBER: builtins.int PAXCOUNTER_FIELD_NUMBER: builtins.int STATUSMESSAGE_FIELD_NUMBER: builtins.int + TRAFFIC_MANAGEMENT_FIELD_NUMBER: builtins.int + TAK_FIELD_NUMBER: builtins.int @property def mqtt(self) -> global___ModuleConfig.MQTTConfig: """ @@ -1300,6 +1430,18 @@ class ModuleConfig(google.protobuf.message.Message): TODO: REPLACE """ + @property + def traffic_management(self) -> global___ModuleConfig.TrafficManagementConfig: + """ + Traffic management module config for mesh network optimization + """ + + @property + def tak(self) -> global___ModuleConfig.TAKConfig: + """ + TAK team/role configuration for TAK_TRACKER + """ + def __init__( self, *, @@ -1317,10 +1459,12 @@ class ModuleConfig(google.protobuf.message.Message): detection_sensor: global___ModuleConfig.DetectionSensorConfig | None = ..., paxcounter: global___ModuleConfig.PaxcounterConfig | None = ..., statusmessage: global___ModuleConfig.StatusMessageConfig | None = ..., + traffic_management: global___ModuleConfig.TrafficManagementConfig | None = ..., + tak: global___ModuleConfig.TAKConfig | None = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["ambient_lighting", b"ambient_lighting", "audio", b"audio", "canned_message", b"canned_message", "detection_sensor", b"detection_sensor", "external_notification", b"external_notification", "mqtt", b"mqtt", "neighbor_info", b"neighbor_info", "paxcounter", b"paxcounter", "payload_variant", b"payload_variant", "range_test", b"range_test", "remote_hardware", b"remote_hardware", "serial", b"serial", "statusmessage", b"statusmessage", "store_forward", b"store_forward", "telemetry", b"telemetry"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["ambient_lighting", b"ambient_lighting", "audio", b"audio", "canned_message", b"canned_message", "detection_sensor", b"detection_sensor", "external_notification", b"external_notification", "mqtt", b"mqtt", "neighbor_info", b"neighbor_info", "paxcounter", b"paxcounter", "payload_variant", b"payload_variant", "range_test", b"range_test", "remote_hardware", b"remote_hardware", "serial", b"serial", "statusmessage", b"statusmessage", "store_forward", b"store_forward", "telemetry", b"telemetry"]) -> None: ... - def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["mqtt", "serial", "external_notification", "store_forward", "range_test", "telemetry", "canned_message", "audio", "remote_hardware", "neighbor_info", "ambient_lighting", "detection_sensor", "paxcounter", "statusmessage"] | None: ... + def HasField(self, field_name: typing.Literal["ambient_lighting", b"ambient_lighting", "audio", b"audio", "canned_message", b"canned_message", "detection_sensor", b"detection_sensor", "external_notification", b"external_notification", "mqtt", b"mqtt", "neighbor_info", b"neighbor_info", "paxcounter", b"paxcounter", "payload_variant", b"payload_variant", "range_test", b"range_test", "remote_hardware", b"remote_hardware", "serial", b"serial", "statusmessage", b"statusmessage", "store_forward", b"store_forward", "tak", b"tak", "telemetry", b"telemetry", "traffic_management", b"traffic_management"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["ambient_lighting", b"ambient_lighting", "audio", b"audio", "canned_message", b"canned_message", "detection_sensor", b"detection_sensor", "external_notification", b"external_notification", "mqtt", b"mqtt", "neighbor_info", b"neighbor_info", "paxcounter", b"paxcounter", "payload_variant", b"payload_variant", "range_test", b"range_test", "remote_hardware", b"remote_hardware", "serial", b"serial", "statusmessage", b"statusmessage", "store_forward", b"store_forward", "tak", b"tak", "telemetry", b"telemetry", "traffic_management", b"traffic_management"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["mqtt", "serial", "external_notification", "store_forward", "range_test", "telemetry", "canned_message", "audio", "remote_hardware", "neighbor_info", "ambient_lighting", "detection_sensor", "paxcounter", "statusmessage", "traffic_management", "tak"] | None: ... global___ModuleConfig = ModuleConfig diff --git a/meshtastic/protobuf/mqtt_pb2.py b/meshtastic/protobuf/mqtt_pb2.py index 7b4e4c0..54e0918 100644 --- a/meshtastic/protobuf/mqtt_pb2.py +++ b/meshtastic/protobuf/mqtt_pb2.py @@ -13,9 +13,10 @@ _sym_db = _symbol_database.Default() from meshtastic.protobuf import config_pb2 as meshtastic_dot_protobuf_dot_config__pb2 from meshtastic.protobuf import mesh_pb2 as meshtastic_dot_protobuf_dot_mesh__pb2 +from meshtastic.protobuf import nanopb_pb2 as meshtastic_dot_protobuf_dot_nanopb__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mqtt.proto\x12\x13meshtastic.protobuf\x1a meshtastic/protobuf/config.proto\x1a\x1emeshtastic/protobuf/mesh.proto\"j\n\x0fServiceEnvelope\x12/\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacket\x12\x12\n\nchannel_id\x18\x02 \x01(\t\x12\x12\n\ngateway_id\x18\x03 \x01(\t\"\x83\x04\n\tMapReport\x12\x11\n\tlong_name\x18\x01 \x01(\t\x12\x12\n\nshort_name\x18\x02 \x01(\t\x12;\n\x04role\x18\x03 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x34\n\x08hw_model\x18\x04 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x18\n\x10\x66irmware_version\x18\x05 \x01(\t\x12\x41\n\x06region\x18\x06 \x01(\x0e\x32\x31.meshtastic.protobuf.Config.LoRaConfig.RegionCode\x12H\n\x0cmodem_preset\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.LoRaConfig.ModemPreset\x12\x1b\n\x13has_default_channel\x18\x08 \x01(\x08\x12\x12\n\nlatitude_i\x18\t \x01(\x0f\x12\x13\n\x0blongitude_i\x18\n \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x0b \x01(\x05\x12\x1a\n\x12position_precision\x18\x0c \x01(\r\x12\x1e\n\x16num_online_local_nodes\x18\r \x01(\r\x12!\n\x19has_opted_report_location\x18\x0e \x01(\x08\x42`\n\x14org.meshtastic.protoB\nMQTTProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mqtt.proto\x12\x13meshtastic.protobuf\x1a meshtastic/protobuf/config.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a meshtastic/protobuf/nanopb.proto\"j\n\x0fServiceEnvelope\x12/\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacket\x12\x12\n\nchannel_id\x18\x02 \x01(\t\x12\x12\n\ngateway_id\x18\x03 \x01(\t\"\x9f\x04\n\tMapReport\x12\x18\n\tlong_name\x18\x01 \x01(\tB\x05\x92?\x02\x08(\x12\x19\n\nshort_name\x18\x02 \x01(\tB\x05\x92?\x02\x08\x05\x12;\n\x04role\x18\x03 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x34\n\x08hw_model\x18\x04 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x1f\n\x10\x66irmware_version\x18\x05 \x01(\tB\x05\x92?\x02\x08\x12\x12\x41\n\x06region\x18\x06 \x01(\x0e\x32\x31.meshtastic.protobuf.Config.LoRaConfig.RegionCode\x12H\n\x0cmodem_preset\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.LoRaConfig.ModemPreset\x12\x1b\n\x13has_default_channel\x18\x08 \x01(\x08\x12\x12\n\nlatitude_i\x18\t \x01(\x0f\x12\x13\n\x0blongitude_i\x18\n \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x0b \x01(\x05\x12\x1a\n\x12position_precision\x18\x0c \x01(\r\x12%\n\x16num_online_local_nodes\x18\r \x01(\rB\x05\x92?\x02\x38\x10\x12!\n\x19has_opted_report_location\x18\x0e \x01(\x08\x42`\n\x14org.meshtastic.protoB\nMQTTProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -23,8 +24,16 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.mqtt_pb if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\nMQTTProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _globals['_SERVICEENVELOPE']._serialized_start=121 - _globals['_SERVICEENVELOPE']._serialized_end=227 - _globals['_MAPREPORT']._serialized_start=230 - _globals['_MAPREPORT']._serialized_end=745 + _MAPREPORT.fields_by_name['long_name']._options = None + _MAPREPORT.fields_by_name['long_name']._serialized_options = b'\222?\002\010(' + _MAPREPORT.fields_by_name['short_name']._options = None + _MAPREPORT.fields_by_name['short_name']._serialized_options = b'\222?\002\010\005' + _MAPREPORT.fields_by_name['firmware_version']._options = None + _MAPREPORT.fields_by_name['firmware_version']._serialized_options = b'\222?\002\010\022' + _MAPREPORT.fields_by_name['num_online_local_nodes']._options = None + _MAPREPORT.fields_by_name['num_online_local_nodes']._serialized_options = b'\222?\0028\020' + _globals['_SERVICEENVELOPE']._serialized_start=155 + _globals['_SERVICEENVELOPE']._serialized_end=261 + _globals['_MAPREPORT']._serialized_start=264 + _globals['_MAPREPORT']._serialized_end=807 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/portnums_pb2.py b/meshtastic/protobuf/portnums_pb2.py index b33b942..2421233 100644 --- a/meshtastic/protobuf/portnums_pb2.py +++ b/meshtastic/protobuf/portnums_pb2.py @@ -13,7 +13,7 @@ _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"meshtastic/protobuf/portnums.proto\x12\x13meshtastic.protobuf*\xab\x05\n\x07PortNum\x12\x0f\n\x0bUNKNOWN_APP\x10\x00\x12\x14\n\x10TEXT_MESSAGE_APP\x10\x01\x12\x17\n\x13REMOTE_HARDWARE_APP\x10\x02\x12\x10\n\x0cPOSITION_APP\x10\x03\x12\x10\n\x0cNODEINFO_APP\x10\x04\x12\x0f\n\x0bROUTING_APP\x10\x05\x12\r\n\tADMIN_APP\x10\x06\x12\x1f\n\x1bTEXT_MESSAGE_COMPRESSED_APP\x10\x07\x12\x10\n\x0cWAYPOINT_APP\x10\x08\x12\r\n\tAUDIO_APP\x10\t\x12\x18\n\x14\x44\x45TECTION_SENSOR_APP\x10\n\x12\r\n\tALERT_APP\x10\x0b\x12\x18\n\x14KEY_VERIFICATION_APP\x10\x0c\x12\r\n\tREPLY_APP\x10 \x12\x11\n\rIP_TUNNEL_APP\x10!\x12\x12\n\x0ePAXCOUNTER_APP\x10\"\x12\x1e\n\x1aSTORE_FORWARD_PLUSPLUS_APP\x10#\x12\x13\n\x0fNODE_STATUS_APP\x10$\x12\x0e\n\nSERIAL_APP\x10@\x12\x15\n\x11STORE_FORWARD_APP\x10\x41\x12\x12\n\x0eRANGE_TEST_APP\x10\x42\x12\x11\n\rTELEMETRY_APP\x10\x43\x12\x0b\n\x07ZPS_APP\x10\x44\x12\x11\n\rSIMULATOR_APP\x10\x45\x12\x12\n\x0eTRACEROUTE_APP\x10\x46\x12\x14\n\x10NEIGHBORINFO_APP\x10G\x12\x0f\n\x0b\x41TAK_PLUGIN\x10H\x12\x12\n\x0eMAP_REPORT_APP\x10I\x12\x13\n\x0fPOWERSTRESS_APP\x10J\x12\x18\n\x14RETICULUM_TUNNEL_APP\x10L\x12\x0f\n\x0b\x43\x41YENNE_APP\x10M\x12\x10\n\x0bPRIVATE_APP\x10\x80\x02\x12\x13\n\x0e\x41TAK_FORWARDER\x10\x81\x02\x12\x08\n\x03MAX\x10\xff\x03\x42^\n\x14org.meshtastic.protoB\x08PortnumsZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"meshtastic/protobuf/portnums.proto\x12\x13meshtastic.protobuf*\xfd\x05\n\x07PortNum\x12\x0f\n\x0bUNKNOWN_APP\x10\x00\x12\x14\n\x10TEXT_MESSAGE_APP\x10\x01\x12\x17\n\x13REMOTE_HARDWARE_APP\x10\x02\x12\x10\n\x0cPOSITION_APP\x10\x03\x12\x10\n\x0cNODEINFO_APP\x10\x04\x12\x0f\n\x0bROUTING_APP\x10\x05\x12\r\n\tADMIN_APP\x10\x06\x12\x1f\n\x1bTEXT_MESSAGE_COMPRESSED_APP\x10\x07\x12\x10\n\x0cWAYPOINT_APP\x10\x08\x12\r\n\tAUDIO_APP\x10\t\x12\x18\n\x14\x44\x45TECTION_SENSOR_APP\x10\n\x12\r\n\tALERT_APP\x10\x0b\x12\x18\n\x14KEY_VERIFICATION_APP\x10\x0c\x12\x14\n\x10REMOTE_SHELL_APP\x10\r\x12\r\n\tREPLY_APP\x10 \x12\x11\n\rIP_TUNNEL_APP\x10!\x12\x12\n\x0ePAXCOUNTER_APP\x10\"\x12\x1e\n\x1aSTORE_FORWARD_PLUSPLUS_APP\x10#\x12\x13\n\x0fNODE_STATUS_APP\x10$\x12\x0e\n\nSERIAL_APP\x10@\x12\x15\n\x11STORE_FORWARD_APP\x10\x41\x12\x12\n\x0eRANGE_TEST_APP\x10\x42\x12\x11\n\rTELEMETRY_APP\x10\x43\x12\x0b\n\x07ZPS_APP\x10\x44\x12\x11\n\rSIMULATOR_APP\x10\x45\x12\x12\n\x0eTRACEROUTE_APP\x10\x46\x12\x14\n\x10NEIGHBORINFO_APP\x10G\x12\x0f\n\x0b\x41TAK_PLUGIN\x10H\x12\x12\n\x0eMAP_REPORT_APP\x10I\x12\x13\n\x0fPOWERSTRESS_APP\x10J\x12\x12\n\x0eLORAWAN_BRIDGE\x10K\x12\x18\n\x14RETICULUM_TUNNEL_APP\x10L\x12\x0f\n\x0b\x43\x41YENNE_APP\x10M\x12\x12\n\x0e\x41TAK_PLUGIN_V2\x10N\x12\x12\n\x0eGROUPALARM_APP\x10p\x12\x10\n\x0bPRIVATE_APP\x10\x80\x02\x12\x13\n\x0e\x41TAK_FORWARDER\x10\x81\x02\x12\x08\n\x03MAX\x10\xff\x03\x42^\n\x14org.meshtastic.protoB\x08PortnumsZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -22,5 +22,5 @@ if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\010PortnumsZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' _globals['_PORTNUM']._serialized_start=60 - _globals['_PORTNUM']._serialized_end=743 + _globals['_PORTNUM']._serialized_end=825 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/portnums_pb2.pyi b/meshtastic/protobuf/portnums_pb2.pyi index 2203d0c..a16cef2 100644 --- a/meshtastic/protobuf/portnums_pb2.pyi +++ b/meshtastic/protobuf/portnums_pb2.pyi @@ -101,6 +101,10 @@ class _PortNumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTy """ Module/port for handling key verification requests. """ + REMOTE_SHELL_APP: _PortNum.ValueType # 13 + """ + Module/port for handling primitive remote shell access. + """ REPLY_APP: _PortNum.ValueType # 32 """ Provides a 'ping' service that replies to any packet it receives. @@ -197,6 +201,11 @@ class _PortNumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTy """ PowerStress based monitoring support (for automated power consumption testing) """ + LORAWAN_BRIDGE: _PortNum.ValueType # 75 + """ + LoraWAN Payload Transport + ENCODING: compact binary LoRaWAN uplink (10-byte RF metadata + PHY payload) - see LoRaWANBridgeModule + """ RETICULUM_TUNNEL_APP: _PortNum.ValueType # 76 """ Reticulum Network Stack Tunnel App @@ -208,6 +217,18 @@ class _PortNumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTy arbitrary telemetry over meshtastic that is not covered by telemetry.proto ENCODING: CayenneLLP """ + ATAK_PLUGIN_V2: _PortNum.ValueType # 78 + """ + ATAK Plugin V2 + Portnum for payloads from the official Meshtastic ATAK plugin using + TAKPacketV2 with zstd dictionary compression. + """ + GROUPALARM_APP: _PortNum.ValueType # 112 + """ + GroupAlarm integration + Used for transporting GroupAlarm-related messages between Meshtastic nodes + and companion applications/services. + """ PRIVATE_APP: _PortNum.ValueType # 256 """ Private applications should use portnums >= 256. @@ -319,6 +340,10 @@ KEY_VERIFICATION_APP: PortNum.ValueType # 12 """ Module/port for handling key verification requests. """ +REMOTE_SHELL_APP: PortNum.ValueType # 13 +""" +Module/port for handling primitive remote shell access. +""" REPLY_APP: PortNum.ValueType # 32 """ Provides a 'ping' service that replies to any packet it receives. @@ -415,6 +440,11 @@ POWERSTRESS_APP: PortNum.ValueType # 74 """ PowerStress based monitoring support (for automated power consumption testing) """ +LORAWAN_BRIDGE: PortNum.ValueType # 75 +""" +LoraWAN Payload Transport +ENCODING: compact binary LoRaWAN uplink (10-byte RF metadata + PHY payload) - see LoRaWANBridgeModule +""" RETICULUM_TUNNEL_APP: PortNum.ValueType # 76 """ Reticulum Network Stack Tunnel App @@ -426,6 +456,18 @@ App for transporting Cayenne Low Power Payload, popular for LoRaWAN sensor nodes arbitrary telemetry over meshtastic that is not covered by telemetry.proto ENCODING: CayenneLLP """ +ATAK_PLUGIN_V2: PortNum.ValueType # 78 +""" +ATAK Plugin V2 +Portnum for payloads from the official Meshtastic ATAK plugin using +TAKPacketV2 with zstd dictionary compression. +""" +GROUPALARM_APP: PortNum.ValueType # 112 +""" +GroupAlarm integration +Used for transporting GroupAlarm-related messages between Meshtastic nodes +and companion applications/services. +""" PRIVATE_APP: PortNum.ValueType # 256 """ Private applications should use portnums >= 256. diff --git a/meshtastic/protobuf/rtttl_pb2.py b/meshtastic/protobuf/rtttl_pb2.py index 12842c2..95039ed 100644 --- a/meshtastic/protobuf/rtttl_pb2.py +++ b/meshtastic/protobuf/rtttl_pb2.py @@ -11,9 +11,10 @@ from google.protobuf.internal import builder as _builder _sym_db = _symbol_database.Default() +from meshtastic.protobuf import nanopb_pb2 as meshtastic_dot_protobuf_dot_nanopb__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmeshtastic/protobuf/rtttl.proto\x12\x13meshtastic.protobuf\"\x1f\n\x0bRTTTLConfig\x12\x10\n\x08ringtone\x18\x01 \x01(\tBg\n\x14org.meshtastic.protoB\x11RTTTLConfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmeshtastic/protobuf/rtttl.proto\x12\x13meshtastic.protobuf\x1a meshtastic/protobuf/nanopb.proto\"\'\n\x0bRTTTLConfig\x12\x18\n\x08ringtone\x18\x01 \x01(\tB\x06\x92?\x03\x08\xe7\x01\x42g\n\x14org.meshtastic.protoB\x11RTTTLConfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -21,6 +22,8 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.rtttl_p if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\021RTTTLConfigProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _globals['_RTTTLCONFIG']._serialized_start=56 - _globals['_RTTTLCONFIG']._serialized_end=87 + _RTTTLCONFIG.fields_by_name['ringtone']._options = None + _RTTTLCONFIG.fields_by_name['ringtone']._serialized_options = b'\222?\003\010\347\001' + _globals['_RTTTLCONFIG']._serialized_start=90 + _globals['_RTTTLCONFIG']._serialized_end=129 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/serial_hal_pb2.py b/meshtastic/protobuf/serial_hal_pb2.py new file mode 100644 index 0000000..2fe775c --- /dev/null +++ b/meshtastic/protobuf/serial_hal_pb2.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: meshtastic/protobuf/serial_hal.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from meshtastic.protobuf import nanopb_pb2 as meshtastic_dot_protobuf_dot_nanopb__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$meshtastic/protobuf/serial_hal.proto\x12\x13meshtastic.protobuf\x1a meshtastic/protobuf/nanopb.proto\"\xb3\x02\n\x10SerialHalCommand\x12\x16\n\x0etransaction_id\x18\x01 \x01(\r\x12\x38\n\x04type\x18\x02 \x01(\x0e\x32*.meshtastic.protobuf.SerialHalCommand.Type\x12\x0b\n\x03pin\x18\x03 \x01(\r\x12\r\n\x05value\x18\x04 \x01(\r\x12\x0c\n\x04mode\x18\x05 \x01(\r\x12\x14\n\x04\x64\x61ta\x18\x06 \x01(\x0c\x42\x06\x92?\x03\x08\x80\x04\"\x8c\x01\n\x04Type\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08PIN_MODE\x10\x01\x12\x11\n\rDIGITAL_WRITE\x10\x02\x12\x10\n\x0c\x44IGITAL_READ\x10\x03\x12\x14\n\x10\x41TTACH_INTERRUPT\x10\x04\x12\x14\n\x10\x44\x45TACH_INTERRUPT\x10\x05\x12\x10\n\x0cSPI_TRANSFER\x10\x06\x12\x08\n\x04NOOP\x10\x07\"\xe4\x01\n\x11SerialHalResponse\x12\x16\n\x0etransaction_id\x18\x01 \x01(\r\x12=\n\x06result\x18\x02 \x01(\x0e\x32-.meshtastic.protobuf.SerialHalResponse.Result\x12\r\n\x05value\x18\x03 \x01(\r\x12\x14\n\x04\x64\x61ta\x18\x04 \x01(\x0c\x42\x06\x92?\x03\x08\x80\x04\x12\x14\n\x05\x65rror\x18\x05 \x01(\tB\x05\x92?\x02\x08P\"=\n\x06Result\x12\x06\n\x02OK\x10\x00\x12\t\n\x05\x45RROR\x10\x01\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10\x02\x12\x0f\n\x0bUNSUPPORTED\x10\x03\x42_\n\x14org.meshtastic.protoB\tSerialHalZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.serial_hal_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + DESCRIPTOR._options = None + DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\tSerialHalZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' + _SERIALHALCOMMAND.fields_by_name['data']._options = None + _SERIALHALCOMMAND.fields_by_name['data']._serialized_options = b'\222?\003\010\200\004' + _SERIALHALRESPONSE.fields_by_name['data']._options = None + _SERIALHALRESPONSE.fields_by_name['data']._serialized_options = b'\222?\003\010\200\004' + _SERIALHALRESPONSE.fields_by_name['error']._options = None + _SERIALHALRESPONSE.fields_by_name['error']._serialized_options = b'\222?\002\010P' + _globals['_SERIALHALCOMMAND']._serialized_start=96 + _globals['_SERIALHALCOMMAND']._serialized_end=403 + _globals['_SERIALHALCOMMAND_TYPE']._serialized_start=263 + _globals['_SERIALHALCOMMAND_TYPE']._serialized_end=403 + _globals['_SERIALHALRESPONSE']._serialized_start=406 + _globals['_SERIALHALRESPONSE']._serialized_end=634 + _globals['_SERIALHALRESPONSE_RESULT']._serialized_start=573 + _globals['_SERIALHALRESPONSE_RESULT']._serialized_end=634 +# @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/serial_hal_pb2.pyi b/meshtastic/protobuf/serial_hal_pb2.pyi new file mode 100644 index 0000000..33d75cb --- /dev/null +++ b/meshtastic/protobuf/serial_hal_pb2.pyi @@ -0,0 +1,140 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" + +import builtins +import google.protobuf.descriptor +import google.protobuf.internal.enum_type_wrapper +import google.protobuf.message +import sys +import typing + +if sys.version_info >= (3, 10): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing.final +class SerialHalCommand(google.protobuf.message.Message): + """SerialHalCommand messages are sent from host to device over the SerialHal + framing stream. Responses normally come back as SerialHalResponse with the + same transaction_id. + + Interrupt notifications are the one asynchronous exception: the device emits + an unsolicited SerialHalResponse with transaction_id == 0 and value == pin. + Host implementations should treat those frames as interrupt events rather + than replies to an outstanding request. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _Type: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _TypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[SerialHalCommand._Type.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + UNSET: SerialHalCommand._Type.ValueType # 0 + PIN_MODE: SerialHalCommand._Type.ValueType # 1 + DIGITAL_WRITE: SerialHalCommand._Type.ValueType # 2 + DIGITAL_READ: SerialHalCommand._Type.ValueType # 3 + ATTACH_INTERRUPT: SerialHalCommand._Type.ValueType # 4 + DETACH_INTERRUPT: SerialHalCommand._Type.ValueType # 5 + SPI_TRANSFER: SerialHalCommand._Type.ValueType # 6 + NOOP: SerialHalCommand._Type.ValueType # 7 + + class Type(_Type, metaclass=_TypeEnumTypeWrapper): ... + UNSET: SerialHalCommand.Type.ValueType # 0 + PIN_MODE: SerialHalCommand.Type.ValueType # 1 + DIGITAL_WRITE: SerialHalCommand.Type.ValueType # 2 + DIGITAL_READ: SerialHalCommand.Type.ValueType # 3 + ATTACH_INTERRUPT: SerialHalCommand.Type.ValueType # 4 + DETACH_INTERRUPT: SerialHalCommand.Type.ValueType # 5 + SPI_TRANSFER: SerialHalCommand.Type.ValueType # 6 + NOOP: SerialHalCommand.Type.ValueType # 7 + + TRANSACTION_ID_FIELD_NUMBER: builtins.int + TYPE_FIELD_NUMBER: builtins.int + PIN_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + MODE_FIELD_NUMBER: builtins.int + DATA_FIELD_NUMBER: builtins.int + transaction_id: builtins.int + """Host-assigned request id. Replies echo this id back in + SerialHalResponse.transaction_id. + """ + type: global___SerialHalCommand.Type.ValueType + pin: builtins.int + value: builtins.int + mode: builtins.int + data: builtins.bytes + def __init__( + self, + *, + transaction_id: builtins.int = ..., + type: global___SerialHalCommand.Type.ValueType = ..., + pin: builtins.int = ..., + value: builtins.int = ..., + mode: builtins.int = ..., + data: builtins.bytes = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["data", b"data", "mode", b"mode", "pin", b"pin", "transaction_id", b"transaction_id", "type", b"type", "value", b"value"]) -> None: ... + +global___SerialHalCommand = SerialHalCommand + +@typing.final +class SerialHalResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _Result: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _ResultEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[SerialHalResponse._Result.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + OK: SerialHalResponse._Result.ValueType # 0 + ERROR: SerialHalResponse._Result.ValueType # 1 + BAD_REQUEST: SerialHalResponse._Result.ValueType # 2 + UNSUPPORTED: SerialHalResponse._Result.ValueType # 3 + + class Result(_Result, metaclass=_ResultEnumTypeWrapper): ... + OK: SerialHalResponse.Result.ValueType # 0 + ERROR: SerialHalResponse.Result.ValueType # 1 + BAD_REQUEST: SerialHalResponse.Result.ValueType # 2 + UNSUPPORTED: SerialHalResponse.Result.ValueType # 3 + + TRANSACTION_ID_FIELD_NUMBER: builtins.int + RESULT_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + DATA_FIELD_NUMBER: builtins.int + ERROR_FIELD_NUMBER: builtins.int + transaction_id: builtins.int + """Matches the originating SerialHalCommand.transaction_id for normal + request/response traffic. + + A value of 0 indicates an unsolicited interrupt notification generated by + the device. In that case, the host should interpret value as the GPIO pin + that triggered. + """ + result: global___SerialHalResponse.Result.ValueType + value: builtins.int + """Used by DIGITAL_READ replies and interrupt notifications. For interrupt + notifications (transaction_id == 0), this carries the pin number. + """ + data: builtins.bytes + error: builtins.str + def __init__( + self, + *, + transaction_id: builtins.int = ..., + result: global___SerialHalResponse.Result.ValueType = ..., + value: builtins.int = ..., + data: builtins.bytes = ..., + error: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["data", b"data", "error", b"error", "result", b"result", "transaction_id", b"transaction_id", "value", b"value"]) -> None: ... + +global___SerialHalResponse = SerialHalResponse diff --git a/meshtastic/protobuf/storeforward_pb2.py b/meshtastic/protobuf/storeforward_pb2.py index cd57ff6..7ff93bd 100644 --- a/meshtastic/protobuf/storeforward_pb2.py +++ b/meshtastic/protobuf/storeforward_pb2.py @@ -11,9 +11,10 @@ from google.protobuf.internal import builder as _builder _sym_db = _symbol_database.Default() +from meshtastic.protobuf import nanopb_pb2 as meshtastic_dot_protobuf_dot_nanopb__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n&meshtastic/protobuf/storeforward.proto\x12\x13meshtastic.protobuf\"\xc0\x07\n\x0fStoreAndForward\x12@\n\x02rr\x18\x01 \x01(\x0e\x32\x34.meshtastic.protobuf.StoreAndForward.RequestResponse\x12@\n\x05stats\x18\x02 \x01(\x0b\x32/.meshtastic.protobuf.StoreAndForward.StatisticsH\x00\x12?\n\x07history\x18\x03 \x01(\x0b\x32,.meshtastic.protobuf.StoreAndForward.HistoryH\x00\x12\x43\n\theartbeat\x18\x04 \x01(\x0b\x32..meshtastic.protobuf.StoreAndForward.HeartbeatH\x00\x12\x0e\n\x04text\x18\x05 \x01(\x0cH\x00\x1a\xcd\x01\n\nStatistics\x12\x16\n\x0emessages_total\x18\x01 \x01(\r\x12\x16\n\x0emessages_saved\x18\x02 \x01(\r\x12\x14\n\x0cmessages_max\x18\x03 \x01(\r\x12\x0f\n\x07up_time\x18\x04 \x01(\r\x12\x10\n\x08requests\x18\x05 \x01(\r\x12\x18\n\x10requests_history\x18\x06 \x01(\r\x12\x11\n\theartbeat\x18\x07 \x01(\x08\x12\x12\n\nreturn_max\x18\x08 \x01(\r\x12\x15\n\rreturn_window\x18\t \x01(\r\x1aI\n\x07History\x12\x18\n\x10history_messages\x18\x01 \x01(\r\x12\x0e\n\x06window\x18\x02 \x01(\r\x12\x14\n\x0clast_request\x18\x03 \x01(\r\x1a.\n\tHeartbeat\x12\x0e\n\x06period\x18\x01 \x01(\r\x12\x11\n\tsecondary\x18\x02 \x01(\r\"\xbc\x02\n\x0fRequestResponse\x12\t\n\x05UNSET\x10\x00\x12\x10\n\x0cROUTER_ERROR\x10\x01\x12\x14\n\x10ROUTER_HEARTBEAT\x10\x02\x12\x0f\n\x0bROUTER_PING\x10\x03\x12\x0f\n\x0bROUTER_PONG\x10\x04\x12\x0f\n\x0bROUTER_BUSY\x10\x05\x12\x12\n\x0eROUTER_HISTORY\x10\x06\x12\x10\n\x0cROUTER_STATS\x10\x07\x12\x16\n\x12ROUTER_TEXT_DIRECT\x10\x08\x12\x19\n\x15ROUTER_TEXT_BROADCAST\x10\t\x12\x10\n\x0c\x43LIENT_ERROR\x10@\x12\x12\n\x0e\x43LIENT_HISTORY\x10\x41\x12\x10\n\x0c\x43LIENT_STATS\x10\x42\x12\x0f\n\x0b\x43LIENT_PING\x10\x43\x12\x0f\n\x0b\x43LIENT_PONG\x10\x44\x12\x10\n\x0c\x43LIENT_ABORT\x10jB\t\n\x07variantBk\n\x14org.meshtastic.protoB\x15StoreAndForwardProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n&meshtastic/protobuf/storeforward.proto\x12\x13meshtastic.protobuf\x1a meshtastic/protobuf/nanopb.proto\"\xc8\x07\n\x0fStoreAndForward\x12@\n\x02rr\x18\x01 \x01(\x0e\x32\x34.meshtastic.protobuf.StoreAndForward.RequestResponse\x12@\n\x05stats\x18\x02 \x01(\x0b\x32/.meshtastic.protobuf.StoreAndForward.StatisticsH\x00\x12?\n\x07history\x18\x03 \x01(\x0b\x32,.meshtastic.protobuf.StoreAndForward.HistoryH\x00\x12\x43\n\theartbeat\x18\x04 \x01(\x0b\x32..meshtastic.protobuf.StoreAndForward.HeartbeatH\x00\x12\x16\n\x04text\x18\x05 \x01(\x0c\x42\x06\x92?\x03\x08\xe9\x01H\x00\x1a\xcd\x01\n\nStatistics\x12\x16\n\x0emessages_total\x18\x01 \x01(\r\x12\x16\n\x0emessages_saved\x18\x02 \x01(\r\x12\x14\n\x0cmessages_max\x18\x03 \x01(\r\x12\x0f\n\x07up_time\x18\x04 \x01(\r\x12\x10\n\x08requests\x18\x05 \x01(\r\x12\x18\n\x10requests_history\x18\x06 \x01(\r\x12\x11\n\theartbeat\x18\x07 \x01(\x08\x12\x12\n\nreturn_max\x18\x08 \x01(\r\x12\x15\n\rreturn_window\x18\t \x01(\r\x1aI\n\x07History\x12\x18\n\x10history_messages\x18\x01 \x01(\r\x12\x0e\n\x06window\x18\x02 \x01(\r\x12\x14\n\x0clast_request\x18\x03 \x01(\r\x1a.\n\tHeartbeat\x12\x0e\n\x06period\x18\x01 \x01(\r\x12\x11\n\tsecondary\x18\x02 \x01(\r\"\xbc\x02\n\x0fRequestResponse\x12\t\n\x05UNSET\x10\x00\x12\x10\n\x0cROUTER_ERROR\x10\x01\x12\x14\n\x10ROUTER_HEARTBEAT\x10\x02\x12\x0f\n\x0bROUTER_PING\x10\x03\x12\x0f\n\x0bROUTER_PONG\x10\x04\x12\x0f\n\x0bROUTER_BUSY\x10\x05\x12\x12\n\x0eROUTER_HISTORY\x10\x06\x12\x10\n\x0cROUTER_STATS\x10\x07\x12\x16\n\x12ROUTER_TEXT_DIRECT\x10\x08\x12\x19\n\x15ROUTER_TEXT_BROADCAST\x10\t\x12\x10\n\x0c\x43LIENT_ERROR\x10@\x12\x12\n\x0e\x43LIENT_HISTORY\x10\x41\x12\x10\n\x0c\x43LIENT_STATS\x10\x42\x12\x0f\n\x0b\x43LIENT_PING\x10\x43\x12\x0f\n\x0b\x43LIENT_PONG\x10\x44\x12\x10\n\x0c\x43LIENT_ABORT\x10jB\t\n\x07variantBk\n\x14org.meshtastic.protoB\x15StoreAndForwardProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -21,14 +22,16 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.storefo if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\025StoreAndForwardProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _globals['_STOREANDFORWARD']._serialized_start=64 - _globals['_STOREANDFORWARD']._serialized_end=1024 - _globals['_STOREANDFORWARD_STATISTICS']._serialized_start=366 - _globals['_STOREANDFORWARD_STATISTICS']._serialized_end=571 - _globals['_STOREANDFORWARD_HISTORY']._serialized_start=573 - _globals['_STOREANDFORWARD_HISTORY']._serialized_end=646 - _globals['_STOREANDFORWARD_HEARTBEAT']._serialized_start=648 - _globals['_STOREANDFORWARD_HEARTBEAT']._serialized_end=694 - _globals['_STOREANDFORWARD_REQUESTRESPONSE']._serialized_start=697 - _globals['_STOREANDFORWARD_REQUESTRESPONSE']._serialized_end=1013 + _STOREANDFORWARD.fields_by_name['text']._options = None + _STOREANDFORWARD.fields_by_name['text']._serialized_options = b'\222?\003\010\351\001' + _globals['_STOREANDFORWARD']._serialized_start=98 + _globals['_STOREANDFORWARD']._serialized_end=1066 + _globals['_STOREANDFORWARD_STATISTICS']._serialized_start=408 + _globals['_STOREANDFORWARD_STATISTICS']._serialized_end=613 + _globals['_STOREANDFORWARD_HISTORY']._serialized_start=615 + _globals['_STOREANDFORWARD_HISTORY']._serialized_end=688 + _globals['_STOREANDFORWARD_HEARTBEAT']._serialized_start=690 + _globals['_STOREANDFORWARD_HEARTBEAT']._serialized_end=736 + _globals['_STOREANDFORWARD_REQUESTRESPONSE']._serialized_start=739 + _globals['_STOREANDFORWARD_REQUESTRESPONSE']._serialized_end=1055 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/telemetry_pb2.py b/meshtastic/protobuf/telemetry_pb2.py index 5b04c45..8fefe68 100644 --- a/meshtastic/protobuf/telemetry_pb2.py +++ b/meshtastic/protobuf/telemetry_pb2.py @@ -11,9 +11,10 @@ from google.protobuf.internal import builder as _builder _sym_db = _symbol_database.Default() +from meshtastic.protobuf import nanopb_pb2 as meshtastic_dot_protobuf_dot_nanopb__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/telemetry.proto\x12\x13meshtastic.protobuf\"\xf3\x01\n\rDeviceMetrics\x12\x1a\n\rbattery_level\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x14\n\x07voltage\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12 \n\x13\x63hannel_utilization\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x18\n\x0b\x61ir_util_tx\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x1b\n\x0euptime_seconds\x18\x05 \x01(\rH\x04\x88\x01\x01\x42\x10\n\x0e_battery_levelB\n\n\x08_voltageB\x16\n\x14_channel_utilizationB\x0e\n\x0c_air_util_txB\x11\n\x0f_uptime_seconds\"\x82\x07\n\x12\x45nvironmentMetrics\x12\x18\n\x0btemperature\x18\x01 \x01(\x02H\x00\x88\x01\x01\x12\x1e\n\x11relative_humidity\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12 \n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x1b\n\x0egas_resistance\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x14\n\x07voltage\x18\x05 \x01(\x02H\x04\x88\x01\x01\x12\x14\n\x07\x63urrent\x18\x06 \x01(\x02H\x05\x88\x01\x01\x12\x10\n\x03iaq\x18\x07 \x01(\rH\x06\x88\x01\x01\x12\x15\n\x08\x64istance\x18\x08 \x01(\x02H\x07\x88\x01\x01\x12\x10\n\x03lux\x18\t \x01(\x02H\x08\x88\x01\x01\x12\x16\n\twhite_lux\x18\n \x01(\x02H\t\x88\x01\x01\x12\x13\n\x06ir_lux\x18\x0b \x01(\x02H\n\x88\x01\x01\x12\x13\n\x06uv_lux\x18\x0c \x01(\x02H\x0b\x88\x01\x01\x12\x1b\n\x0ewind_direction\x18\r \x01(\rH\x0c\x88\x01\x01\x12\x17\n\nwind_speed\x18\x0e \x01(\x02H\r\x88\x01\x01\x12\x13\n\x06weight\x18\x0f \x01(\x02H\x0e\x88\x01\x01\x12\x16\n\twind_gust\x18\x10 \x01(\x02H\x0f\x88\x01\x01\x12\x16\n\twind_lull\x18\x11 \x01(\x02H\x10\x88\x01\x01\x12\x16\n\tradiation\x18\x12 \x01(\x02H\x11\x88\x01\x01\x12\x18\n\x0brainfall_1h\x18\x13 \x01(\x02H\x12\x88\x01\x01\x12\x19\n\x0crainfall_24h\x18\x14 \x01(\x02H\x13\x88\x01\x01\x12\x1a\n\rsoil_moisture\x18\x15 \x01(\rH\x14\x88\x01\x01\x12\x1d\n\x10soil_temperature\x18\x16 \x01(\x02H\x15\x88\x01\x01\x42\x0e\n\x0c_temperatureB\x14\n\x12_relative_humidityB\x16\n\x14_barometric_pressureB\x11\n\x0f_gas_resistanceB\n\n\x08_voltageB\n\n\x08_currentB\x06\n\x04_iaqB\x0b\n\t_distanceB\x06\n\x04_luxB\x0c\n\n_white_luxB\t\n\x07_ir_luxB\t\n\x07_uv_luxB\x11\n\x0f_wind_directionB\r\n\x0b_wind_speedB\t\n\x07_weightB\x0c\n\n_wind_gustB\x0c\n\n_wind_lullB\x0c\n\n_radiationB\x0e\n\x0c_rainfall_1hB\x0f\n\r_rainfall_24hB\x10\n\x0e_soil_moistureB\x13\n\x11_soil_temperature\"\xae\x05\n\x0cPowerMetrics\x12\x18\n\x0b\x63h1_voltage\x18\x01 \x01(\x02H\x00\x88\x01\x01\x12\x18\n\x0b\x63h1_current\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12\x18\n\x0b\x63h2_voltage\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x18\n\x0b\x63h2_current\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x18\n\x0b\x63h3_voltage\x18\x05 \x01(\x02H\x04\x88\x01\x01\x12\x18\n\x0b\x63h3_current\x18\x06 \x01(\x02H\x05\x88\x01\x01\x12\x18\n\x0b\x63h4_voltage\x18\x07 \x01(\x02H\x06\x88\x01\x01\x12\x18\n\x0b\x63h4_current\x18\x08 \x01(\x02H\x07\x88\x01\x01\x12\x18\n\x0b\x63h5_voltage\x18\t \x01(\x02H\x08\x88\x01\x01\x12\x18\n\x0b\x63h5_current\x18\n \x01(\x02H\t\x88\x01\x01\x12\x18\n\x0b\x63h6_voltage\x18\x0b \x01(\x02H\n\x88\x01\x01\x12\x18\n\x0b\x63h6_current\x18\x0c \x01(\x02H\x0b\x88\x01\x01\x12\x18\n\x0b\x63h7_voltage\x18\r \x01(\x02H\x0c\x88\x01\x01\x12\x18\n\x0b\x63h7_current\x18\x0e \x01(\x02H\r\x88\x01\x01\x12\x18\n\x0b\x63h8_voltage\x18\x0f \x01(\x02H\x0e\x88\x01\x01\x12\x18\n\x0b\x63h8_current\x18\x10 \x01(\x02H\x0f\x88\x01\x01\x42\x0e\n\x0c_ch1_voltageB\x0e\n\x0c_ch1_currentB\x0e\n\x0c_ch2_voltageB\x0e\n\x0c_ch2_currentB\x0e\n\x0c_ch3_voltageB\x0e\n\x0c_ch3_currentB\x0e\n\x0c_ch4_voltageB\x0e\n\x0c_ch4_currentB\x0e\n\x0c_ch5_voltageB\x0e\n\x0c_ch5_currentB\x0e\n\x0c_ch6_voltageB\x0e\n\x0c_ch6_currentB\x0e\n\x0c_ch7_voltageB\x0e\n\x0c_ch7_currentB\x0e\n\x0c_ch8_voltageB\x0e\n\x0c_ch8_current\"\xb1\t\n\x11\x41irQualityMetrics\x12\x1a\n\rpm10_standard\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x1a\n\rpm25_standard\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x1b\n\x0epm100_standard\x18\x03 \x01(\rH\x02\x88\x01\x01\x12\x1f\n\x12pm10_environmental\x18\x04 \x01(\rH\x03\x88\x01\x01\x12\x1f\n\x12pm25_environmental\x18\x05 \x01(\rH\x04\x88\x01\x01\x12 \n\x13pm100_environmental\x18\x06 \x01(\rH\x05\x88\x01\x01\x12\x1b\n\x0eparticles_03um\x18\x07 \x01(\rH\x06\x88\x01\x01\x12\x1b\n\x0eparticles_05um\x18\x08 \x01(\rH\x07\x88\x01\x01\x12\x1b\n\x0eparticles_10um\x18\t \x01(\rH\x08\x88\x01\x01\x12\x1b\n\x0eparticles_25um\x18\n \x01(\rH\t\x88\x01\x01\x12\x1b\n\x0eparticles_50um\x18\x0b \x01(\rH\n\x88\x01\x01\x12\x1c\n\x0fparticles_100um\x18\x0c \x01(\rH\x0b\x88\x01\x01\x12\x10\n\x03\x63o2\x18\r \x01(\rH\x0c\x88\x01\x01\x12\x1c\n\x0f\x63o2_temperature\x18\x0e \x01(\x02H\r\x88\x01\x01\x12\x19\n\x0c\x63o2_humidity\x18\x0f \x01(\x02H\x0e\x88\x01\x01\x12\x1e\n\x11\x66orm_formaldehyde\x18\x10 \x01(\x02H\x0f\x88\x01\x01\x12\x1a\n\rform_humidity\x18\x11 \x01(\x02H\x10\x88\x01\x01\x12\x1d\n\x10\x66orm_temperature\x18\x12 \x01(\x02H\x11\x88\x01\x01\x12\x1a\n\rpm40_standard\x18\x13 \x01(\rH\x12\x88\x01\x01\x12\x1b\n\x0eparticles_40um\x18\x14 \x01(\rH\x13\x88\x01\x01\x12\x1b\n\x0epm_temperature\x18\x15 \x01(\x02H\x14\x88\x01\x01\x12\x18\n\x0bpm_humidity\x18\x16 \x01(\x02H\x15\x88\x01\x01\x12\x17\n\npm_voc_idx\x18\x17 \x01(\x02H\x16\x88\x01\x01\x12\x17\n\npm_nox_idx\x18\x18 \x01(\x02H\x17\x88\x01\x01\x12\x1a\n\rparticles_tps\x18\x19 \x01(\x02H\x18\x88\x01\x01\x42\x10\n\x0e_pm10_standardB\x10\n\x0e_pm25_standardB\x11\n\x0f_pm100_standardB\x15\n\x13_pm10_environmentalB\x15\n\x13_pm25_environmentalB\x16\n\x14_pm100_environmentalB\x11\n\x0f_particles_03umB\x11\n\x0f_particles_05umB\x11\n\x0f_particles_10umB\x11\n\x0f_particles_25umB\x11\n\x0f_particles_50umB\x12\n\x10_particles_100umB\x06\n\x04_co2B\x12\n\x10_co2_temperatureB\x0f\n\r_co2_humidityB\x14\n\x12_form_formaldehydeB\x10\n\x0e_form_humidityB\x13\n\x11_form_temperatureB\x10\n\x0e_pm40_standardB\x11\n\x0f_particles_40umB\x11\n\x0f_pm_temperatureB\x0e\n\x0c_pm_humidityB\r\n\x0b_pm_voc_idxB\r\n\x0b_pm_nox_idxB\x10\n\x0e_particles_tps\"\xff\x02\n\nLocalStats\x12\x16\n\x0euptime_seconds\x18\x01 \x01(\r\x12\x1b\n\x13\x63hannel_utilization\x18\x02 \x01(\x02\x12\x13\n\x0b\x61ir_util_tx\x18\x03 \x01(\x02\x12\x16\n\x0enum_packets_tx\x18\x04 \x01(\r\x12\x16\n\x0enum_packets_rx\x18\x05 \x01(\r\x12\x1a\n\x12num_packets_rx_bad\x18\x06 \x01(\r\x12\x18\n\x10num_online_nodes\x18\x07 \x01(\r\x12\x17\n\x0fnum_total_nodes\x18\x08 \x01(\r\x12\x13\n\x0bnum_rx_dupe\x18\t \x01(\r\x12\x14\n\x0cnum_tx_relay\x18\n \x01(\r\x12\x1d\n\x15num_tx_relay_canceled\x18\x0b \x01(\r\x12\x18\n\x10heap_total_bytes\x18\x0c \x01(\r\x12\x17\n\x0fheap_free_bytes\x18\r \x01(\r\x12\x16\n\x0enum_tx_dropped\x18\x0e \x01(\r\x12\x13\n\x0bnoise_floor\x18\x0f \x01(\x05\"{\n\rHealthMetrics\x12\x16\n\theart_bpm\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x11\n\x04spO2\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x18\n\x0btemperature\x18\x03 \x01(\x02H\x02\x88\x01\x01\x42\x0c\n\n_heart_bpmB\x07\n\x05_spO2B\x0e\n\x0c_temperature\"\x91\x02\n\x0bHostMetrics\x12\x16\n\x0euptime_seconds\x18\x01 \x01(\r\x12\x15\n\rfreemem_bytes\x18\x02 \x01(\x04\x12\x17\n\x0f\x64iskfree1_bytes\x18\x03 \x01(\x04\x12\x1c\n\x0f\x64iskfree2_bytes\x18\x04 \x01(\x04H\x00\x88\x01\x01\x12\x1c\n\x0f\x64iskfree3_bytes\x18\x05 \x01(\x04H\x01\x88\x01\x01\x12\r\n\x05load1\x18\x06 \x01(\r\x12\r\n\x05load5\x18\x07 \x01(\r\x12\x0e\n\x06load15\x18\x08 \x01(\r\x12\x18\n\x0buser_string\x18\t \x01(\tH\x02\x88\x01\x01\x42\x12\n\x10_diskfree2_bytesB\x12\n\x10_diskfree3_bytesB\x0e\n\x0c_user_string\"\xdd\x03\n\tTelemetry\x12\x0c\n\x04time\x18\x01 \x01(\x07\x12<\n\x0e\x64\x65vice_metrics\x18\x02 \x01(\x0b\x32\".meshtastic.protobuf.DeviceMetricsH\x00\x12\x46\n\x13\x65nvironment_metrics\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.EnvironmentMetricsH\x00\x12\x45\n\x13\x61ir_quality_metrics\x18\x04 \x01(\x0b\x32&.meshtastic.protobuf.AirQualityMetricsH\x00\x12:\n\rpower_metrics\x18\x05 \x01(\x0b\x32!.meshtastic.protobuf.PowerMetricsH\x00\x12\x36\n\x0blocal_stats\x18\x06 \x01(\x0b\x32\x1f.meshtastic.protobuf.LocalStatsH\x00\x12<\n\x0ehealth_metrics\x18\x07 \x01(\x0b\x32\".meshtastic.protobuf.HealthMetricsH\x00\x12\x38\n\x0chost_metrics\x18\x08 \x01(\x0b\x32 .meshtastic.protobuf.HostMetricsH\x00\x42\t\n\x07variant\">\n\rNau7802Config\x12\x12\n\nzeroOffset\x18\x01 \x01(\x05\x12\x19\n\x11\x63\x61librationFactor\x18\x02 \x01(\x02*\xf9\x04\n\x13TelemetrySensorType\x12\x10\n\x0cSENSOR_UNSET\x10\x00\x12\n\n\x06\x42ME280\x10\x01\x12\n\n\x06\x42ME680\x10\x02\x12\x0b\n\x07MCP9808\x10\x03\x12\n\n\x06INA260\x10\x04\x12\n\n\x06INA219\x10\x05\x12\n\n\x06\x42MP280\x10\x06\x12\t\n\x05SHTC3\x10\x07\x12\t\n\x05LPS22\x10\x08\x12\x0b\n\x07QMC6310\x10\t\x12\x0b\n\x07QMI8658\x10\n\x12\x0c\n\x08QMC5883L\x10\x0b\x12\t\n\x05SHT31\x10\x0c\x12\x0c\n\x08PMSA003I\x10\r\x12\x0b\n\x07INA3221\x10\x0e\x12\n\n\x06\x42MP085\x10\x0f\x12\x0c\n\x08RCWL9620\x10\x10\x12\t\n\x05SHT4X\x10\x11\x12\x0c\n\x08VEML7700\x10\x12\x12\x0c\n\x08MLX90632\x10\x13\x12\x0b\n\x07OPT3001\x10\x14\x12\x0c\n\x08LTR390UV\x10\x15\x12\x0e\n\nTSL25911FN\x10\x16\x12\t\n\x05\x41HT10\x10\x17\x12\x10\n\x0c\x44\x46ROBOT_LARK\x10\x18\x12\x0b\n\x07NAU7802\x10\x19\x12\n\n\x06\x42MP3XX\x10\x1a\x12\x0c\n\x08ICM20948\x10\x1b\x12\x0c\n\x08MAX17048\x10\x1c\x12\x11\n\rCUSTOM_SENSOR\x10\x1d\x12\x0c\n\x08MAX30102\x10\x1e\x12\x0c\n\x08MLX90614\x10\x1f\x12\t\n\x05SCD4X\x10 \x12\x0b\n\x07RADSENS\x10!\x12\n\n\x06INA226\x10\"\x12\x10\n\x0c\x44\x46ROBOT_RAIN\x10#\x12\n\n\x06\x44PS310\x10$\x12\x0c\n\x08RAK12035\x10%\x12\x0c\n\x08MAX17261\x10&\x12\x0b\n\x07PCT2075\x10\'\x12\x0b\n\x07\x41\x44S1X15\x10(\x12\x0f\n\x0b\x41\x44S1X15_ALT\x10)\x12\t\n\x05SFA30\x10*\x12\t\n\x05SEN5X\x10+\x12\x0b\n\x07TSL2561\x10,\x12\n\n\x06\x42H1750\x10-Be\n\x14org.meshtastic.protoB\x0fTelemetryProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/telemetry.proto\x12\x13meshtastic.protobuf\x1a meshtastic/protobuf/nanopb.proto\"\xf3\x01\n\rDeviceMetrics\x12\x1a\n\rbattery_level\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x14\n\x07voltage\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12 \n\x13\x63hannel_utilization\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x18\n\x0b\x61ir_util_tx\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x1b\n\x0euptime_seconds\x18\x05 \x01(\rH\x04\x88\x01\x01\x42\x10\n\x0e_battery_levelB\n\n\x08_voltageB\x16\n\x14_channel_utilizationB\x0e\n\x0c_air_util_txB\x11\n\x0f_uptime_seconds\"\xbc\x07\n\x12\x45nvironmentMetrics\x12\x18\n\x0btemperature\x18\x01 \x01(\x02H\x00\x88\x01\x01\x12\x1e\n\x11relative_humidity\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12 \n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x1b\n\x0egas_resistance\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x14\n\x07voltage\x18\x05 \x01(\x02H\x04\x88\x01\x01\x12\x14\n\x07\x63urrent\x18\x06 \x01(\x02H\x05\x88\x01\x01\x12\x17\n\x03iaq\x18\x07 \x01(\rB\x05\x92?\x02\x38\x10H\x06\x88\x01\x01\x12\x15\n\x08\x64istance\x18\x08 \x01(\x02H\x07\x88\x01\x01\x12\x10\n\x03lux\x18\t \x01(\x02H\x08\x88\x01\x01\x12\x16\n\twhite_lux\x18\n \x01(\x02H\t\x88\x01\x01\x12\x13\n\x06ir_lux\x18\x0b \x01(\x02H\n\x88\x01\x01\x12\x13\n\x06uv_lux\x18\x0c \x01(\x02H\x0b\x88\x01\x01\x12\"\n\x0ewind_direction\x18\r \x01(\rB\x05\x92?\x02\x38\x10H\x0c\x88\x01\x01\x12\x17\n\nwind_speed\x18\x0e \x01(\x02H\r\x88\x01\x01\x12\x13\n\x06weight\x18\x0f \x01(\x02H\x0e\x88\x01\x01\x12\x16\n\twind_gust\x18\x10 \x01(\x02H\x0f\x88\x01\x01\x12\x16\n\twind_lull\x18\x11 \x01(\x02H\x10\x88\x01\x01\x12\x16\n\tradiation\x18\x12 \x01(\x02H\x11\x88\x01\x01\x12\x18\n\x0brainfall_1h\x18\x13 \x01(\x02H\x12\x88\x01\x01\x12\x19\n\x0crainfall_24h\x18\x14 \x01(\x02H\x13\x88\x01\x01\x12!\n\rsoil_moisture\x18\x15 \x01(\rB\x05\x92?\x02\x38\x08H\x14\x88\x01\x01\x12\x1d\n\x10soil_temperature\x18\x16 \x01(\x02H\x15\x88\x01\x01\x12#\n\x14one_wire_temperature\x18\x17 \x03(\x02\x42\x05\x92?\x02\x10\x08\x42\x0e\n\x0c_temperatureB\x14\n\x12_relative_humidityB\x16\n\x14_barometric_pressureB\x11\n\x0f_gas_resistanceB\n\n\x08_voltageB\n\n\x08_currentB\x06\n\x04_iaqB\x0b\n\t_distanceB\x06\n\x04_luxB\x0c\n\n_white_luxB\t\n\x07_ir_luxB\t\n\x07_uv_luxB\x11\n\x0f_wind_directionB\r\n\x0b_wind_speedB\t\n\x07_weightB\x0c\n\n_wind_gustB\x0c\n\n_wind_lullB\x0c\n\n_radiationB\x0e\n\x0c_rainfall_1hB\x0f\n\r_rainfall_24hB\x10\n\x0e_soil_moistureB\x13\n\x11_soil_temperature\"\xae\x05\n\x0cPowerMetrics\x12\x18\n\x0b\x63h1_voltage\x18\x01 \x01(\x02H\x00\x88\x01\x01\x12\x18\n\x0b\x63h1_current\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12\x18\n\x0b\x63h2_voltage\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x18\n\x0b\x63h2_current\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x18\n\x0b\x63h3_voltage\x18\x05 \x01(\x02H\x04\x88\x01\x01\x12\x18\n\x0b\x63h3_current\x18\x06 \x01(\x02H\x05\x88\x01\x01\x12\x18\n\x0b\x63h4_voltage\x18\x07 \x01(\x02H\x06\x88\x01\x01\x12\x18\n\x0b\x63h4_current\x18\x08 \x01(\x02H\x07\x88\x01\x01\x12\x18\n\x0b\x63h5_voltage\x18\t \x01(\x02H\x08\x88\x01\x01\x12\x18\n\x0b\x63h5_current\x18\n \x01(\x02H\t\x88\x01\x01\x12\x18\n\x0b\x63h6_voltage\x18\x0b \x01(\x02H\n\x88\x01\x01\x12\x18\n\x0b\x63h6_current\x18\x0c \x01(\x02H\x0b\x88\x01\x01\x12\x18\n\x0b\x63h7_voltage\x18\r \x01(\x02H\x0c\x88\x01\x01\x12\x18\n\x0b\x63h7_current\x18\x0e \x01(\x02H\r\x88\x01\x01\x12\x18\n\x0b\x63h8_voltage\x18\x0f \x01(\x02H\x0e\x88\x01\x01\x12\x18\n\x0b\x63h8_current\x18\x10 \x01(\x02H\x0f\x88\x01\x01\x42\x0e\n\x0c_ch1_voltageB\x0e\n\x0c_ch1_currentB\x0e\n\x0c_ch2_voltageB\x0e\n\x0c_ch2_currentB\x0e\n\x0c_ch3_voltageB\x0e\n\x0c_ch3_currentB\x0e\n\x0c_ch4_voltageB\x0e\n\x0c_ch4_currentB\x0e\n\x0c_ch5_voltageB\x0e\n\x0c_ch5_currentB\x0e\n\x0c_ch6_voltageB\x0e\n\x0c_ch6_currentB\x0e\n\x0c_ch7_voltageB\x0e\n\x0c_ch7_currentB\x0e\n\x0c_ch8_voltageB\x0e\n\x0c_ch8_current\"\xb1\t\n\x11\x41irQualityMetrics\x12\x1a\n\rpm10_standard\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x1a\n\rpm25_standard\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x1b\n\x0epm100_standard\x18\x03 \x01(\rH\x02\x88\x01\x01\x12\x1f\n\x12pm10_environmental\x18\x04 \x01(\rH\x03\x88\x01\x01\x12\x1f\n\x12pm25_environmental\x18\x05 \x01(\rH\x04\x88\x01\x01\x12 \n\x13pm100_environmental\x18\x06 \x01(\rH\x05\x88\x01\x01\x12\x1b\n\x0eparticles_03um\x18\x07 \x01(\rH\x06\x88\x01\x01\x12\x1b\n\x0eparticles_05um\x18\x08 \x01(\rH\x07\x88\x01\x01\x12\x1b\n\x0eparticles_10um\x18\t \x01(\rH\x08\x88\x01\x01\x12\x1b\n\x0eparticles_25um\x18\n \x01(\rH\t\x88\x01\x01\x12\x1b\n\x0eparticles_50um\x18\x0b \x01(\rH\n\x88\x01\x01\x12\x1c\n\x0fparticles_100um\x18\x0c \x01(\rH\x0b\x88\x01\x01\x12\x10\n\x03\x63o2\x18\r \x01(\rH\x0c\x88\x01\x01\x12\x1c\n\x0f\x63o2_temperature\x18\x0e \x01(\x02H\r\x88\x01\x01\x12\x19\n\x0c\x63o2_humidity\x18\x0f \x01(\x02H\x0e\x88\x01\x01\x12\x1e\n\x11\x66orm_formaldehyde\x18\x10 \x01(\x02H\x0f\x88\x01\x01\x12\x1a\n\rform_humidity\x18\x11 \x01(\x02H\x10\x88\x01\x01\x12\x1d\n\x10\x66orm_temperature\x18\x12 \x01(\x02H\x11\x88\x01\x01\x12\x1a\n\rpm40_standard\x18\x13 \x01(\rH\x12\x88\x01\x01\x12\x1b\n\x0eparticles_40um\x18\x14 \x01(\rH\x13\x88\x01\x01\x12\x1b\n\x0epm_temperature\x18\x15 \x01(\x02H\x14\x88\x01\x01\x12\x18\n\x0bpm_humidity\x18\x16 \x01(\x02H\x15\x88\x01\x01\x12\x17\n\npm_voc_idx\x18\x17 \x01(\x02H\x16\x88\x01\x01\x12\x17\n\npm_nox_idx\x18\x18 \x01(\x02H\x17\x88\x01\x01\x12\x1a\n\rparticles_tps\x18\x19 \x01(\x02H\x18\x88\x01\x01\x42\x10\n\x0e_pm10_standardB\x10\n\x0e_pm25_standardB\x11\n\x0f_pm100_standardB\x15\n\x13_pm10_environmentalB\x15\n\x13_pm25_environmentalB\x16\n\x14_pm100_environmentalB\x11\n\x0f_particles_03umB\x11\n\x0f_particles_05umB\x11\n\x0f_particles_10umB\x11\n\x0f_particles_25umB\x11\n\x0f_particles_50umB\x12\n\x10_particles_100umB\x06\n\x04_co2B\x12\n\x10_co2_temperatureB\x0f\n\r_co2_humidityB\x14\n\x12_form_formaldehydeB\x10\n\x0e_form_humidityB\x13\n\x11_form_temperatureB\x10\n\x0e_pm40_standardB\x11\n\x0f_particles_40umB\x11\n\x0f_pm_temperatureB\x0e\n\x0c_pm_humidityB\r\n\x0b_pm_voc_idxB\r\n\x0b_pm_nox_idxB\x10\n\x0e_particles_tps\"\x94\x03\n\nLocalStats\x12\x16\n\x0euptime_seconds\x18\x01 \x01(\r\x12\x1b\n\x13\x63hannel_utilization\x18\x02 \x01(\x02\x12\x13\n\x0b\x61ir_util_tx\x18\x03 \x01(\x02\x12\x16\n\x0enum_packets_tx\x18\x04 \x01(\r\x12\x16\n\x0enum_packets_rx\x18\x05 \x01(\r\x12\x1a\n\x12num_packets_rx_bad\x18\x06 \x01(\r\x12\x1f\n\x10num_online_nodes\x18\x07 \x01(\rB\x05\x92?\x02\x38\x10\x12\x1e\n\x0fnum_total_nodes\x18\x08 \x01(\rB\x05\x92?\x02\x38\x10\x12\x13\n\x0bnum_rx_dupe\x18\t \x01(\r\x12\x14\n\x0cnum_tx_relay\x18\n \x01(\r\x12\x1d\n\x15num_tx_relay_canceled\x18\x0b \x01(\r\x12\x18\n\x10heap_total_bytes\x18\x0c \x01(\r\x12\x17\n\x0fheap_free_bytes\x18\r \x01(\r\x12\x1d\n\x0enum_tx_dropped\x18\x0e \x01(\rB\x05\x92?\x02\x38\x10\x12\x13\n\x0bnoise_floor\x18\x0f \x01(\x05\"\xe4\x01\n\x16TrafficManagementStats\x12\x19\n\x11packets_inspected\x18\x01 \x01(\r\x12\x1c\n\x14position_dedup_drops\x18\x02 \x01(\r\x12\x1b\n\x13nodeinfo_cache_hits\x18\x03 \x01(\r\x12\x18\n\x10rate_limit_drops\x18\x04 \x01(\r\x12\x1c\n\x14unknown_packet_drops\x18\x05 \x01(\r\x12\x1d\n\x15hop_exhausted_packets\x18\x06 \x01(\r\x12\x1d\n\x15router_hops_preserved\x18\x07 \x01(\r\"\x89\x01\n\rHealthMetrics\x12\x1d\n\theart_bpm\x18\x01 \x01(\rB\x05\x92?\x02\x38\x08H\x00\x88\x01\x01\x12\x18\n\x04spO2\x18\x02 \x01(\rB\x05\x92?\x02\x38\x08H\x01\x88\x01\x01\x12\x18\n\x0btemperature\x18\x03 \x01(\x02H\x02\x88\x01\x01\x42\x0c\n\n_heart_bpmB\x07\n\x05_spO2B\x0e\n\x0c_temperature\"\xae\x02\n\x0bHostMetrics\x12\x16\n\x0euptime_seconds\x18\x01 \x01(\r\x12\x15\n\rfreemem_bytes\x18\x02 \x01(\x04\x12\x17\n\x0f\x64iskfree1_bytes\x18\x03 \x01(\x04\x12\x1c\n\x0f\x64iskfree2_bytes\x18\x04 \x01(\x04H\x00\x88\x01\x01\x12\x1c\n\x0f\x64iskfree3_bytes\x18\x05 \x01(\x04H\x01\x88\x01\x01\x12\x14\n\x05load1\x18\x06 \x01(\rB\x05\x92?\x02\x38\x10\x12\x14\n\x05load5\x18\x07 \x01(\rB\x05\x92?\x02\x38\x10\x12\x15\n\x06load15\x18\x08 \x01(\rB\x05\x92?\x02\x38\x10\x12 \n\x0buser_string\x18\t \x01(\tB\x06\x92?\x03\x08\xc8\x01H\x02\x88\x01\x01\x42\x12\n\x10_diskfree2_bytesB\x12\n\x10_diskfree3_bytesB\x0e\n\x0c_user_string\"\xae\x04\n\tTelemetry\x12\x0c\n\x04time\x18\x01 \x01(\x07\x12<\n\x0e\x64\x65vice_metrics\x18\x02 \x01(\x0b\x32\".meshtastic.protobuf.DeviceMetricsH\x00\x12\x46\n\x13\x65nvironment_metrics\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.EnvironmentMetricsH\x00\x12\x45\n\x13\x61ir_quality_metrics\x18\x04 \x01(\x0b\x32&.meshtastic.protobuf.AirQualityMetricsH\x00\x12:\n\rpower_metrics\x18\x05 \x01(\x0b\x32!.meshtastic.protobuf.PowerMetricsH\x00\x12\x36\n\x0blocal_stats\x18\x06 \x01(\x0b\x32\x1f.meshtastic.protobuf.LocalStatsH\x00\x12<\n\x0ehealth_metrics\x18\x07 \x01(\x0b\x32\".meshtastic.protobuf.HealthMetricsH\x00\x12\x38\n\x0chost_metrics\x18\x08 \x01(\x0b\x32 .meshtastic.protobuf.HostMetricsH\x00\x12O\n\x18traffic_management_stats\x18\t \x01(\x0b\x32+.meshtastic.protobuf.TrafficManagementStatsH\x00\x42\t\n\x07variant\">\n\rNau7802Config\x12\x12\n\nzeroOffset\x18\x01 \x01(\x05\x12\x19\n\x11\x63\x61librationFactor\x18\x02 \x01(\x02\"\xf0\x01\n\nSEN5XState\x12\x1a\n\x12last_cleaning_time\x18\x01 \x01(\r\x12\x1b\n\x13last_cleaning_valid\x18\x02 \x01(\x08\x12\x15\n\rone_shot_mode\x18\x03 \x01(\x08\x12\x1b\n\x0evoc_state_time\x18\x04 \x01(\rH\x00\x88\x01\x01\x12\x1c\n\x0fvoc_state_valid\x18\x05 \x01(\x08H\x01\x88\x01\x01\x12\x1c\n\x0fvoc_state_array\x18\x06 \x01(\x06H\x02\x88\x01\x01\x42\x11\n\x0f_voc_state_timeB\x12\n\x10_voc_state_validB\x12\n\x10_voc_state_array*\xdc\x05\n\x13TelemetrySensorType\x12\x10\n\x0cSENSOR_UNSET\x10\x00\x12\n\n\x06\x42ME280\x10\x01\x12\n\n\x06\x42ME680\x10\x02\x12\x0b\n\x07MCP9808\x10\x03\x12\n\n\x06INA260\x10\x04\x12\n\n\x06INA219\x10\x05\x12\n\n\x06\x42MP280\x10\x06\x12\t\n\x05SHTC3\x10\x07\x12\t\n\x05LPS22\x10\x08\x12\x0b\n\x07QMC6310\x10\t\x12\x0b\n\x07QMI8658\x10\n\x12\x0c\n\x08QMC5883L\x10\x0b\x12\t\n\x05SHT31\x10\x0c\x12\x0c\n\x08PMSA003I\x10\r\x12\x0b\n\x07INA3221\x10\x0e\x12\n\n\x06\x42MP085\x10\x0f\x12\x0c\n\x08RCWL9620\x10\x10\x12\t\n\x05SHT4X\x10\x11\x12\x0c\n\x08VEML7700\x10\x12\x12\x0c\n\x08MLX90632\x10\x13\x12\x0b\n\x07OPT3001\x10\x14\x12\x0c\n\x08LTR390UV\x10\x15\x12\x0e\n\nTSL25911FN\x10\x16\x12\t\n\x05\x41HT10\x10\x17\x12\x10\n\x0c\x44\x46ROBOT_LARK\x10\x18\x12\x0b\n\x07NAU7802\x10\x19\x12\n\n\x06\x42MP3XX\x10\x1a\x12\x0c\n\x08ICM20948\x10\x1b\x12\x0c\n\x08MAX17048\x10\x1c\x12\x11\n\rCUSTOM_SENSOR\x10\x1d\x12\x0c\n\x08MAX30102\x10\x1e\x12\x0c\n\x08MLX90614\x10\x1f\x12\t\n\x05SCD4X\x10 \x12\x0b\n\x07RADSENS\x10!\x12\n\n\x06INA226\x10\"\x12\x10\n\x0c\x44\x46ROBOT_RAIN\x10#\x12\n\n\x06\x44PS310\x10$\x12\x0c\n\x08RAK12035\x10%\x12\x0c\n\x08MAX17261\x10&\x12\x0b\n\x07PCT2075\x10\'\x12\x0b\n\x07\x41\x44S1X15\x10(\x12\x0f\n\x0b\x41\x44S1X15_ALT\x10)\x12\t\n\x05SFA30\x10*\x12\t\n\x05SEN5X\x10+\x12\x0b\n\x07TSL2561\x10,\x12\n\n\x06\x42H1750\x10-\x12\x0b\n\x07HDC1080\x10.\x12\t\n\x05SHT21\x10/\x12\t\n\x05STC31\x10\x30\x12\t\n\x05SCD30\x10\x31\x12\t\n\x05SHTXX\x10\x32\x12\n\n\x06\x44S248X\x10\x33\x12\r\n\tMMC5983MA\x10\x34\x12\r\n\tICM42607P\x10\x35\x42\x65\n\x14org.meshtastic.protoB\x0fTelemetryProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -21,24 +22,54 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.telemet if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\017TelemetryProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _globals['_TELEMETRYSENSORTYPE']._serialized_start=4432 - _globals['_TELEMETRYSENSORTYPE']._serialized_end=5065 - _globals['_DEVICEMETRICS']._serialized_start=61 - _globals['_DEVICEMETRICS']._serialized_end=304 - _globals['_ENVIRONMENTMETRICS']._serialized_start=307 - _globals['_ENVIRONMENTMETRICS']._serialized_end=1205 - _globals['_POWERMETRICS']._serialized_start=1208 - _globals['_POWERMETRICS']._serialized_end=1894 - _globals['_AIRQUALITYMETRICS']._serialized_start=1897 - _globals['_AIRQUALITYMETRICS']._serialized_end=3098 - _globals['_LOCALSTATS']._serialized_start=3101 - _globals['_LOCALSTATS']._serialized_end=3484 - _globals['_HEALTHMETRICS']._serialized_start=3486 - _globals['_HEALTHMETRICS']._serialized_end=3609 - _globals['_HOSTMETRICS']._serialized_start=3612 - _globals['_HOSTMETRICS']._serialized_end=3885 - _globals['_TELEMETRY']._serialized_start=3888 - _globals['_TELEMETRY']._serialized_end=4365 - _globals['_NAU7802CONFIG']._serialized_start=4367 - _globals['_NAU7802CONFIG']._serialized_end=4429 + _ENVIRONMENTMETRICS.fields_by_name['iaq']._options = None + _ENVIRONMENTMETRICS.fields_by_name['iaq']._serialized_options = b'\222?\0028\020' + _ENVIRONMENTMETRICS.fields_by_name['wind_direction']._options = None + _ENVIRONMENTMETRICS.fields_by_name['wind_direction']._serialized_options = b'\222?\0028\020' + _ENVIRONMENTMETRICS.fields_by_name['soil_moisture']._options = None + _ENVIRONMENTMETRICS.fields_by_name['soil_moisture']._serialized_options = b'\222?\0028\010' + _ENVIRONMENTMETRICS.fields_by_name['one_wire_temperature']._options = None + _ENVIRONMENTMETRICS.fields_by_name['one_wire_temperature']._serialized_options = b'\222?\002\020\010' + _LOCALSTATS.fields_by_name['num_online_nodes']._options = None + _LOCALSTATS.fields_by_name['num_online_nodes']._serialized_options = b'\222?\0028\020' + _LOCALSTATS.fields_by_name['num_total_nodes']._options = None + _LOCALSTATS.fields_by_name['num_total_nodes']._serialized_options = b'\222?\0028\020' + _LOCALSTATS.fields_by_name['num_tx_dropped']._options = None + _LOCALSTATS.fields_by_name['num_tx_dropped']._serialized_options = b'\222?\0028\020' + _HEALTHMETRICS.fields_by_name['heart_bpm']._options = None + _HEALTHMETRICS.fields_by_name['heart_bpm']._serialized_options = b'\222?\0028\010' + _HEALTHMETRICS.fields_by_name['spO2']._options = None + _HEALTHMETRICS.fields_by_name['spO2']._serialized_options = b'\222?\0028\010' + _HOSTMETRICS.fields_by_name['load1']._options = None + _HOSTMETRICS.fields_by_name['load1']._serialized_options = b'\222?\0028\020' + _HOSTMETRICS.fields_by_name['load5']._options = None + _HOSTMETRICS.fields_by_name['load5']._serialized_options = b'\222?\0028\020' + _HOSTMETRICS.fields_by_name['load15']._options = None + _HOSTMETRICS.fields_by_name['load15']._serialized_options = b'\222?\0028\020' + _HOSTMETRICS.fields_by_name['user_string']._options = None + _HOSTMETRICS.fields_by_name['user_string']._serialized_options = b'\222?\003\010\310\001' + _globals['_TELEMETRYSENSORTYPE']._serialized_start=5144 + _globals['_TELEMETRYSENSORTYPE']._serialized_end=5876 + _globals['_DEVICEMETRICS']._serialized_start=95 + _globals['_DEVICEMETRICS']._serialized_end=338 + _globals['_ENVIRONMENTMETRICS']._serialized_start=341 + _globals['_ENVIRONMENTMETRICS']._serialized_end=1297 + _globals['_POWERMETRICS']._serialized_start=1300 + _globals['_POWERMETRICS']._serialized_end=1986 + _globals['_AIRQUALITYMETRICS']._serialized_start=1989 + _globals['_AIRQUALITYMETRICS']._serialized_end=3190 + _globals['_LOCALSTATS']._serialized_start=3193 + _globals['_LOCALSTATS']._serialized_end=3597 + _globals['_TRAFFICMANAGEMENTSTATS']._serialized_start=3600 + _globals['_TRAFFICMANAGEMENTSTATS']._serialized_end=3828 + _globals['_HEALTHMETRICS']._serialized_start=3831 + _globals['_HEALTHMETRICS']._serialized_end=3968 + _globals['_HOSTMETRICS']._serialized_start=3971 + _globals['_HOSTMETRICS']._serialized_end=4273 + _globals['_TELEMETRY']._serialized_start=4276 + _globals['_TELEMETRY']._serialized_end=4834 + _globals['_NAU7802CONFIG']._serialized_start=4836 + _globals['_NAU7802CONFIG']._serialized_end=4898 + _globals['_SEN5XSTATE']._serialized_start=4901 + _globals['_SEN5XSTATE']._serialized_end=5141 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/protobuf/telemetry_pb2.pyi b/meshtastic/protobuf/telemetry_pb2.pyi index 23c1025..13a44fb 100644 --- a/meshtastic/protobuf/telemetry_pb2.pyi +++ b/meshtastic/protobuf/telemetry_pb2.pyi @@ -4,7 +4,9 @@ isort:skip_file """ import builtins +import collections.abc import google.protobuf.descriptor +import google.protobuf.internal.containers import google.protobuf.internal.enum_type_wrapper import google.protobuf.message import sys @@ -53,7 +55,7 @@ class _TelemetrySensorTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wra """ SHTC3: _TelemetrySensorType.ValueType # 7 """ - High accuracy temperature and humidity + TODO - REMOVE High accuracy temperature and humidity """ LPS22: _TelemetrySensorType.ValueType # 8 """ @@ -73,7 +75,7 @@ class _TelemetrySensorTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wra """ SHT31: _TelemetrySensorType.ValueType # 12 """ - High accuracy temperature and humidity + TODO - REMOVE High accuracy temperature and humidity """ PMSA003I: _TelemetrySensorType.ValueType # 13 """ @@ -93,7 +95,7 @@ class _TelemetrySensorTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wra """ SHT4X: _TelemetrySensorType.ValueType # 17 """ - Sensirion High accuracy temperature and humidity + TODO - REMOVE Sensirion High accuracy temperature and humidity """ VEML7700: _TelemetrySensorType.ValueType # 18 """ @@ -207,6 +209,38 @@ class _TelemetrySensorTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wra """ BH1750 light sensor """ + HDC1080: _TelemetrySensorType.ValueType # 46 + """ + HDC1080 Temperature and Humidity Sensor + """ + SHT21: _TelemetrySensorType.ValueType # 47 + """ + TODO - REMOVE STH21 Temperature and R. Humidity sensor + """ + STC31: _TelemetrySensorType.ValueType # 48 + """ + Sensirion STC31 CO2 sensor + """ + SCD30: _TelemetrySensorType.ValueType # 49 + """ + SCD30 CO2, humidity, temperature sensor + """ + SHTXX: _TelemetrySensorType.ValueType # 50 + """ + SHT family of sensors for temperature and humidity + """ + DS248X: _TelemetrySensorType.ValueType # 51 + """ + DS248X Bridge for one-wire temperature sensors + """ + MMC5983MA: _TelemetrySensorType.ValueType # 52 + """ + MMC5983MA 3-Axis Digital Magnetic Sensor + """ + ICM42607P: _TelemetrySensorType.ValueType # 53 + """ + ICM-42607-P 6‑Axis IMU + """ class TelemetrySensorType(_TelemetrySensorType, metaclass=_TelemetrySensorTypeEnumTypeWrapper): """ @@ -243,7 +277,7 @@ High accuracy temperature and pressure """ SHTC3: TelemetrySensorType.ValueType # 7 """ -High accuracy temperature and humidity +TODO - REMOVE High accuracy temperature and humidity """ LPS22: TelemetrySensorType.ValueType # 8 """ @@ -263,7 +297,7 @@ QMC5883L: TelemetrySensorType.ValueType # 11 """ SHT31: TelemetrySensorType.ValueType # 12 """ -High accuracy temperature and humidity +TODO - REMOVE High accuracy temperature and humidity """ PMSA003I: TelemetrySensorType.ValueType # 13 """ @@ -283,7 +317,7 @@ RCWL-9620 Doppler Radar Distance Sensor, used for water level detection """ SHT4X: TelemetrySensorType.ValueType # 17 """ -Sensirion High accuracy temperature and humidity +TODO - REMOVE Sensirion High accuracy temperature and humidity """ VEML7700: TelemetrySensorType.ValueType # 18 """ @@ -397,6 +431,38 @@ BH1750: TelemetrySensorType.ValueType # 45 """ BH1750 light sensor """ +HDC1080: TelemetrySensorType.ValueType # 46 +""" +HDC1080 Temperature and Humidity Sensor +""" +SHT21: TelemetrySensorType.ValueType # 47 +""" +TODO - REMOVE STH21 Temperature and R. Humidity sensor +""" +STC31: TelemetrySensorType.ValueType # 48 +""" +Sensirion STC31 CO2 sensor +""" +SCD30: TelemetrySensorType.ValueType # 49 +""" +SCD30 CO2, humidity, temperature sensor +""" +SHTXX: TelemetrySensorType.ValueType # 50 +""" +SHT family of sensors for temperature and humidity +""" +DS248X: TelemetrySensorType.ValueType # 51 +""" +DS248X Bridge for one-wire temperature sensors +""" +MMC5983MA: TelemetrySensorType.ValueType # 52 +""" +MMC5983MA 3-Axis Digital Magnetic Sensor +""" +ICM42607P: TelemetrySensorType.ValueType # 53 +""" +ICM-42607-P 6‑Axis IMU +""" global___TelemetrySensorType = TelemetrySensorType @typing.final @@ -486,6 +552,7 @@ class EnvironmentMetrics(google.protobuf.message.Message): RAINFALL_24H_FIELD_NUMBER: builtins.int SOIL_MOISTURE_FIELD_NUMBER: builtins.int SOIL_TEMPERATURE_FIELD_NUMBER: builtins.int + ONE_WIRE_TEMPERATURE_FIELD_NUMBER: builtins.int temperature: builtins.float """ Temperature measured @@ -576,6 +643,12 @@ class EnvironmentMetrics(google.protobuf.message.Message): """ Soil temperature measured (*C) """ + @property + def one_wire_temperature(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.float]: + """ + One-wire temperature (*C) + """ + def __init__( self, *, @@ -601,9 +674,10 @@ class EnvironmentMetrics(google.protobuf.message.Message): rainfall_24h: builtins.float | None = ..., soil_moisture: builtins.int | None = ..., soil_temperature: builtins.float | None = ..., + one_wire_temperature: collections.abc.Iterable[builtins.float] | None = ..., ) -> None: ... def HasField(self, field_name: typing.Literal["_barometric_pressure", b"_barometric_pressure", "_current", b"_current", "_distance", b"_distance", "_gas_resistance", b"_gas_resistance", "_iaq", b"_iaq", "_ir_lux", b"_ir_lux", "_lux", b"_lux", "_radiation", b"_radiation", "_rainfall_1h", b"_rainfall_1h", "_rainfall_24h", b"_rainfall_24h", "_relative_humidity", b"_relative_humidity", "_soil_moisture", b"_soil_moisture", "_soil_temperature", b"_soil_temperature", "_temperature", b"_temperature", "_uv_lux", b"_uv_lux", "_voltage", b"_voltage", "_weight", b"_weight", "_white_lux", b"_white_lux", "_wind_direction", b"_wind_direction", "_wind_gust", b"_wind_gust", "_wind_lull", b"_wind_lull", "_wind_speed", b"_wind_speed", "barometric_pressure", b"barometric_pressure", "current", b"current", "distance", b"distance", "gas_resistance", b"gas_resistance", "iaq", b"iaq", "ir_lux", b"ir_lux", "lux", b"lux", "radiation", b"radiation", "rainfall_1h", b"rainfall_1h", "rainfall_24h", b"rainfall_24h", "relative_humidity", b"relative_humidity", "soil_moisture", b"soil_moisture", "soil_temperature", b"soil_temperature", "temperature", b"temperature", "uv_lux", b"uv_lux", "voltage", b"voltage", "weight", b"weight", "white_lux", b"white_lux", "wind_direction", b"wind_direction", "wind_gust", b"wind_gust", "wind_lull", b"wind_lull", "wind_speed", b"wind_speed"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["_barometric_pressure", b"_barometric_pressure", "_current", b"_current", "_distance", b"_distance", "_gas_resistance", b"_gas_resistance", "_iaq", b"_iaq", "_ir_lux", b"_ir_lux", "_lux", b"_lux", "_radiation", b"_radiation", "_rainfall_1h", b"_rainfall_1h", "_rainfall_24h", b"_rainfall_24h", "_relative_humidity", b"_relative_humidity", "_soil_moisture", b"_soil_moisture", "_soil_temperature", b"_soil_temperature", "_temperature", b"_temperature", "_uv_lux", b"_uv_lux", "_voltage", b"_voltage", "_weight", b"_weight", "_white_lux", b"_white_lux", "_wind_direction", b"_wind_direction", "_wind_gust", b"_wind_gust", "_wind_lull", b"_wind_lull", "_wind_speed", b"_wind_speed", "barometric_pressure", b"barometric_pressure", "current", b"current", "distance", b"distance", "gas_resistance", b"gas_resistance", "iaq", b"iaq", "ir_lux", b"ir_lux", "lux", b"lux", "radiation", b"radiation", "rainfall_1h", b"rainfall_1h", "rainfall_24h", b"rainfall_24h", "relative_humidity", b"relative_humidity", "soil_moisture", b"soil_moisture", "soil_temperature", b"soil_temperature", "temperature", b"temperature", "uv_lux", b"uv_lux", "voltage", b"voltage", "weight", b"weight", "white_lux", b"white_lux", "wind_direction", b"wind_direction", "wind_gust", b"wind_gust", "wind_lull", b"wind_lull", "wind_speed", b"wind_speed"]) -> None: ... + def ClearField(self, field_name: typing.Literal["_barometric_pressure", b"_barometric_pressure", "_current", b"_current", "_distance", b"_distance", "_gas_resistance", b"_gas_resistance", "_iaq", b"_iaq", "_ir_lux", b"_ir_lux", "_lux", b"_lux", "_radiation", b"_radiation", "_rainfall_1h", b"_rainfall_1h", "_rainfall_24h", b"_rainfall_24h", "_relative_humidity", b"_relative_humidity", "_soil_moisture", b"_soil_moisture", "_soil_temperature", b"_soil_temperature", "_temperature", b"_temperature", "_uv_lux", b"_uv_lux", "_voltage", b"_voltage", "_weight", b"_weight", "_white_lux", b"_white_lux", "_wind_direction", b"_wind_direction", "_wind_gust", b"_wind_gust", "_wind_lull", b"_wind_lull", "_wind_speed", b"_wind_speed", "barometric_pressure", b"barometric_pressure", "current", b"current", "distance", b"distance", "gas_resistance", b"gas_resistance", "iaq", b"iaq", "ir_lux", b"ir_lux", "lux", b"lux", "one_wire_temperature", b"one_wire_temperature", "radiation", b"radiation", "rainfall_1h", b"rainfall_1h", "rainfall_24h", b"rainfall_24h", "relative_humidity", b"relative_humidity", "soil_moisture", b"soil_moisture", "soil_temperature", b"soil_temperature", "temperature", b"temperature", "uv_lux", b"uv_lux", "voltage", b"voltage", "weight", b"weight", "white_lux", b"white_lux", "wind_direction", b"wind_direction", "wind_gust", b"wind_gust", "wind_lull", b"wind_lull", "wind_speed", b"wind_speed"]) -> None: ... @typing.overload def WhichOneof(self, oneof_group: typing.Literal["_barometric_pressure", b"_barometric_pressure"]) -> typing.Literal["barometric_pressure"] | None: ... @typing.overload @@ -1121,6 +1195,64 @@ class LocalStats(google.protobuf.message.Message): global___LocalStats = LocalStats +@typing.final +class TrafficManagementStats(google.protobuf.message.Message): + """ + Traffic management statistics for mesh network optimization + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PACKETS_INSPECTED_FIELD_NUMBER: builtins.int + POSITION_DEDUP_DROPS_FIELD_NUMBER: builtins.int + NODEINFO_CACHE_HITS_FIELD_NUMBER: builtins.int + RATE_LIMIT_DROPS_FIELD_NUMBER: builtins.int + UNKNOWN_PACKET_DROPS_FIELD_NUMBER: builtins.int + HOP_EXHAUSTED_PACKETS_FIELD_NUMBER: builtins.int + ROUTER_HOPS_PRESERVED_FIELD_NUMBER: builtins.int + packets_inspected: builtins.int + """ + Total number of packets inspected by traffic management + """ + position_dedup_drops: builtins.int + """ + Number of position packets dropped due to deduplication + """ + nodeinfo_cache_hits: builtins.int + """ + Number of NodeInfo requests answered from cache + """ + rate_limit_drops: builtins.int + """ + Number of packets dropped due to rate limiting + """ + unknown_packet_drops: builtins.int + """ + Number of unknown/undecryptable packets dropped + """ + hop_exhausted_packets: builtins.int + """ + Number of packets with hop_limit exhausted for local-only broadcast + """ + router_hops_preserved: builtins.int + """ + Number of times router hop preservation was applied + """ + def __init__( + self, + *, + packets_inspected: builtins.int = ..., + position_dedup_drops: builtins.int = ..., + nodeinfo_cache_hits: builtins.int = ..., + rate_limit_drops: builtins.int = ..., + unknown_packet_drops: builtins.int = ..., + hop_exhausted_packets: builtins.int = ..., + router_hops_preserved: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing.Literal["hop_exhausted_packets", b"hop_exhausted_packets", "nodeinfo_cache_hits", b"nodeinfo_cache_hits", "packets_inspected", b"packets_inspected", "position_dedup_drops", b"position_dedup_drops", "rate_limit_drops", b"rate_limit_drops", "router_hops_preserved", b"router_hops_preserved", "unknown_packet_drops", b"unknown_packet_drops"]) -> None: ... + +global___TrafficManagementStats = TrafficManagementStats + @typing.final class HealthMetrics(google.protobuf.message.Message): """ @@ -1256,6 +1388,7 @@ class Telemetry(google.protobuf.message.Message): LOCAL_STATS_FIELD_NUMBER: builtins.int HEALTH_METRICS_FIELD_NUMBER: builtins.int HOST_METRICS_FIELD_NUMBER: builtins.int + TRAFFIC_MANAGEMENT_STATS_FIELD_NUMBER: builtins.int time: builtins.int """ Seconds since 1970 - or 0 for unknown/unset @@ -1302,6 +1435,12 @@ class Telemetry(google.protobuf.message.Message): Linux host metrics """ + @property + def traffic_management_stats(self) -> global___TrafficManagementStats: + """ + Traffic management statistics + """ + def __init__( self, *, @@ -1313,10 +1452,11 @@ class Telemetry(google.protobuf.message.Message): local_stats: global___LocalStats | None = ..., health_metrics: global___HealthMetrics | None = ..., host_metrics: global___HostMetrics | None = ..., + traffic_management_stats: global___TrafficManagementStats | None = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["air_quality_metrics", b"air_quality_metrics", "device_metrics", b"device_metrics", "environment_metrics", b"environment_metrics", "health_metrics", b"health_metrics", "host_metrics", b"host_metrics", "local_stats", b"local_stats", "power_metrics", b"power_metrics", "variant", b"variant"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["air_quality_metrics", b"air_quality_metrics", "device_metrics", b"device_metrics", "environment_metrics", b"environment_metrics", "health_metrics", b"health_metrics", "host_metrics", b"host_metrics", "local_stats", b"local_stats", "power_metrics", b"power_metrics", "time", b"time", "variant", b"variant"]) -> None: ... - def WhichOneof(self, oneof_group: typing.Literal["variant", b"variant"]) -> typing.Literal["device_metrics", "environment_metrics", "air_quality_metrics", "power_metrics", "local_stats", "health_metrics", "host_metrics"] | None: ... + def HasField(self, field_name: typing.Literal["air_quality_metrics", b"air_quality_metrics", "device_metrics", b"device_metrics", "environment_metrics", b"environment_metrics", "health_metrics", b"health_metrics", "host_metrics", b"host_metrics", "local_stats", b"local_stats", "power_metrics", b"power_metrics", "traffic_management_stats", b"traffic_management_stats", "variant", b"variant"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["air_quality_metrics", b"air_quality_metrics", "device_metrics", b"device_metrics", "environment_metrics", b"environment_metrics", "health_metrics", b"health_metrics", "host_metrics", b"host_metrics", "local_stats", b"local_stats", "power_metrics", b"power_metrics", "time", b"time", "traffic_management_stats", b"traffic_management_stats", "variant", b"variant"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["variant", b"variant"]) -> typing.Literal["device_metrics", "environment_metrics", "air_quality_metrics", "power_metrics", "local_stats", "health_metrics", "host_metrics", "traffic_management_stats"] | None: ... global___Telemetry = Telemetry @@ -1347,3 +1487,62 @@ class Nau7802Config(google.protobuf.message.Message): def ClearField(self, field_name: typing.Literal["calibrationFactor", b"calibrationFactor", "zeroOffset", b"zeroOffset"]) -> None: ... global___Nau7802Config = Nau7802Config + +@typing.final +class SEN5XState(google.protobuf.message.Message): + """ + SEN5X State, for saving to flash + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + LAST_CLEANING_TIME_FIELD_NUMBER: builtins.int + LAST_CLEANING_VALID_FIELD_NUMBER: builtins.int + ONE_SHOT_MODE_FIELD_NUMBER: builtins.int + VOC_STATE_TIME_FIELD_NUMBER: builtins.int + VOC_STATE_VALID_FIELD_NUMBER: builtins.int + VOC_STATE_ARRAY_FIELD_NUMBER: builtins.int + last_cleaning_time: builtins.int + """ + Last cleaning time for SEN5X + """ + last_cleaning_valid: builtins.bool + """ + Last cleaning time for SEN5X - valid flag + """ + one_shot_mode: builtins.bool + """ + Config flag for one-shot mode (see admin.proto) + """ + voc_state_time: builtins.int + """ + Last VOC state time for SEN55 + """ + voc_state_valid: builtins.bool + """ + Last VOC state validity flag for SEN55 + """ + voc_state_array: builtins.int + """ + VOC state array (8x uint8t) for SEN55 + """ + def __init__( + self, + *, + last_cleaning_time: builtins.int = ..., + last_cleaning_valid: builtins.bool = ..., + one_shot_mode: builtins.bool = ..., + voc_state_time: builtins.int | None = ..., + voc_state_valid: builtins.bool | None = ..., + voc_state_array: builtins.int | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["_voc_state_array", b"_voc_state_array", "_voc_state_time", b"_voc_state_time", "_voc_state_valid", b"_voc_state_valid", "voc_state_array", b"voc_state_array", "voc_state_time", b"voc_state_time", "voc_state_valid", b"voc_state_valid"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["_voc_state_array", b"_voc_state_array", "_voc_state_time", b"_voc_state_time", "_voc_state_valid", b"_voc_state_valid", "last_cleaning_time", b"last_cleaning_time", "last_cleaning_valid", b"last_cleaning_valid", "one_shot_mode", b"one_shot_mode", "voc_state_array", b"voc_state_array", "voc_state_time", b"voc_state_time", "voc_state_valid", b"voc_state_valid"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_voc_state_array", b"_voc_state_array"]) -> typing.Literal["voc_state_array"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_voc_state_time", b"_voc_state_time"]) -> typing.Literal["voc_state_time"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing.Literal["_voc_state_valid", b"_voc_state_valid"]) -> typing.Literal["voc_state_valid"] | None: ... + +global___SEN5XState = SEN5XState diff --git a/meshtastic/protobuf/xmodem_pb2.py b/meshtastic/protobuf/xmodem_pb2.py index 3c3dec2..772b3f4 100644 --- a/meshtastic/protobuf/xmodem_pb2.py +++ b/meshtastic/protobuf/xmodem_pb2.py @@ -11,9 +11,10 @@ from google.protobuf.internal import builder as _builder _sym_db = _symbol_database.Default() +from meshtastic.protobuf import nanopb_pb2 as meshtastic_dot_protobuf_dot_nanopb__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/protobuf/xmodem.proto\x12\x13meshtastic.protobuf\"\xbf\x01\n\x06XModem\x12\x34\n\x07\x63ontrol\x18\x01 \x01(\x0e\x32#.meshtastic.protobuf.XModem.Control\x12\x0b\n\x03seq\x18\x02 \x01(\r\x12\r\n\x05\x63rc16\x18\x03 \x01(\r\x12\x0e\n\x06\x62uffer\x18\x04 \x01(\x0c\"S\n\x07\x43ontrol\x12\x07\n\x03NUL\x10\x00\x12\x07\n\x03SOH\x10\x01\x12\x07\n\x03STX\x10\x02\x12\x07\n\x03\x45OT\x10\x04\x12\x07\n\x03\x41\x43K\x10\x06\x12\x07\n\x03NAK\x10\x15\x12\x07\n\x03\x43\x41N\x10\x18\x12\t\n\x05\x43TRLZ\x10\x1a\x42\x62\n\x14org.meshtastic.protoB\x0cXmodemProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/protobuf/xmodem.proto\x12\x13meshtastic.protobuf\x1a meshtastic/protobuf/nanopb.proto\"\xd5\x01\n\x06XModem\x12\x34\n\x07\x63ontrol\x18\x01 \x01(\x0e\x32#.meshtastic.protobuf.XModem.Control\x12\x12\n\x03seq\x18\x02 \x01(\rB\x05\x92?\x02\x38\x10\x12\x14\n\x05\x63rc16\x18\x03 \x01(\rB\x05\x92?\x02\x38\x10\x12\x16\n\x06\x62uffer\x18\x04 \x01(\x0c\x42\x06\x92?\x03\x08\x80\x01\"S\n\x07\x43ontrol\x12\x07\n\x03NUL\x10\x00\x12\x07\n\x03SOH\x10\x01\x12\x07\n\x03STX\x10\x02\x12\x07\n\x03\x45OT\x10\x04\x12\x07\n\x03\x41\x43K\x10\x06\x12\x07\n\x03NAK\x10\x15\x12\x07\n\x03\x43\x41N\x10\x18\x12\t\n\x05\x43TRLZ\x10\x1a\x42\x62\n\x14org.meshtastic.protoB\x0cXmodemProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -21,8 +22,14 @@ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.xmodem_ if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\014XmodemProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000' - _globals['_XMODEM']._serialized_start=58 - _globals['_XMODEM']._serialized_end=249 - _globals['_XMODEM_CONTROL']._serialized_start=166 - _globals['_XMODEM_CONTROL']._serialized_end=249 + _XMODEM.fields_by_name['seq']._options = None + _XMODEM.fields_by_name['seq']._serialized_options = b'\222?\0028\020' + _XMODEM.fields_by_name['crc16']._options = None + _XMODEM.fields_by_name['crc16']._serialized_options = b'\222?\0028\020' + _XMODEM.fields_by_name['buffer']._options = None + _XMODEM.fields_by_name['buffer']._serialized_options = b'\222?\003\010\200\001' + _globals['_XMODEM']._serialized_start=92 + _globals['_XMODEM']._serialized_end=305 + _globals['_XMODEM_CONTROL']._serialized_start=222 + _globals['_XMODEM_CONTROL']._serialized_end=305 # @@protoc_insertion_point(module_scope) diff --git a/meshtastic/serial_interface.py b/meshtastic/serial_interface.py index 88f17de..758ee2c 100644 --- a/meshtastic/serial_interface.py +++ b/meshtastic/serial_interface.py @@ -35,8 +35,6 @@ class SerialInterface(StreamInterface): debugOut {stream} -- If a stream is provided, any debug serial output from the device will be emitted to that stream. (default: {None}) timeout -- How long to wait for replies (default: 300 seconds) """ - self.noProto = noProto - self.devPath: Optional[str] = devPath if self.devPath is None: @@ -52,22 +50,28 @@ class SerialInterface(StreamInterface): else: self.devPath = ports[0] + StreamInterface.__init__( + self, debugOut=debugOut, noProto=noProto, connectNow=connectNow, noNodes=noNodes, timeout=timeout + ) + + def connect(self) -> None: logger.debug(f"Connecting to {self.devPath}") + dev_path = self.devPath + if dev_path is None: + raise RuntimeError("Serial device path is not set") if sys.platform != "win32": - with open(self.devPath, encoding="utf8") as f: + with open(dev_path, encoding="utf8") as f: self._set_hupcl_with_termios(f) time.sleep(0.1) self.stream = serial.Serial( - self.devPath, 115200, exclusive=True, timeout=0.5, write_timeout=0 + dev_path, 115200, exclusive=True, timeout=0.5, write_timeout=0 ) self.stream.flush() # type: ignore[attr-defined] time.sleep(0.1) - StreamInterface.__init__( - self, debugOut=debugOut, noProto=noProto, connectNow=connectNow, noNodes=noNodes, timeout=timeout - ) + super().connect() def _set_hupcl_with_termios(self, f: TextIOWrapper): """first we need to set the HUPCL so the device will not reboot based on RTS and/or DTR diff --git a/meshtastic/stream_interface.py b/meshtastic/stream_interface.py index 06ee28a..584079f 100644 --- a/meshtastic/stream_interface.py +++ b/meshtastic/stream_interface.py @@ -1,5 +1,6 @@ """Stream Interface base class """ +import contextlib import io import logging import threading @@ -39,15 +40,14 @@ class StreamInterface(MeshInterface): timeout -- How long to wait for replies (default: 300 seconds) Raises: - Exception: [description] - Exception: [description] + RuntimeError: Raised if StreamInterface is instantiated when noProto is false. """ - if not hasattr(self, "stream") and not noProto: - raise Exception( # pylint: disable=W0719 + if not noProto and type(self) == StreamInterface: # pylint: disable=C0123 + raise RuntimeError( "StreamInterface is now abstract (to update existing code create SerialInterface instead)" ) - self.stream: Optional[serial.Serial] # only serial uses this, TCPInterface overrides the relevant methods instead + self.stream: Optional[serial.Serial] = None # only serial uses this, TCPInterface overrides the relevant methods instead self._rxBuf = bytes() # empty self._wantExit = False @@ -61,9 +61,17 @@ class StreamInterface(MeshInterface): # Start the reader thread after superclass constructor completes init if connectNow: - self.connect() - if not noProto: - self.waitForConfig() + try: + self.connect() + if not noProto: + self.waitForConfig() + except Exception: + # If the handshake raises, the caller never receives a reference + # to this instance and cannot call close() themselves. Clean up + # the reader thread + stream here so retries don't leak. + with contextlib.suppress(Exception): + self.close() + raise def connect(self) -> None: """Connect to our radio @@ -136,7 +144,16 @@ class StreamInterface(MeshInterface): # reader thread to close things for us self._wantExit = True if self._rxThread != threading.current_thread(): - self._rxThread.join() # wait for it to exit + try: + self._rxThread.join() # wait for it to exit + except RuntimeError: + # Thread was never started — happens when close() is invoked + # from a failed __init__ before connect() could spawn it. + # In this case there is no reader thread to close the stream. + if self.stream is not None: + with contextlib.suppress(Exception): + self.stream.close() + self.stream = None def _handleLogByte(self, b): """Handle a byte that is part of a log message from the device.""" diff --git a/meshtastic/tcp_interface.py b/meshtastic/tcp_interface.py index efa0950..670335c 100644 --- a/meshtastic/tcp_interface.py +++ b/meshtastic/tcp_interface.py @@ -33,20 +33,12 @@ class TCPInterface(StreamInterface): hostname {string} -- Hostname/IP address of the device to connect to timeout -- How long to wait for replies (default: 300 seconds) """ - - self.stream = None - self.hostname: str = hostname self.portNumber: int = portNumber self.socket: Optional[socket.socket] = None self.reconnectLock = threading.Lock() - if connectNow: - self.myConnect() - else: - self.socket = None - super().__init__( debugOut=debugOut, noProto=noProto, @@ -77,8 +69,13 @@ class TCPInterface(StreamInterface): if self.socket is not None: self.socket.shutdown(socket.SHUT_RDWR) + def connect(self) -> None: + """Connect the interface""" + self.myConnect() + super().connect() + def myConnect(self) -> None: - """Connect to socket.""" + """Connect to socket (without attempting to start the interface's receive thread)""" logger.debug(f"Connecting to {self.hostname}") # type: ignore[str-bytes-safe] server_address = (self.hostname, self.portNumber) self.socket = socket.create_connection(server_address) diff --git a/meshtastic/tests/test_inject_nanopb_options.py b/meshtastic/tests/test_inject_nanopb_options.py new file mode 100644 index 0000000..852b72b --- /dev/null +++ b/meshtastic/tests/test_inject_nanopb_options.py @@ -0,0 +1,646 @@ +"""Tests for bin/inject_nanopb_options.py — the nanopb options injection script +and the generated protobuf descriptors it produces. + +Part 1 (test_parse_*, test_inject_*): unit-tests the script's logic directly, +using small synthetic proto snippets. + +Part 2 (test_descriptor_*): smoke-tests the already-generated _pb2.py files to +confirm the regen pipeline embedded the expected nanopb options. +""" + +import importlib.util +import sys +import textwrap +from pathlib import Path +from unittest.mock import patch + +import pytest +from hypothesis import given, strategies as st + +from meshtastic.protobuf import ( + atak_pb2, + config_pb2, + mesh_pb2, + nanopb_pb2, + telemetry_pb2, +) + +# --------------------------------------------------------------------------- +# Load bin/inject_nanopb_options.py as a module without adding it to the +# package. __main__ guard means no side-effects on import. +# --------------------------------------------------------------------------- +_SCRIPT_PATH = Path(__file__).parent.parent.parent / "bin" / "inject_nanopb_options.py" + + +def _load_inject_module(): + spec = importlib.util.spec_from_file_location("inject_nanopb_options", _SCRIPT_PATH) + mod = importlib.util.module_from_spec(spec) + with patch.object(sys, "argv", ["inject_nanopb_options.py"]): + spec.loader.exec_module(mod) + return mod + + +_inj = _load_inject_module() + +parse_value = _inj.parse_value +parse_options_file = _inj.parse_options_file +format_nanopb_opts = _inj.format_nanopb_opts +inject_into_proto = _inj.inject_into_proto +message_path_matches = _inj.message_path_matches + +# Convenience: the nanopb import path the script uses after the sed fixup +NANOPB_IMPORT = 'import "meshtastic/protobuf/nanopb.proto";' + + +# =========================================================================== +# Part 1 — Script unit tests +# =========================================================================== + +# --------------------------------------------------------------------------- +# parse_value +# --------------------------------------------------------------------------- + + +@pytest.mark.unit +def test_parse_value_integer(): + """parse_value converts a decimal string to int.""" + assert parse_value("40") == 40 + + +@pytest.mark.unit +def test_parse_value_negative_integer(): + """parse_value handles negative integer strings.""" + assert parse_value("-1") == -1 + + +@pytest.mark.unit +def test_parse_value_true(): + """parse_value converts 'true' to Python True.""" + assert parse_value("true") is True + + +@pytest.mark.unit +def test_parse_value_false(): + """parse_value converts 'false' to Python False.""" + assert parse_value("false") is False + + +@pytest.mark.unit +def test_parse_value_string(): + """parse_value returns non-numeric, non-boolean strings as-is.""" + assert parse_value("IS_8") == "IS_8" + + +@pytest.mark.unit +@given(st.integers()) +def test_parse_value_any_integer_returns_int(n): + """parse_value always returns int for any decimal integer string.""" + assert parse_value(str(n)) == n + + +@pytest.mark.unit +@given(st.text()) +def test_parse_value_never_crashes(s): + """parse_value never raises on arbitrary input.""" + result = parse_value(s) + assert isinstance(result, (int, bool, str)) + + +@pytest.mark.unit +@given(st.text().filter(lambda s: not s.lstrip("-").isdigit() and s.lower() not in ("true", "false"))) +def test_parse_value_non_numeric_non_bool_returns_str(s): + """parse_value returns the original string when it is neither an integer nor a boolean.""" + assert parse_value(s) == s + + +# --------------------------------------------------------------------------- +# parse_options_file +# --------------------------------------------------------------------------- + + +def _write_options(tmp_path: Path, content: str) -> Path: + p = tmp_path / "test.options" + p.write_text(textwrap.dedent(content)) + return p + + +@pytest.mark.unit +def test_parse_wildcard(tmp_path): + """Wildcard pattern (no dot) lands in the wildcard dict.""" + f = _write_options(tmp_path, "*macaddr max_size:6 fixed_length:true\n") + specific, wildcard = parse_options_file(f) + assert "macaddr" in wildcard + assert wildcard["macaddr"] == {"max_size": 6, "fixed_length": True} + assert specific == {} + + +@pytest.mark.unit +def test_parse_specific(tmp_path): + """Single-dot pattern lands in the specific dict with a 2-tuple key.""" + f = _write_options(tmp_path, "*User.long_name max_size:40\n") + specific, wildcard = parse_options_file(f) + assert ("User", "long_name") in specific + assert specific[("User", "long_name")] == {"max_size": 40} + assert wildcard == {} + + +@pytest.mark.unit +def test_parse_multilevel(tmp_path): + """Three-part pattern (Route.Link.uid) produces a 3-tuple key.""" + f = _write_options(tmp_path, "*Route.Link.uid max_size:48\n") + specific, _ = parse_options_file(f) + assert ("Route", "Link", "uid") in specific + assert specific[("Route", "Link", "uid")] == {"max_size": 48} + + +@pytest.mark.unit +def test_parse_strips_inline_comments(tmp_path): + """Text after # is ignored.""" + f = _write_options(tmp_path, "*id max_size:16 # node id strings\n") + _, wildcard = parse_options_file(f) + assert wildcard["id"] == {"max_size": 16} + + +@pytest.mark.unit +def test_parse_skips_comment_only_lines(tmp_path): + """Lines that are entirely comments produce no entries.""" + f = _write_options(tmp_path, "# this is a comment\n*id max_size:16\n") + _, wildcard = parse_options_file(f) + assert list(wildcard.keys()) == ["id"] + + +@pytest.mark.unit +def test_parse_skips_blank_lines(tmp_path): + """Blank lines are silently ignored.""" + f = _write_options(tmp_path, "\n\n*id max_size:16\n\n") + _, wildcard = parse_options_file(f) + assert "id" in wildcard + + +@pytest.mark.unit +def test_parse_skips_non_python_options(tmp_path): + """Options not in FIELD_OPTIONS (e.g. anonymous_oneof) are dropped.""" + f = _write_options(tmp_path, "*MeshPacket.payload_variant anonymous_oneof:true\n") + specific, wildcard = parse_options_file(f) + # anonymous_oneof is not in FIELD_OPTIONS → no entry should be produced + assert specific == {} + assert wildcard == {} + + +@pytest.mark.unit +def test_parse_merges_repeated_patterns(tmp_path): + """Two lines for the same pattern are merged.""" + f = _write_options( + tmp_path, + "*SecurityConfig.admin_key max_size:32\n" + "*SecurityConfig.admin_key max_count:3\n", + ) + specific, _ = parse_options_file(f) + assert specific[("SecurityConfig", "admin_key")] == {"max_size": 32, "max_count": 3} + + +@pytest.mark.unit +def test_parse_int_and_bool_values(tmp_path): + """int_size parses as int; fixed_length parses as bool.""" + f = _write_options(tmp_path, "*Data.payload max_size:233 fixed_length:false\n") + specific, _ = parse_options_file(f) + opts = specific[("Data", "payload")] + assert opts["max_size"] == 233 + assert opts["fixed_length"] is False + + +# --------------------------------------------------------------------------- +# message_path_matches +# --------------------------------------------------------------------------- + + +@pytest.mark.unit +def test_message_path_matches_simple(): + """A single-element path matches the current message on the stack.""" + stack = [("message", "User")] + assert message_path_matches(stack, ("User",)) + + +@pytest.mark.unit +def test_message_path_matches_nested(): + """Both a 1-element and 2-element path match correctly against a nested stack.""" + stack = [("message", "Config"), ("message", "DeviceConfig")] + assert message_path_matches(stack, ("DeviceConfig",)) + assert message_path_matches(stack, ("Config", "DeviceConfig")) + + +@pytest.mark.unit +def test_message_path_matches_with_oneof_in_stack(): + """oneof frames in the stack are skipped when looking for messages.""" + stack = [("message", "MeshPacket"), ("oneof", "payload_variant")] + assert message_path_matches(stack, ("MeshPacket",)) + + +@pytest.mark.unit +def test_message_path_no_match(): + """A path with the wrong message name does not match.""" + stack = [("message", "User")] + assert not message_path_matches(stack, ("Route",)) + + +@pytest.mark.unit +def test_message_path_multilevel_partial_match(): + """A 2-element path must match the last 2 message names on the stack.""" + stack = [("message", "Route"), ("message", "Link")] + assert message_path_matches(stack, ("Route", "Link")) + assert not message_path_matches(stack, ("Other", "Link")) + + +# --------------------------------------------------------------------------- +# format_nanopb_opts +# --------------------------------------------------------------------------- + + +@pytest.mark.unit +def test_format_max_size(): + """max_size is rendered as an integer literal.""" + assert format_nanopb_opts({"max_size": 40}) == "(nanopb).max_size = 40" + + +@pytest.mark.unit +def test_format_int_size_as_enum(): + """int_size numeric values are rendered as IS_8/IS_16/IS_32/IS_64 enum names.""" + assert format_nanopb_opts({"int_size": 8}) == "(nanopb).int_size = IS_8" + assert format_nanopb_opts({"int_size": 16}) == "(nanopb).int_size = IS_16" + assert format_nanopb_opts({"int_size": 32}) == "(nanopb).int_size = IS_32" + assert format_nanopb_opts({"int_size": 64}) == "(nanopb).int_size = IS_64" + + +@pytest.mark.unit +def test_format_bool_true(): + """True is rendered as the proto literal 'true'.""" + assert format_nanopb_opts({"fixed_length": True}) == "(nanopb).fixed_length = true" + + +@pytest.mark.unit +def test_format_bool_false(): + """False is rendered as the proto literal 'false'.""" + assert format_nanopb_opts({"fixed_length": False}) == "(nanopb).fixed_length = false" + + +# --------------------------------------------------------------------------- +# inject_into_proto — helpers +# --------------------------------------------------------------------------- + +_NANOPB_IMPORT_PATH = "meshtastic/protobuf/nanopb.proto" + + +def _inject(proto_src: str, specific=None, wildcard=None) -> str: + """Run inject_into_proto with empty dicts as defaults.""" + return inject_into_proto( + textwrap.dedent(proto_src), + specific or {}, + wildcard or {}, + _NANOPB_IMPORT_PATH, + ) + + +# --------------------------------------------------------------------------- +# inject_into_proto — option injection +# --------------------------------------------------------------------------- + + +@pytest.mark.unit +def test_inject_adds_option_to_plain_field(): + """A field with no existing options gets a nanopb annotation.""" + proto = """\ + syntax = "proto3"; + import "meshtastic/protobuf/channel.proto"; + message User { + string long_name = 1; + } + """ + result = _inject(proto, specific={("User", "long_name"): {"max_size": 40}}) + assert "long_name = 1 [(nanopb).max_size = 40];" in result + + +@pytest.mark.unit +def test_inject_merges_with_existing_options(): + """nanopb annotation is appended after existing field options.""" + proto = """\ + syntax = "proto3"; + import "meshtastic/protobuf/channel.proto"; + message User { + bytes macaddr = 4 [deprecated = true]; + } + """ + result = _inject(proto, wildcard={"macaddr": {"max_size": 6}}) + assert "[deprecated = true, (nanopb).max_size = 6];" in result + + +@pytest.mark.unit +def test_inject_int_size_uses_enum_name(): + """int_size values are written as IS_N enum names, not raw integers.""" + proto = """\ + syntax = "proto3"; + import "meshtastic/protobuf/mesh.proto"; + message Foo { + uint32 hop_limit = 9; + } + """ + result = _inject(proto, specific={("Foo", "hop_limit"): {"int_size": 8}}) + assert "(nanopb).int_size = IS_8" in result + + +@pytest.mark.unit +def test_inject_wildcard_applied_across_messages(): + """A wildcard option hits the matching field in every message.""" + proto = """\ + syntax = "proto3"; + import "meshtastic/protobuf/mesh.proto"; + message A { + bytes macaddr = 1; + } + message B { + bytes macaddr = 2; + } + """ + result = _inject(proto, wildcard={"macaddr": {"max_size": 6}}) + assert result.count("(nanopb).max_size = 6") == 2 + + +@pytest.mark.unit +def test_inject_specific_not_leaking_to_other_messages(): + """A message-specific option does NOT apply to a different message's field.""" + proto = """\ + syntax = "proto3"; + import "meshtastic/protobuf/mesh.proto"; + message User { + string id = 1; + } + message Other { + string id = 1; + } + """ + result = _inject(proto, specific={("User", "id"): {"max_size": 16}}) + # Easier: count annotations — should be exactly one + assert result.count("(nanopb).max_size = 16") == 1 + + +@pytest.mark.unit +def test_inject_nested_message(): + """A 2-part specific key only hits the field in the correct nested message.""" + proto = """\ + syntax = "proto3"; + import "meshtastic/protobuf/mesh.proto"; + message Route { + message Link { + string uid = 1; + } + string uid = 2; + } + """ + # Route.Link.uid → key = ('Route', 'Link', 'uid') + result = _inject(proto, specific={("Route", "Link", "uid"): {"max_size": 48}}) + lines = result.splitlines() + # Only the uid inside Link should have the annotation + assert result.count("(nanopb).max_size = 48") == 1 + # Confirm it's the inner one (it has 4 spaces more indent than outer uid) + annotated = next(l for l in lines if "(nanopb).max_size = 48" in l) + plain = next(l for l in lines if "uid = 2" in l) + assert annotated.index("uid") > plain.index("uid") + + +@pytest.mark.unit +def test_inject_skips_enum_body_values(): + """Enum value lines must not be treated as field declarations.""" + proto = """\ + syntax = "proto3"; + message Foo { + enum Role { + CLIENT = 0; + ROUTER = 2; + } + Role role = 1; + } + """ + # Wildcard for 'role' should only hit the field, not enum values + result = _inject(proto, wildcard={"role": {"max_size": 8}}) + assert result.count("(nanopb)") == 1 + assert "(nanopb)" not in next(l for l in result.splitlines() if "CLIENT" in l) + + +@pytest.mark.unit +def test_inject_optional_qualifier_preserved(): + """The 'optional' qualifier is kept when a field gets an annotation.""" + proto = """\ + syntax = "proto3"; + import "meshtastic/protobuf/mesh.proto"; + message Foo { + optional uint32 altitude = 3; + } + """ + result = _inject(proto, specific={("Foo", "altitude"): {"int_size": 16}}) + assert "optional uint32 altitude = 3 [(nanopb).int_size = IS_16];" in result + + +@pytest.mark.unit +def test_inject_repeated_qualifier_preserved(): + """The 'repeated' qualifier is kept when a field gets an annotation.""" + proto = """\ + syntax = "proto3"; + import "meshtastic/protobuf/mesh.proto"; + message Foo { + repeated int32 snr = 2; + } + """ + result = _inject(proto, specific={("Foo", "snr"): {"max_count": 8}}) + assert "repeated int32 snr = 2 [(nanopb).max_count = 8];" in result + + +@pytest.mark.unit +def test_inject_multiple_options_on_one_field(): + """Multiple options from the same pattern are all injected on one field.""" + proto = """\ + syntax = "proto3"; + import "meshtastic/protobuf/mesh.proto"; + message Foo { + repeated int32 snr = 1; + } + """ + result = _inject(proto, specific={("Foo", "snr"): {"max_count": 8, "int_size": 8}}) + assert "(nanopb).max_count = 8" in result + assert "(nanopb).int_size = IS_8" in result + + +# --------------------------------------------------------------------------- +# inject_into_proto — import insertion +# --------------------------------------------------------------------------- + + +@pytest.mark.unit +def test_inject_adds_nanopb_import_when_absent(): + """nanopb.proto import is added when the file has other imports.""" + proto = """\ + syntax = "proto3"; + import "meshtastic/protobuf/mesh.proto"; + message Foo { + string name = 1; + } + """ + result = _inject(proto, wildcard={"name": {"max_size": 30}}) + assert NANOPB_IMPORT in result + + +@pytest.mark.unit +def test_inject_no_duplicate_nanopb_import(): + """nanopb.proto import is NOT added a second time if already present.""" + proto = """\ + syntax = "proto3"; + import "meshtastic/protobuf/mesh.proto"; + import "meshtastic/protobuf/nanopb.proto"; + message Foo { + string name = 1; + } + """ + result = _inject(proto, wildcard={"name": {"max_size": 30}}) + assert result.count(NANOPB_IMPORT) == 1 + + +@pytest.mark.unit +def test_inject_import_placed_after_existing_imports(): + """nanopb import appears after the last existing import, not at the top.""" + proto = """\ + syntax = "proto3"; + import "meshtastic/protobuf/mesh.proto"; + message Foo { + string name = 1; + } + """ + result = _inject(proto, wildcard={"name": {"max_size": 30}}) + lines = result.splitlines() + mesh_idx = next(i for i, l in enumerate(lines) if "mesh.proto" in l) + nanopb_idx = next(i for i, l in enumerate(lines) if "nanopb.proto" in l) + assert nanopb_idx == mesh_idx + 1 + + +@pytest.mark.unit +def test_inject_import_after_syntax_when_no_existing_imports(): + """When a proto has no imports, nanopb import goes AFTER the syntax line, + not before it (regression test for the last_import_idx == -1 bug).""" + proto = """\ + syntax = "proto3"; + message XModem { + uint32 seq = 2; + } + """ + result = _inject(proto, specific={("XModem", "seq"): {"int_size": 16}}) + lines = result.splitlines() + syntax_idx = next(i for i, l in enumerate(lines) if l.strip().startswith("syntax")) + nanopb_idx = next(i for i, l in enumerate(lines) if "nanopb.proto" in l) + assert nanopb_idx > syntax_idx, "nanopb import must come after the syntax line" + # syntax line must still be first non-blank line + first_non_blank = next(l.strip() for l in lines if l.strip()) + assert first_non_blank.startswith("syntax") + + +@pytest.mark.unit +def test_inject_noop_when_no_options(): + """Proto file is returned unchanged when there are no options to inject.""" + proto = 'syntax = "proto3";\nmessage Foo { string x = 1; }\n' + result = _inject(proto) + assert result == proto + + +# =========================================================================== +# Part 2 — Descriptor integration tests +# Verify that regen-protobufs.sh produced _pb2.py files with nanopb options +# embedded in the serialized descriptors. +# =========================================================================== + + +def _field_opts(descriptor, *path): + """Walk a descriptor by field/nested-type path and return its nanopb opts. + + Elements of *path that are message names are looked up in nested_types_by_name; + the final element is looked up in fields_by_name. + """ + desc = descriptor + for step in path[:-1]: + desc = desc.nested_types_by_name[step] + field = desc.fields_by_name[path[-1]] + return field.GetOptions().Extensions[nanopb_pb2.nanopb] + + +@pytest.mark.unit +def test_descriptor_user_long_name(): + """User.long_name has max_size = 40 from mesh.options.""" + opts = _field_opts(mesh_pb2.DESCRIPTOR.message_types_by_name["User"], "long_name") + assert opts.max_size == 40 + + +@pytest.mark.unit +def test_descriptor_user_short_name(): + """User.short_name has max_size = 5 from mesh.options.""" + opts = _field_opts(mesh_pb2.DESCRIPTOR.message_types_by_name["User"], "short_name") + assert opts.max_size == 5 + + +@pytest.mark.unit +def test_descriptor_wildcard_macaddr(): + """Wildcard option from mesh.options applied to User.macaddr.""" + opts = _field_opts(mesh_pb2.DESCRIPTOR.message_types_by_name["User"], "macaddr") + assert opts.max_size == 6 + assert opts.fixed_length is True + + +@pytest.mark.unit +def test_descriptor_meshpacket_hop_limit(): + """MeshPacket.hop_limit has int_size = IS_8 from mesh.options.""" + opts = _field_opts(mesh_pb2.DESCRIPTOR.message_types_by_name["MeshPacket"], "hop_limit") + assert opts.int_size == nanopb_pb2.IS_8 + + +@pytest.mark.unit +def test_descriptor_routediscovery_snr_towards(): + """RouteDiscovery.snr_towards has max_count = 8 and int_size = IS_8 from mesh.options.""" + opts = _field_opts( + mesh_pb2.DESCRIPTOR.message_types_by_name["RouteDiscovery"], "snr_towards" + ) + assert opts.max_count == 8 + assert opts.int_size == nanopb_pb2.IS_8 + + +@pytest.mark.unit +def test_descriptor_data_payload(): + """Data.payload has max_size = 233 from mesh.options.""" + opts = _field_opts(mesh_pb2.DESCRIPTOR.message_types_by_name["Data"], "payload") + assert opts.max_size == 233 + + +@pytest.mark.unit +def test_descriptor_nested_deviceconfig_tzdef(): + """Config.DeviceConfig.tzdef — option on a field inside a nested message.""" + config = config_pb2.DESCRIPTOR.message_types_by_name["Config"] + opts = _field_opts(config, "DeviceConfig", "tzdef") + assert opts.max_size == 65 + + +@pytest.mark.unit +def test_descriptor_nested_securityconfig_admin_key(): + """Config.SecurityConfig.admin_key — two options merged from two .options lines.""" + config = config_pb2.DESCRIPTOR.message_types_by_name["Config"] + opts = _field_opts(config, "SecurityConfig", "admin_key") + assert opts.max_size == 32 + assert opts.max_count == 3 + + +@pytest.mark.unit +def test_descriptor_multilevel_nested_route_link_uid(): + """Route.Link.uid — three-level nested pattern from atak.options.""" + route = atak_pb2.DESCRIPTOR.message_types_by_name["Route"] + opts = _field_opts(route, "Link", "uid") + assert opts.max_size == 48 + + +@pytest.mark.unit +def test_descriptor_telemetry_environment_one_wire_temperature(): + """EnvironmentMetrics.one_wire_temperature has max_count = 8 from telemetry.options.""" + env = telemetry_pb2.DESCRIPTOR.message_types_by_name["EnvironmentMetrics"] + opts = _field_opts(env, "one_wire_temperature") + assert opts.max_count == 8 diff --git a/meshtastic/tests/test_main.py b/meshtastic/tests/test_main.py index 251de98..b664665 100644 --- a/meshtastic/tests/test_main.py +++ b/meshtastic/tests/test_main.py @@ -6,6 +6,8 @@ import os import platform import re import sys +import tempfile +from types import SimpleNamespace from unittest.mock import mock_open, MagicMock, patch import pytest @@ -1721,11 +1723,9 @@ def test_main_onReceive_with_sendtext(caplog, capsys): @pytest.mark.unit @pytest.mark.usefixtures("reset_mt_config") -def test_main_onReceive_with_text(caplog, capsys): - """Test onReceive with text""" - args = MagicMock() - args.sendtext.return_value = "foo" - mt_config.args = args +def test_main_onReceive_with_text_replies_on_target_channel(caplog, capsys): + """Test onReceive replies when channel matches --ch-index (default 0).""" + mt_config.args = SimpleNamespace(reply=True, ch_index=0, sendtext=None) # Note: 'TEXT_MESSAGE_APP' value is 1 # Note: Some of this is faked below. @@ -1751,6 +1751,83 @@ def test_main_onReceive_with_text(caplog, capsys): assert re.search(r"in onReceive", caplog.text, re.MULTILINE) out, err = capsys.readouterr() assert re.search(r"Sending reply", out, re.MULTILINE) + iface.sendText.assert_called_once_with( + "got msg 'faked' with rxSnr: 6.0 and hopLimit: 3", channelIndex=0 + ) + assert err == "" + + +@pytest.mark.unit +@pytest.mark.usefixtures("reset_mt_config") +def test_main_onReceive_with_text_ignores_non_target_channel(caplog, capsys): + """Test onReceive does not reply when packet channel differs from --ch-index.""" + mt_config.args = SimpleNamespace(reply=True, ch_index=1, sendtext=None) + + packet = { + "to": 4294967295, + "decoded": {"portnum": 1, "payload": "hello", "text": "faked"}, + "id": 334776977, + "hop_limit": 3, + "want_ack": True, + "rxSnr": 6.0, + "hopLimit": 3, + "raw": "faked", + "fromId": "!28b5465c", + "toId": "^all", + "channel": 0, + } + + iface = MagicMock(autospec=SerialInterface) + iface.myInfo.my_node_num = 4294967295 + + with patch("meshtastic.serial_interface.SerialInterface", return_value=iface): + with caplog.at_level(logging.DEBUG): + onReceive(packet, iface) + assert re.search(r"in onReceive", caplog.text, re.MULTILINE) + out, err = capsys.readouterr() + assert re.search( + r"Ignored message on channel 0 \(waiting for channel 1\)", out, re.MULTILINE + ) + iface.sendText.assert_not_called() + assert err == "" + + +@pytest.mark.unit +@pytest.mark.usefixtures("reset_mt_config") +def test_main_onReceive_with_text_replies_on_explicit_matching_channel(caplog, capsys): + """Test onReceive replies when explicit packet channel matches --ch-index.""" + mt_config.args = SimpleNamespace(reply=True, ch_index=2, sendtext=None) + + packet = { + "to": 4294967295, + "decoded": {"portnum": 1, "payload": "hello", "text": "faked"}, + "id": 334776977, + "hop_limit": 3, + "want_ack": True, + "rxSnr": 6.0, + "hopLimit": 3, + "raw": "faked", + "fromId": "!28b5465c", + "toId": "^all", + "channel": 2, + } + + iface = MagicMock(autospec=SerialInterface) + iface.myInfo.my_node_num = 4294967295 + + with patch("meshtastic.serial_interface.SerialInterface", return_value=iface): + with caplog.at_level(logging.DEBUG): + onReceive(packet, iface) + assert re.search(r"in onReceive", caplog.text, re.MULTILINE) + out, err = capsys.readouterr() + assert re.search( + r"Received channel 2\. Sending reply: got msg 'faked' with rxSnr: 6.0 and hopLimit: 3", + out, + re.MULTILINE, + ) + iface.sendText.assert_called_once_with( + "got msg 'faked' with rxSnr: 6.0 and hopLimit: 3", channelIndex=2 + ) assert err == "" @@ -2900,3 +2977,68 @@ def test_main_set_ham_empty_string(capsys): out, _ = capsys.readouterr() assert "ERROR: Ham radio callsign cannot be empty or contain only whitespace characters" in out assert excinfo.value.code == 1 + + +# OTA-related tests +@pytest.mark.unit +@pytest.mark.usefixtures("reset_mt_config") +def test_main_ota_update_file_not_found(capsys): + """Test --ota-update with non-existent file""" + sys.argv = [ + "", + "--ota-update", + "/nonexistent/firmware.bin", + "--host", + "192.168.1.100", + ] + mt_config.args = sys.argv + + with pytest.raises(SystemExit) as pytest_wrapped_e: + main() + + assert pytest_wrapped_e.type == SystemExit + assert pytest_wrapped_e.value.code == 1 + + +@pytest.mark.unit +@pytest.mark.usefixtures("reset_mt_config") +@patch("meshtastic.ota.ESP32WiFiOTA") +@patch("meshtastic.__main__.meshtastic.util.our_exit") +def test_main_ota_update_retries(mock_our_exit, mock_ota_class, capsys): + """Test --ota-update retries on failure""" + # Create a temporary firmware file + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + f.write(b"fake firmware data") + firmware_file = f.name + + try: + sys.argv = ["", "--ota-update", firmware_file, "--host", "192.168.1.100"] + mt_config.args = sys.argv + + # Mock the OTA class to fail all 5 retries + mock_ota = MagicMock() + mock_ota_class.return_value = mock_ota + mock_ota.hash_bytes.return_value = b"\x00" * 32 + mock_ota.hash_hex.return_value = "a" * 64 + mock_ota.update.side_effect = Exception("Connection failed") + + # Mock isinstance to return True + with patch("meshtastic.__main__.isinstance", return_value=True): + with patch("meshtastic.tcp_interface.TCPInterface") as mock_tcp: + mock_iface = MagicMock() + mock_iface.hostname = "192.168.1.100" + mock_iface.localNode = MagicMock(autospec=Node) + mock_tcp.return_value = mock_iface + + with patch("time.sleep"): + main() + + # Should have exhausted all retries and called our_exit + # Note: our_exit might be called twice - once for TCP check, once for failure + assert mock_our_exit.call_count >= 1 + # Check the last call was for OTA failure + last_call_args = mock_our_exit.call_args[0][0] + assert "OTA update failed" in last_call_args + + finally: + os.unlink(firmware_file) diff --git a/meshtastic/tests/test_mesh_interface_traffic_management.py b/meshtastic/tests/test_mesh_interface_traffic_management.py new file mode 100644 index 0000000..f1aa4f9 --- /dev/null +++ b/meshtastic/tests/test_mesh_interface_traffic_management.py @@ -0,0 +1,22 @@ +"""Meshtastic unit tests for traffic management handling in mesh_interface.py.""" + +import pytest + +from ..mesh_interface import MeshInterface +from ..protobuf import mesh_pb2 + + +@pytest.mark.unit +@pytest.mark.usefixtures("reset_mt_config") +def test_handleFromRadio_with_traffic_management_module_config(): + """Test _handleFromRadio with moduleConfig.traffic_management.""" + iface = MeshInterface(noProto=True) + from_radio = mesh_pb2.FromRadio() + from_radio.moduleConfig.traffic_management.enabled = True + from_radio.moduleConfig.traffic_management.rate_limit_enabled = True + + iface._handleFromRadio(from_radio.SerializeToString()) + + assert iface.localNode.moduleConfig.traffic_management.enabled is True + assert iface.localNode.moduleConfig.traffic_management.rate_limit_enabled is True + iface.close() diff --git a/meshtastic/tests/test_node.py b/meshtastic/tests/test_node.py index c5cb6b3..bd0644d 100644 --- a/meshtastic/tests/test_node.py +++ b/meshtastic/tests/test_node.py @@ -1,4 +1,5 @@ """Meshtastic unit tests for node.py""" +# pylint: disable=C0302 import logging import re @@ -261,6 +262,36 @@ def test_shutdown(caplog): assert re.search(r"Telling node to shutdown", caplog.text, re.MULTILINE) +@pytest.mark.unit +def test_factoryReset_config_uses_int_field(): + """Test factoryReset(config) sets int32 protobuf field with an int value.""" + iface = MagicMock(autospec=MeshInterface) + anode = Node(iface, 1234567890, noProto=True) + + amesg = admin_pb2.AdminMessage() + with patch("meshtastic.node.admin_pb2.AdminMessage", return_value=amesg): + with patch.object(anode, "_sendAdmin") as mock_send_admin: + anode.factoryReset(full=False) + + assert amesg.factory_reset_config == 1 + mock_send_admin.assert_called_once_with(amesg, onResponse=anode.onAckNak) + + +@pytest.mark.unit +def test_factoryReset_full_sets_device_field(): + """Test factoryReset(full=True) sets the full-device reset protobuf field.""" + iface = MagicMock(autospec=MeshInterface) + anode = Node(iface, 1234567890, noProto=True) + + amesg = admin_pb2.AdminMessage() + with patch("meshtastic.node.admin_pb2.AdminMessage", return_value=amesg): + with patch.object(anode, "_sendAdmin") as mock_send_admin: + anode.factoryReset(full=True) + + assert amesg.factory_reset_device == 1 + mock_send_admin.assert_called_once_with(amesg, onResponse=anode.onAckNak) + + @pytest.mark.unit def test_setURL_empty_url(capsys): """Test reboot""" @@ -794,6 +825,30 @@ def test_writeConfig_with_no_radioConfig(capsys): assert err == "" +@pytest.mark.unit +@pytest.mark.usefixtures("reset_mt_config") +def test_writeConfig_traffic_management(): + """Test writeConfig with traffic_management module config.""" + iface = MagicMock(autospec=SerialInterface) + anode = Node(iface, 123, noProto=True) + anode.moduleConfig.traffic_management.enabled = True + anode.moduleConfig.traffic_management.rate_limit_enabled = True + + sent_admin = [] + + def capture_send(p, *args, **kwargs): # pylint: disable=W0613 + sent_admin.append(p) + + with patch.object(anode, "_sendAdmin", side_effect=capture_send): + anode.writeConfig("traffic_management") + + assert len(sent_admin) == 1 + assert sent_admin[0].HasField("set_module_config") + assert sent_admin[0].set_module_config.HasField("traffic_management") + assert sent_admin[0].set_module_config.traffic_management.enabled is True + assert sent_admin[0].set_module_config.traffic_management.rate_limit_enabled is True + + # TODO # @pytest.mark.unit # def test_writeConfig(caplog): @@ -1550,6 +1605,41 @@ def test_setOwner_valid_names(caplog): assert re.search(r'p.set_owner.short_name:VN:', caplog.text, re.MULTILINE) +@pytest.mark.unit +def test_start_ota_local_node(): + """Test startOTA on local node""" + iface = MagicMock(autospec=MeshInterface) + anode = Node(iface, 1234567890, noProto=True) + # Set up as local node + iface.localNode = anode + + amesg = admin_pb2.AdminMessage() + with patch("meshtastic.admin_pb2.AdminMessage", return_value=amesg): + with patch.object(anode, "_sendAdmin") as mock_send_admin: + test_hash = b"\x01\x02\x03" * 8 # 24 bytes hash + anode.startOTA(ota_mode=admin_pb2.OTAMode.OTA_WIFI, ota_file_hash=test_hash) + + # Verify the OTA request was set correctly + assert amesg.ota_request.reboot_ota_mode == admin_pb2.OTAMode.OTA_WIFI + assert amesg.ota_request.ota_hash == test_hash + mock_send_admin.assert_called_once_with(amesg) + + +@pytest.mark.unit +def test_start_ota_remote_node_raises_error(): + """Test startOTA on remote node raises ValueError""" + iface = MagicMock(autospec=MeshInterface) + local_node = Node(iface, 1234567890, noProto=True) + remote_node = Node(iface, 9876543210, noProto=True) + iface.localNode = local_node + + test_hash = b"\x01\x02\x03" * 8 + with pytest.raises(ValueError, match="startOTA only possible in local node"): + remote_node.startOTA( + ota_mode=admin_pb2.OTAMode.OTA_WIFI, ota_file_hash=test_hash + ) + + # TODO # @pytest.mark.unitslow # def test_waitForConfig(): diff --git a/meshtastic/tests/test_ota.py b/meshtastic/tests/test_ota.py new file mode 100644 index 0000000..8703361 --- /dev/null +++ b/meshtastic/tests/test_ota.py @@ -0,0 +1,455 @@ +"""Meshtastic unit tests for ota.py""" + +import hashlib +import logging +import os +import socket +import tempfile +from unittest.mock import MagicMock, patch + +import pytest + +from meshtastic.ota import ( + _file_sha256, + ESP32WiFiOTA, + OTAError, +) + + +@pytest.mark.unit +def test_file_sha256(): + """Test _file_sha256 calculates correct hash""" + # Create a temporary file with known content + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + test_data = b"Hello, World!" + f.write(test_data) + temp_file = f.name + + try: + result = _file_sha256(temp_file) + expected_hash = hashlib.sha256(test_data).hexdigest() + assert result.hexdigest() == expected_hash + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +def test_file_sha256_large_file(): + """Test _file_sha256 handles files larger than chunk size""" + # Create a temporary file with more than 4096 bytes + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + test_data = b"A" * 8192 # More than 4096 bytes + f.write(test_data) + temp_file = f.name + + try: + result = _file_sha256(temp_file) + expected_hash = hashlib.sha256(test_data).hexdigest() + assert result.hexdigest() == expected_hash + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +def test_esp32_wifi_ota_init_file_not_found(): + """Test ESP32WiFiOTA raises FileNotFoundError for non-existent file""" + with pytest.raises(FileNotFoundError, match="does not exist"): + ESP32WiFiOTA("/nonexistent/firmware.bin", "192.168.1.1") + + +@pytest.mark.unit +def test_esp32_wifi_ota_init_success(): + """Test ESP32WiFiOTA initializes correctly with valid file""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + f.write(b"fake firmware data") + temp_file = f.name + + try: + ota = ESP32WiFiOTA(temp_file, "192.168.1.1", 3232) + assert ota._filename == temp_file + assert ota._hostname == "192.168.1.1" + assert ota._port == 3232 + assert ota._socket is None + # Verify hash is calculated + assert ota._file_hash is not None + assert len(ota.hash_hex()) == 64 # SHA256 hex is 64 chars + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +def test_esp32_wifi_ota_init_default_port(): + """Test ESP32WiFiOTA uses default port 3232""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + f.write(b"fake firmware data") + temp_file = f.name + + try: + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + assert ota._port == 3232 + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +def test_esp32_wifi_ota_hash_bytes(): + """Test hash_bytes returns correct bytes""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + test_data = b"firmware data" + f.write(test_data) + temp_file = f.name + + try: + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + hash_bytes = ota.hash_bytes() + expected_bytes = hashlib.sha256(test_data).digest() + assert hash_bytes == expected_bytes + assert len(hash_bytes) == 32 # SHA256 is 32 bytes + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +def test_esp32_wifi_ota_hash_hex(): + """Test hash_hex returns correct hex string""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + test_data = b"firmware data" + f.write(test_data) + temp_file = f.name + + try: + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + hash_hex = ota.hash_hex() + expected_hex = hashlib.sha256(test_data).hexdigest() + assert hash_hex == expected_hex + assert len(hash_hex) == 64 # SHA256 hex is 64 chars + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +def test_esp32_wifi_ota_read_line_not_connected(): + """Test _read_line raises ConnectionError when not connected""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + f.write(b"firmware") + temp_file = f.name + + try: + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + with pytest.raises(ConnectionError, match="Socket not connected"): + ota._read_line() + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +def test_esp32_wifi_ota_read_line_connection_closed(): + """Test _read_line raises ConnectionError when connection closed""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + f.write(b"firmware") + temp_file = f.name + + try: + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + mock_socket = MagicMock() + # Simulate connection closed + mock_socket.recv.return_value = b"" + ota._socket = mock_socket + + with pytest.raises(ConnectionError, match="Connection closed"): + ota._read_line() + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +def test_esp32_wifi_ota_read_line_success(): + """Test _read_line successfully reads a line""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + f.write(b"firmware") + temp_file = f.name + + try: + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + mock_socket = MagicMock() + # Simulate receiving "OK\n" + mock_socket.recv.side_effect = [b"O", b"K", b"\n"] + ota._socket = mock_socket + + result = ota._read_line() + assert result == "OK" + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +@patch("meshtastic.ota.socket.socket") +def test_esp32_wifi_ota_update_success(mock_socket_class): + """Test update() with successful OTA""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + test_data = b"A" * 1024 # 1KB of data + f.write(test_data) + temp_file = f.name + + try: + # Setup mock socket + mock_socket = MagicMock() + mock_socket_class.return_value = mock_socket + + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + + # Mock _read_line to return appropriate responses + # First call: ERASING, Second call: OK (ready), Third call: OK (complete) + with patch.object(ota, "_read_line") as mock_read_line: + mock_read_line.side_effect = [ + "ERASING", # Device is erasing flash + "OK", # Device ready for firmware + "OK", # Device finished successfully + ] + + ota.update() + + # Verify socket was created and connected + mock_socket_class.assert_called_once_with( + socket.AF_INET, socket.SOCK_STREAM + ) + mock_socket.settimeout.assert_called_once_with(15) + mock_socket.connect.assert_called_once_with(("192.168.1.1", 3232)) + + # Verify start command was sent + start_cmd = f"OTA {len(test_data)} {ota.hash_hex()}\n".encode("utf-8") + mock_socket.sendall.assert_any_call(start_cmd) + + # Verify firmware was sent (at least one chunk) + assert mock_socket.sendall.call_count >= 2 + + # Verify socket was closed + mock_socket.close.assert_called_once() + + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +@patch("meshtastic.ota.socket.socket") +def test_esp32_wifi_ota_update_with_progress_callback(mock_socket_class): + """Test update() with progress callback""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + test_data = b"A" * 1024 # 1KB of data + f.write(test_data) + temp_file = f.name + + try: + # Setup mock socket + mock_socket = MagicMock() + mock_socket_class.return_value = mock_socket + + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + + # Track progress callback calls + progress_calls = [] + + def progress_callback(sent, total): + progress_calls.append((sent, total)) + + # Mock _read_line + with patch.object(ota, "_read_line") as mock_read_line: + mock_read_line.side_effect = [ + "OK", # Device ready + "OK", # Device finished + ] + + ota.update(progress_callback=progress_callback) + + # Verify progress callback was called + assert len(progress_calls) > 0 + # First call should show some progress + assert progress_calls[0][0] > 0 + # Total should be the firmware size + assert progress_calls[0][1] == len(test_data) + # Last call should show all bytes sent + assert progress_calls[-1][0] == len(test_data) + + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +@patch("meshtastic.ota.socket.socket") +def test_esp32_wifi_ota_update_device_error_on_start(mock_socket_class): + """Test update() raises OTAError when device reports error during start""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + f.write(b"firmware") + temp_file = f.name + + try: + mock_socket = MagicMock() + mock_socket_class.return_value = mock_socket + + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + + with patch.object(ota, "_read_line") as mock_read_line: + mock_read_line.return_value = "ERR BAD_HASH" + + with pytest.raises(OTAError, match="Device reported error"): + ota.update() + + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +@patch("meshtastic.ota.socket.socket") +def test_esp32_wifi_ota_update_device_error_on_finish(mock_socket_class): + """Test update() raises OTAError when device reports error after firmware sent""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + f.write(b"firmware") + temp_file = f.name + + try: + mock_socket = MagicMock() + mock_socket_class.return_value = mock_socket + + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + + with patch.object(ota, "_read_line") as mock_read_line: + mock_read_line.side_effect = [ + "OK", # Device ready + "ERR FLASH_ERR", # Error after firmware sent + ] + + with pytest.raises(OTAError, match="OTA update failed"): + ota.update() + + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +@patch("meshtastic.ota.socket.socket") +def test_esp32_wifi_ota_update_socket_cleanup_on_error(mock_socket_class): + """Test that socket is properly cleaned up on error""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + f.write(b"firmware") + temp_file = f.name + + try: + mock_socket = MagicMock() + mock_socket_class.return_value = mock_socket + + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + + # Simulate connection error + mock_socket.connect.side_effect = ConnectionRefusedError("Connection refused") + + with pytest.raises(ConnectionRefusedError): + ota.update() + + # Verify socket was closed even on error + mock_socket.close.assert_called_once() + assert ota._socket is None + + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +@patch("meshtastic.ota.socket.socket") +def test_esp32_wifi_ota_update_large_firmware(mock_socket_class): + """Test update() correctly chunks large firmware files""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + # Create a file larger than chunk_size (1024) + test_data = b"B" * 3000 + f.write(test_data) + temp_file = f.name + + try: + mock_socket = MagicMock() + mock_socket_class.return_value = mock_socket + + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + + with patch.object(ota, "_read_line") as mock_read_line: + mock_read_line.side_effect = [ + "OK", # Device ready + "OK", # Device finished + ] + + ota.update() + + # Verify that all data was sent in chunks + # 3000 bytes should be sent in ~3 chunks of 1024 bytes + sendall_calls = [ + call + for call in mock_socket.sendall.call_args_list + if call[0][0] + != f"OTA {len(test_data)} {ota.hash_hex()}\n".encode("utf-8") + ] + # Calculate total data sent (excluding the start command) + total_sent = sum(len(call[0][0]) for call in sendall_calls) + assert total_sent == len(test_data) + + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +@patch("meshtastic.ota.socket.socket") +def test_esp32_wifi_ota_update_unexpected_response_warning(mock_socket_class, caplog): + """Test update() logs warning on unexpected response during startup""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + f.write(b"firmware") + temp_file = f.name + + try: + mock_socket = MagicMock() + mock_socket_class.return_value = mock_socket + + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + + with patch.object(ota, "_read_line") as mock_read_line: + mock_read_line.side_effect = [ + "UNKNOWN", # Unexpected response + "OK", # Then proceed + "OK", # Device finished + ] + + with caplog.at_level(logging.WARNING): + ota.update() + + # Check that warning was logged for unexpected response + assert "Unexpected response" in caplog.text + + finally: + os.unlink(temp_file) + + +@pytest.mark.unit +@patch("meshtastic.ota.socket.socket") +def test_esp32_wifi_ota_update_unexpected_final_response(mock_socket_class, caplog): + """Test update() logs warning on unexpected final response after firmware upload""" + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as f: + f.write(b"firmware") + temp_file = f.name + + try: + mock_socket = MagicMock() + mock_socket_class.return_value = mock_socket + + ota = ESP32WiFiOTA(temp_file, "192.168.1.1") + + with patch.object(ota, "_read_line") as mock_read_line: + mock_read_line.side_effect = [ + "OK", # Device ready for firmware + "UNKNOWN", # Unexpected final response (not OK, not ERR, not ACK) + "OK", # Then succeed + ] + + with caplog.at_level(logging.WARNING): + ota.update() + + # Check that warning was logged for unexpected final response + assert "Unexpected final response" in caplog.text + + finally: + os.unlink(temp_file) diff --git a/meshtastic/tests/test_stream_interface.py b/meshtastic/tests/test_stream_interface.py index 3411ffb..97b3de4 100644 --- a/meshtastic/tests/test_stream_interface.py +++ b/meshtastic/tests/test_stream_interface.py @@ -15,7 +15,115 @@ def test_StreamInterface(): """Test that we cannot instantiate a StreamInterface based on noProto""" with pytest.raises(Exception) as pytest_wrapped_e: StreamInterface() - assert pytest_wrapped_e.type == Exception + assert pytest_wrapped_e.type == RuntimeError + + +@pytest.mark.unit +@pytest.mark.usefixtures("reset_mt_config") +def test_StreamInterface_close_safe_when_thread_never_started(): + """close() must not raise RuntimeError when called before connect() has started the reader. + + Hits the cleanup path used by __init__ when the handshake raises before the + reader thread is started. + """ + iface = StreamInterface(noProto=True, connectNow=False) + iface.stream = MagicMock() + # _rxThread was created in __init__ but never .start()'d. close() should + # detect that and skip join() instead of raising RuntimeError. + iface.close() + + +@pytest.mark.unit +@pytest.mark.usefixtures("reset_mt_config") +def test_StreamInterface_close_when_thread_never_started_closes_stream(): + """If no reader thread was started, close() should still close the stream.""" + iface = StreamInterface(noProto=True, connectNow=False) + stream = MagicMock() + iface.stream = stream + iface.close() + stream.close.assert_called_once() + + +@pytest.mark.unit +@pytest.mark.usefixtures("reset_mt_config") +def test_StreamInterface_init_cleans_up_when_connect_raises(): + """If connect() raises during __init__, close() runs and the original exception propagates.""" + + cleanup_calls = [] + + class FailingConnectStream(StreamInterface): + """Subclass whose connect() raises, to exercise the __init__ cleanup path.""" + + def __init__(self): + self.stream = MagicMock() # bypass StreamInterface abstract check + super().__init__(noProto=False, connectNow=True) + + def connect(self): + raise RuntimeError("simulated handshake failure") + + def close(self): + cleanup_calls.append("close") + super().close() + + with pytest.raises(RuntimeError, match="simulated handshake failure"): + FailingConnectStream() + assert cleanup_calls == ["close"], "close() should be invoked exactly once on handshake failure" + + +@pytest.mark.unit +@pytest.mark.usefixtures("reset_mt_config") +def test_StreamInterface_init_cleans_up_when_waitForConfig_raises(): + """If waitForConfig() raises after a successful connect(), close() runs and exception propagates.""" + + cleanup_calls = [] + + class FailingWaitStream(StreamInterface): + """Subclass whose waitForConfig() raises, to exercise the second leg of cleanup.""" + + def __init__(self): + self.stream = MagicMock() + super().__init__(noProto=False, connectNow=True) + + def connect(self): + # No-op connect — we are simulating handshake-stage failure, not connect-stage. + pass + + def waitForConfig(self): + raise TimeoutError("simulated config-handshake timeout") + + def close(self): + cleanup_calls.append("close") + super().close() + + with pytest.raises(TimeoutError, match="simulated config-handshake timeout"): + FailingWaitStream() + assert cleanup_calls == ["close"], "close() should be invoked exactly once on handshake timeout" + + +@pytest.mark.unit +@pytest.mark.usefixtures("reset_mt_config") +def test_StreamInterface_init_cleanup_does_not_shadow_original_exception(): + """If close() itself raises during __init__ cleanup, the original exception still propagates. + + The cleanup uses contextlib.suppress(Exception) so that a secondary failure + in close() doesn't replace the real reason for the failed handshake. + """ + + class CleanupRaisesStream(StreamInterface): + """Helper stream that raises during close() to verify exception precedence.""" + + def __init__(self): + self.stream = MagicMock() + super().__init__(noProto=False, connectNow=True) + + def connect(self): + raise RuntimeError("original handshake failure") + + def close(self): + raise RuntimeError("secondary close failure — should be suppressed") + + with pytest.raises(RuntimeError, match="original handshake failure"): + CleanupRaisesStream() # Note: This takes a bit, so moving from unit to slow diff --git a/poetry.lock b/poetry.lock index d52d961..97e2f2d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -5941,4 +5941,4 @@ tunnel = ["pytap2"] [metadata] lock-version = "2.1" python-versions = "^3.9,<3.15" -content-hash = "e87e2eaffca4ad13aa7e1b8622ec4b37b23a4efe1f4febe0ca87b92db5fe6d1e" +content-hash = "674308d6eb7c3730031cc3e73c98b2413c7f59002a9317bfad387bc34a17c64d" diff --git a/protobufs b/protobufs new file mode 160000 index 0000000..dd6c3f8 --- /dev/null +++ b/protobufs @@ -0,0 +1 @@ +Subproject commit dd6c3f850a56a00cbc2cc5b93db2fd43b1a2f46a diff --git a/pyproject.toml b/pyproject.toml index d195fef..720f999 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "meshtastic" -version = "2.7.7" +version = "2.7.8" description = "Python API & client shell for talking to Meshtastic devices" authors = ["Meshtastic Developers "] license = "GPL-3.0-only" @@ -15,7 +15,7 @@ requests = "^2.31.0" pyyaml = "^6.0.1" pypubsub = "^4.0.3" bleak = ">=0.22.3" -packaging = "^24.0" +packaging = ">=24.0" argcomplete = { version = "^3.5.2", optional = true } pyqrcode = { version = "^1.2.1", optional = true } dotmap = { version = "^1.3.30", optional = true }