# Default Repeater Configuration
# radio_type: sx1262 | kiss (use kiss for serial KISS TNC modem)
radio_type: sx1262

repeater:
  # Node name for logging and identification
  node_name: "mesh-repeater-01"

  # TX mode: forward | monitor | no_tx (default: forward)
  # forward = repeat on; monitor = no repeat but companions/tenants can send; no_tx = all TX off
  # mode: forward

  # Geographic location (optional)
  # Latitude in decimal degrees (-90 to 90)
  latitude: 0.0
  # Longitude in decimal degrees (-180 to 180)
  longitude: 0.0

  # Path to identity file (public/private key)
  # If not specified, a new identity will be generated
  identity_file: null

  # Identity key (alternative to identity_file)
  # Store the private key directly in config as binary (set by convert_firmware_key.sh)
  # If both identity_file and identity_key are set, identity_key takes precedence
  # identity_key: null

  # Duplicate packet cache TTL in seconds
  cache_ttl: 3600

  # Score-based transmission filtering
  # Enable quality-based packet filtering and adaptive delays
  use_score_for_tx: false

  # Score threshold for quality monitoring (future use)
  # Currently reserved for potential future features like dashboard alerts,
  # proactive statistics collection, or advanced filtering strategies.
  # Changing this value has no effect on current packet processing.
  score_threshold: 0.3

  # Automatic advertisement interval in hours
  # The repeater will send an advertisement packet at this interval
  # Set to 0 to disable automatic adverts (manual only via web interface)
  # Range: 0 (disabled) to 24+ hours
  # Recommended: 10 hours for typical deployments
  send_advert_interval_hours: 10

  # Respond to discovery requests from other nodes
  # When enabled, the repeater will automatically respond to discovery packets
  # with its node information (node type 2 - repeater)
  allow_discovery: true

  # Incoming advert rate limiter (per advert public key)
  # Uses a token bucket to smooth bursts.
  advert_rate_limit:
    # Master switch for token bucket limiting
    enabled: false
    # Max burst size allowed immediately per pubkey
    # Keep this small for long advert intervals.
    bucket_capacity: 2
    # Number of tokens added each refill interval
    refill_tokens: 1
    # Refill interval in seconds (10 hours)
    refill_interval_seconds: 36000
    # Optional hard minimum spacing between adverts from same pubkey
    # Set 0 to disable (recommended - mesh retransmissions are normal in active networks)
    min_interval_seconds: 0

  # Penalty box for repeat advert limit violations (per pubkey)
  advert_penalty_box:
    # Master switch for escalating cooldowns
    enabled: false
    # Number of violations within decay window before cooldown starts
    violation_threshold: 2
    # Reset violation count if pubkey stays quiet for this long
    violation_decay_seconds: 43200
    # First penalty duration in seconds
    base_penalty_seconds: 21600
    # Exponential growth factor for repeated violations
    penalty_multiplier: 2.0
    # Maximum penalty duration cap
    max_penalty_seconds: 86400

  # Adaptive rate limiting based on mesh activity
  # Rate limits scale with mesh busyness: quiet mesh = lenient, busy mesh = strict
  advert_adaptive:
    # Master switch for adaptive scaling
    enabled: false
    # EWMA smoothing factor (0.0-1.0, higher = faster response)
    ewma_alpha: 0.1
    # Seconds without metrics change before tier change takes effect (hysteresis)
    hysteresis_seconds: 300
    # Tier thresholds based on adverts per minute EWMA
    thresholds:
      quiet_max: 0.05         # Below this = QUIET tier (no limiting)
      normal_max: 0.20        # Below this = NORMAL tier (1x limits)
      busy_max: 0.50          # Below this = BUSY tier (0.5x capacity)
      # Above busy_max = CONGESTED tier (0.25x capacity)

  # Security settings for login/authentication (shared across all identities)
  security:
    # Maximum number of authenticated clients (across all identities)
    max_clients: 1

    # Admin password for full access
    admin_password: "admin123"

    # Guest password for limited access
    guest_password: "guest123"

    # Allow read-only access for clients without password/not in ACL
    allow_read_only: false

    # JWT secret key for signing tokens (auto-generated if not provided)
    # Generate with: python -c "import secrets; print(secrets.token_hex(32))"
    jwt_secret: ""

    # JWT token expiry time in minutes (default: 60 minutes / 1 hour)
    # Controls how long users stay logged in before needing to re-authenticate
    jwt_expiry_minutes: 60

# Mesh Network Configuration
mesh:
  # Global flood policy - controls whether the repeater allows or denies flooding by default
  # true = allow flooding globally, false = deny flooding globally
  # Individual transport keys can override this setting
  global_flood_allow: true

  # Path hash mode for flood packets (0-hop): per-hop hash size in path encoding
  # 0 = 1-byte hashes (legacy), 1 = 2-byte, 2 = 3-byte. Must match mesh convention.
  # Affects originated adverts and any other flood packets sent by the repeater.
  path_hash_mode: 0

  # Flood loop detection mode
  # off = disabled, minimal = allow up to 3 self-hashes, moderate = allow up to 1, strict = allow 0
  loop_detect: minimal

