From be024d8d4e3812d35281e19a387353444a3c9d2c Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Fri, 9 Jan 2026 17:14:35 -0600 Subject: [PATCH] Add copilot-instructions.md for better contextual hints --- .github/copilot-instructions.md | 314 ++++++++++++++++++++++++++++++++ 1 file changed, 314 insertions(+) create mode 100644 .github/copilot-instructions.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 000000000..14601b058 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,314 @@ +# Meshtastic Firmware - Copilot Instructions + +This document provides context and guidelines for AI assistants working with the Meshtastic firmware codebase. + +## Project Overview + +Meshtastic is an open-source LoRa mesh networking project for long-range, low-power communication without relying on internet or cellular infrastructure. The firmware enables text messaging, location sharing, and telemetry over a decentralized mesh network. + +### Supported Hardware Platforms + +- **ESP32** (ESP32, ESP32-S3, ESP32-C3) - Most common platform +- **nRF52** (nRF52840, nRF52833) - Low power Nordic chips +- **RP2040/RP2350** - Raspberry Pi Pico variants +- **STM32WL** - STM32 with integrated LoRa +- **Linux/Portduino** - Native Linux builds (Raspberry Pi, etc.) + +### Supported Radio Chips + +- **SX1262/SX1268** - Sub-GHz LoRa (868/915 MHz regions) +- **SX1280** - 2.4 GHz LoRa +- **LR1110/LR1120/LR1121** - Wideband radios (sub-GHz and 2.4 GHz capable, but not simultaneously) +- **RF95** - Legacy RFM95 modules +- **LLCC68** - Low-cost LoRa + +### MQTT Integration + +MQTT provides a bridge between Meshtastic mesh networks and the internet, enabling nodes with network connectivity to share messages with remote meshes or external services. + +#### Key Components + +- **`src/mqtt/MQTT.cpp`** - Main MQTT client singleton, handles connection and message routing +- **`src/mqtt/ServiceEnvelope.cpp`** - Protobuf wrapper for mesh packets sent over MQTT +- **`moduleConfig.mqtt`** - MQTT module configuration + +#### MQTT Topic Structure + +Messages are published/subscribed using a hierarchical topic format: + +``` +{root}/{channel_id}/{gateway_id} +``` + +- `root` - Configurable prefix (default: `msh`) +- `channel_id` - Channel name/identifier +- `gateway_id` - Node ID of the publishing gateway + +#### Configuration Defaults (from `Default.h`) + +```cpp +#define default_mqtt_address "mqtt.meshtastic.org" +#define default_mqtt_username "meshdev" +#define default_mqtt_password "large4cats" +#define default_mqtt_root "msh" +#define default_mqtt_encryption_enabled true +#define default_mqtt_tls_enabled false +``` + +#### Key Concepts + +- **Uplink** - Mesh packets sent TO the MQTT broker (controlled by `uplink_enabled` per channel) +- **Downlink** - MQTT messages received and injected INTO the mesh (controlled by `downlink_enabled` per channel) +- **Encryption** - When `encryption_enabled` is true, only encrypted packets are sent; plaintext JSON is disabled +- **ServiceEnvelope** - Protobuf wrapper containing packet + channel_id + gateway_id for routing +- **JSON Support** - Optional JSON encoding for integration with external systems (disabled on nRF52 by default) + +#### PKI Messages + +PKI (Public Key Infrastructure) messages have special handling: + +- Accepted on a special "PKI" channel +- Allow encrypted DMs between nodes that discovered each other on downlink-enabled channels + +## Project Structure + +``` +firmware/ +├── src/ # Main source code +│ ├── main.cpp # Application entry point +│ ├── mesh/ # Core mesh networking +│ │ ├── NodeDB.* # Node database management +│ │ ├── Router.* # Packet routing +│ │ ├── Channels.* # Channel management +│ │ ├── *Interface.* # Radio interface implementations +│ │ └── generated/ # Protobuf generated code +│ ├── modules/ # Feature modules (Position, Telemetry, etc.) +│ ├── gps/ # GPS handling +│ ├── graphics/ # Display drivers and UI +│ ├── platform/ # Platform-specific code +│ ├── input/ # Input device handling +│ └── concurrency/ # Threading utilities +├── variants/ # Hardware variant definitions +│ ├── esp32/ # ESP32 variants +│ ├── esp32s3/ # ESP32-S3 variants +│ ├── nrf52/ # nRF52 variants +│ └── rp2xxx/ # RP2040/RP2350 variants +├── protobufs/ # Protocol buffer definitions +├── boards/ # Custom PlatformIO board definitions +└── bin/ # Build and utility scripts +``` + +## Coding Conventions + +### General Style + +- Follow existing code style - run `trunk fmt` before commits +- Prefer `LOG_DEBUG`, `LOG_INFO`, `LOG_WARN`, `LOG_ERROR` for logging +- Use `assert()` for invariants that should never fail + +### Naming Conventions + +- Classes: `PascalCase` (e.g., `PositionModule`, `NodeDB`) +- Functions/Methods: `camelCase` (e.g., `sendOurPosition`, `getNodeNum`) +- Constants/Defines: `UPPER_SNAKE_CASE` (e.g., `MAX_INTERVAL`, `ONE_DAY`) +- Member variables: `camelCase` (e.g., `lastGpsSend`, `nodeDB`) +- Config defines: `USERPREFS_*` for user-configurable options + +### Key Patterns + +#### Module System + +Modules inherit from `MeshModule` or `ProtobufModule` and implement: + +- `handleReceivedProtobuf()` - Process incoming packets +- `allocReply()` - Generate response packets +- `runOnce()` - Periodic task execution (returns next run interval in ms) + +```cpp +class MyModule : public ProtobufModule +{ + protected: + virtual bool handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_MyMessage *msg) override; + virtual int32_t runOnce() override; +}; +``` + +#### Configuration Access + +- `config.*` - Device configuration (LoRa, position, power, etc.) +- `moduleConfig.*` - Module-specific configuration +- `channels.*` - Channel configuration and management + +#### Default Values + +Use the `Default` class helpers in `src/mesh/Default.h`: + +- `Default::getConfiguredOrDefaultMs(configured, default)` - Returns ms, using default if configured is 0 +- `Default::getConfiguredOrMinimumValue(configured, min)` - Enforces minimum values +- `Default::getConfiguredOrDefaultMsScaled(configured, default, numNodes)` - Scales based on network size + +#### Thread Safety + +- Use `concurrency::Lock` for mutex protection +- Radio SPI access uses `SPILock` +- Prefer `OSThread` for background tasks + +### Hardware Variants + +Each hardware variant has: + +- `variant.h` - Pin definitions and hardware capabilities +- `platformio.ini` - Build configuration +- Optional: `pins_arduino.h`, `rfswitch.h` + +Key defines in variant.h: + +```cpp +#define USE_SX1262 // Radio chip selection +#define HAS_GPS 1 // Hardware capabilities +#define LORA_CS 36 // Pin assignments +#define SX126X_DIO1 14 // Radio-specific pins +``` + +### Protobuf Messages + +- Defined in `protobufs/meshtastic/*.proto` +- Generated code in `src/mesh/generated/` +- Regenerate with `bin/regen-protos.sh` +- Message types prefixed with `meshtastic_` + +### Conditional Compilation + +```cpp +#if !MESHTASTIC_EXCLUDE_GPS // Feature exclusion +#ifdef ARCH_ESP32 // Architecture-specific +#if defined(USE_SX1262) // Radio-specific +#ifdef HAS_SCREEN // Hardware capability +#if USERPREFS_EVENT_MODE // User preferences +``` + +## Build System + +Uses **PlatformIO** with custom scripts: + +- `bin/platformio-pre.py` - Pre-build script +- `bin/platformio-custom.py` - Custom build logic + +Build commands: + +```bash +pio run -e tbeam # Build specific target +pio run -e tbeam -t upload # Build and upload +pio run -e native # Build native/Linux version +``` + +## Common Tasks + +### Adding a New Module + +1. Create `src/modules/MyModule.cpp` and `.h` +2. Inherit from appropriate base class +3. Register in `src/modules/Modules.cpp` +4. Add protobuf messages if needed in `protobufs/` + +### Adding a New Hardware Variant + +1. Create directory under `variants///` +2. Add `variant.h` with pin definitions +3. Add `platformio.ini` with build config +4. Reference common configs with `extends` + +### Modifying Configuration Defaults + +- Check `src/mesh/Default.h` for default value defines +- Check `src/mesh/NodeDB.cpp` for initialization logic +- Consider `isDefaultChannel()` checks for public channel restrictions + +## Important Considerations + +### Traffic Management + +The mesh network has limited bandwidth. When modifying broadcast intervals: + +- Respect minimum intervals on default/public channels +- Use `Default::getConfiguredOrMinimumValue()` to enforce minimums +- Consider `numOnlineNodes` scaling for congestion control + +### Power Management + +Many devices are battery-powered: + +- Use `IF_ROUTER(routerVal, normalVal)` for role-based defaults +- Check `config.power.is_power_saving` for power-saving modes +- Implement proper `sleep()` methods in radio interfaces + +### Channel Security + +- `channels.isDefaultChannel(index)` - Check if using default/public settings +- Default channels get stricter rate limits to prevent abuse +- Private channels may have relaxed limits + +## GitHub Actions CI/CD + +The project uses GitHub Actions extensively for CI/CD. Key workflows are in `.github/workflows/`: + +### Core CI Workflows + +- **`main_matrix.yml`** - Main CI pipeline, runs on push to `master`/`develop` and PRs + - Uses `bin/generate_ci_matrix.py` to dynamically generate build targets + - Builds all supported hardware variants + - PRs build a subset (`--level pr`) for faster feedback + +- **`trunk_check.yml`** - Code quality checks on PRs + - Runs Trunk.io for linting and formatting + - Must pass before merge + +- **`tests.yml`** - End-to-end and hardware tests + - Runs daily on schedule + - Includes native tests and hardware-in-the-loop testing + +- **`test_native.yml`** - Native platform unit tests + - Runs `pio test -e native` + +### Release Workflows + +- **`release_channels.yml`** - Triggered on GitHub release publish + - Builds Docker images + - Packages for PPA (Ubuntu), OBS (openSUSE), and COPR (Fedora) + - Handles Alpha/Beta/Stable release channels + +- **`nightly.yml`** - Nightly builds from develop branch + +- **`docker_build.yml`** / **`docker_manifest.yml`** - Docker image builds + +### Build Matrix Generation + +The CI uses `bin/generate_ci_matrix.py` to dynamically select which targets to build: + +```bash +# Generate full build matrix +./bin/generate_ci_matrix.py all + +# Generate PR-level matrix (subset for faster builds) +./bin/generate_ci_matrix.py all --level pr +``` + +Variants can specify their support level in `platformio.ini`: + +- `custom_meshtastic_support_level = 1` - Actively supported, built on every PR +- `custom_meshtastic_support_level = 2` - Supported, built on merge to main branches +- `board_level = extra` - Extra builds, only on full releases + +### Running Workflows Locally + +Most workflows can be triggered manually via `workflow_dispatch` for testing. + +## Testing + +- Unit tests in `test/` directory +- Run with `pio test -e native` +- Use `bin/test-simulator.sh` for simulation testing + +## Resources + +- [Documentation](https://meshtastic.org/docs/)