# Multiple Identity Configuration (Optional)
# Define additional identities for the repeater to manage
# Each identity operates independently with its own key pair and configuration
identities:
  # Room Server Identities
  # Each room server acts as a separate logical node on the mesh
  room_servers:
    # Example room server configuration (commented out by default)
    # - name: "TestBBS"
    #   identity_key: "your_room_identity_key_hex_here"
    #   type: "room_server"
    #
    #   # Room-specific settings
    #   settings:
    #     node_name: "Test BBS Room"
    #     latitude: 0.0
    #     longitude: 0.0
    #     admin_password: "room_admin_password"
    #     guest_password: "room_guest_password"
    # Add more room servers as needed
    # - name: "SocialHub"
    #   identity_key: "another_identity_key_hex_here"
    #   type: "room_server"
    #   settings:
    #     node_name: "Social Hub"
    #     latitude: 0.0
    #     longitude: 0.0
    #     admin_password: "social_admin_123"
    #     guest_password: "social_guest_123"

  # Companion Identities
  # Each companion exposes the MeshCore frame protocol over TCP for standard clients.
  # One TCP client per companion at a time. Clients connect to repeater-ip:tcp_port.
  companions:
    # - name: "RepeaterCompanion"
    #   identity_key: "your_companion_identity_key_hex_here"
    #   settings:
    #     node_name: "RepeaterCompanion"
    #     tcp_port: 5000
    #     bind_address: "0.0.0.0"
    #     tcp_timeout: 120   # seconds; default 120 when omitted; 0 = disable (no timeout)
    # - name: "BotCompanion"
    #   identity_key: "another_companion_identity_key_hex"
    #   settings:
    #     node_name: "meshcore-bot"
    #     tcp_port: 5001
    #     tcp_timeout: 120   # seconds; default 120 when omitted; 0 = disable (no timeout)

# Radio hardware type
# Supported:
#   - sx1262        (Linux spidev + system GPIO)
#   - sx1262_ch341  (CH341 USB-to-SPI + CH341 GPIO 0-7)
radio_type: sx1262

# CH341 USB-to-SPI adapter settings (only used when radio_type: sx1262_ch341)
# NOTE: VID/PID are integers. Hex is also accepted in YAML, e.g. 0x1A86.
ch341:
  vid: 6790   # 0x1A86
  pid: 21778  # 0x5512

radio:
  # Frequency in Hz (869.618 MHz for EU)
  frequency: 869618000

  # TX power in dBm
  tx_power: 14

  # Bandwidth in Hz (62500 = 62.5 kHz)
  bandwidth: 62500

  # LoRa spreading factor (7-12)
  spreading_factor: 8

  # Coding rate (5-8)
  coding_rate: 8

  # Preamble length in symbols
  preamble_length: 17

  # Sync word (LoRa network ID)
  sync_word: 13380

  # Use implicit header mode
  implicit_header: false

# KISS modem (when radio_type: kiss). Requires pyMC_core with KISS support.
# kiss:
#   port: "/dev/ttyUSB0"
#   baud_rate: 9600

# SX1262 Hardware Configuration
# NOTE:
# - When radio_type: sx1262, these pins are BCM GPIO numbers.
# - When radio_type: sx1262_ch341, these pins are CH341 GPIO numbers (0-7).
sx1262:
  # SPI bus and chip select
  # NOTE: For CH341 these are not used but are still required parameters.
  bus_id: 0
  cs_id: 0

  # GPIO pins
  cs_pin: 21
  reset_pin: 18
  busy_pin: 20
  irq_pin: 16

  # TX/RX enable pins (-1 to disable)
  txen_pin: -1
  rxen_pin: -1

  # LED pins for TX/RX indication (-1 to disable)
  txled_pin: -1
  rxled_pin: -1

  use_dio3_tcxo: false
  dio3_tcxo_voltage: 1.8
  use_dio2_rf: false

  # Waveshare hardware flag
  is_waveshare: false

delays:
  # TX delay factor for flood mode (multiplier)
  tx_delay_factor: 1.0

  # TX delay factor for direct mode (faster)
  direct_tx_delay_factor: 0.5

duty_cycle:
  # Enable/disable duty cycle enforcement
  # Set to false to disable airtime limits
  enforcement_enabled: false

  # Maximum airtime per minute in milliseconds
  max_airtime_per_minute: 3600


# MQTT Publishing Configuration (Optional)
mqtt:
  # Enable/disable MQTT publishing
  enabled: false

  # MQTT broker settings
  broker: "localhost"
  port: 1883  # Use 8883 for TLS/SSL, 80/443/9001 for WebSockets

  # Use WebSocket transport instead of standard TCP
  # Typically uses ports: 80 (ws://), 443 (wss://), or 9001
  use_websockets: false

  # Authentication (optional)
  username: null
  password: null

  # TLS/SSL configuration (optional)
  # For public brokers with trusted certificates, just enable TLS:
  # tls:
  #   enabled: true
  tls:
    enabled: false

    # Advanced TLS options (usually not needed for public brokers):

    # Custom CA certificate for server verification
    # Leave null to use system default CA certificates (recommended)
    ca_cert: null  # e.g., "/etc/ssl/certs/ca-certificates.crt"

    # Client certificate and key for mutual TLS (rarely needed)
    client_cert: null  # e.g., "/etc/pymc/client.crt"
    client_key: null   # e.g., "/etc/pymc/client.key"

    # Skip certificate verification (insecure, not recommended)
    insecure: false

  # Base topic for publishing
  # Messages will be published to: {base_topic}/{node_name}/{packet|advert}
  base_topic: "meshcore/repeater"


# Storage Configuration
storage:
  # Directory for persistent storage files (SQLite, RRD).
  # Use a writable path for local/dev (e.g. "./var/pymc_repeater" or "~/var/pymc_repeater").
  storage_dir: "/var/lib/pymc_repeater"

  # Data retention settings
  retention:
    # Clean up SQLite records older than this many days
    sqlite_cleanup_days: 31

    # RRD archives are managed automatically:
    # - 1 minute resolution for 1 week
    # - 5 minute resolution for 1 month
    # - 1 hour resolution for 1 year


letsmesh:
  enabled: false
  iata_code: "Test"  # e.g., "SFO", "LHR", "Test"

  # ============================================================
  # BROKER SELECTION MODE - Choose how to connect to brokers
  # ============================================================
  #
  # EXAMPLE 1: Single built-in broker (default, most common)
  # Connect to Europe only - simple, low bandwidth
  broker_index: 0    # 0 = Europe, 1 = US West

  # EXAMPLE 2: All built-in brokers for maximum redundancy
  # Survives single broker failure, best uptime
  # broker_index: -1  # or null - connects to both EU and US

  # EXAMPLE 3: Only custom brokers (private/self-hosted)
  # Ignores built-in LetsMesh brokers completely
  # broker_index: -2
  # additional_brokers:
  #   - name: "Private Server"
  #     host: "mqtt.myserver.com"
  #     port: 443
  #     audience: "mqtt.myserver.com"

  # EXAMPLE 4: Single built-in + custom backup
  # Use EU primary with your own backup
  # broker_index: 0
  # additional_brokers:
  #   - name: "Backup Server"
  #     host: "mqtt-backup.mydomain.com"
  #     port: 8883
  #     audience: "mqtt-backup.mydomain.com"

  # EXAMPLE 5: All built-in + multiple custom (maximum redundancy)
  # EU + US + your own servers - best for critical deployments
  # broker_index: -1
  # additional_brokers:
  #   - name: "Custom Primary"
  #     host: "mqtt-1.mydomain.com"
  #     port: 443
  #     audience: "mqtt-1.mydomain.com"
  #   - name: "Custom Backup"
  #     host: "mqtt-2.mydomain.com"
  #     port: 443
  #     audience: "mqtt-2.mydomain.com"
  # ============================================================

  status_interval: 300
  owner: ""
  email: ""

  # Block specific packet types from being published to LetsMesh
  # If not specified or empty list, all types are published
  # Available types: REQ, RESPONSE, TXT_MSG, ACK, ADVERT, GRP_TXT,
  #                  GRP_DATA, ANON_REQ, PATH, TRACE, RAW_CUSTOM
  disallowed_packet_types: []
    # - REQ           # Don't publish requests
    # - RESPONSE      # Don't publish responses
    # - TXT_MSG       # Don't publish text messages
    # - ACK           # Don't publish acknowledgments
    # - ADVERT        # Don't publish advertisements
    # - GRP_TXT       # Don't publish group text messages
    # - GRP_DATA      # Don't publish group data
    # - ANON_REQ      # Don't publish anonymous requests
    # - PATH          # Don't publish path packets
    # - TRACE         # Don't publish trace packets
    # - RAW_CUSTOM    # Don't publish custom raw packets

logging:
  # Log level: DEBUG, INFO, WARNING, ERROR
  level: INFO

  # Log format
  format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"

# Web interface configuration
web:
  # Enable Cross-Origin Resource Sharing (CORS) headers
  # Allows web frontends from different origins to access the API
  cors_enabled: false

  # Custom path to web frontend files (optional)
  # If not specified, uses the default built-in path
  # Example: /opt/custom-web-ui or /home/user/my-frontend
  # web_path: null
