diff options
Diffstat (limited to 'openhop/repeater')
| -rw-r--r-- | openhop/repeater/defaults/main.yaml | 7 | ||||
| -rw-r--r-- | openhop/repeater/tasks/main.yaml | 60 | ||||
| -rw-r--r-- | openhop/repeater/templates/config.yaml.j2 | 26 | ||||
| -rw-r--r-- | openhop/repeater/vars/boards/rak6421-slot1.yaml | 16 | ||||
| -rw-r--r-- | openhop/repeater/vars/boards/rak6421-slot2.yaml | 16 | ||||
| -rw-r--r-- | openhop/repeater/vars/rf/us.yaml | 7 |
6 files changed, 117 insertions, 15 deletions
diff --git a/openhop/repeater/defaults/main.yaml b/openhop/repeater/defaults/main.yaml index d26e73e..b72dcfb 100644 --- a/openhop/repeater/defaults/main.yaml +++ b/openhop/repeater/defaults/main.yaml @@ -12,6 +12,13 @@ repeater_venv_dir: "/opt/openhop_repeater/venv" repeater_config_dir: "/etc/openhop_repeater" repeater_data_dir: "/var/lib/openhop_repeater" +# --- Web UI credentials (set from vaulted host_vars) --- +# When null the daemon generates a jwt_secret at startup and requires its setup +# wizard before login; anything the wizard writes into config.yaml is lost on +# the next re-template, so real deployments should set both here. +repeater_admin_password: null +repeater_jwt_secret: null + # --- Node identity --- repeater_node_name: "{{inventory_hostname}}" repeater_latitude: 0.0 diff --git a/openhop/repeater/tasks/main.yaml b/openhop/repeater/tasks/main.yaml index b24044c..3d47ef4 100644 --- a/openhop/repeater/tasks/main.yaml +++ b/openhop/repeater/tasks/main.yaml @@ -28,6 +28,32 @@ - "python3-dev" - "build-essential" +# Raspberry Pi OS ships the spi/gpio groups and udev rules via +# raspberrypi-sys-mods; Ubuntu images have neither, so create them here. +- name: create spi and gpio device access groups + become: yes + group: + name: "{{item}}" + system: "yes" + loop: + - "spi" + - "gpio" + +- name: grant spi and gpio groups access to their devices + become: yes + copy: + dest: "/etc/udev/rules.d/90-spi-gpio-groups.rules" + content: | + SUBSYSTEM=="spidev", GROUP="spi", MODE="0660" + SUBSYSTEM=="gpio", GROUP="gpio", MODE="0660" + mode: "0644" + register: udev_result + +- name: apply udev rules to existing devices + become: yes + shell: "udevadm control --reload-rules && udevadm trigger --subsystem-match=spidev --subsystem-match=gpio" + when: udev_result.changed + - name: add openhop repeater user become: yes user: @@ -67,6 +93,22 @@ when: not repeater_installed.stat.exists notify: restart openhop-repeater +# The pip package does not ship these repo-root files, but the web UI's setup +# wizard reads them from the storage dir; without them the hardware step lists +# no options and cannot proceed. +- name: install web UI radio settings and presets + become: yes + get_url: + url: "{{repeater_repo}}/raw/{{repeater_version}}/{{item}}" + dest: "{{repeater_data_dir}}/{{item}}" + owner: "{{repeater_user}}" + group: "{{repeater_user}}" + mode: "0644" + force: "{{not repeater_installed.stat.exists}}" + loop: + - "radio-settings.json" + - "radio-presets.json" + - name: stamp installed openhop_repeater version become: yes copy: @@ -75,6 +117,9 @@ mode: "0644" when: not repeater_installed.stat.exists +# Group-writable so the daemon can persist its generated jwt_secret and the +# setup-wizard credentials back into the config. Note the trade-off: every +# re-template wipes those daemon-written keys and restarts the service. - name: configure openhop repeater become: yes template: @@ -82,9 +127,22 @@ dest: "{{repeater_config_dir}}/config.yaml" owner: "root" group: "{{repeater_user}}" - mode: "0640" + mode: "0660" notify: restart openhop-repeater +# The web UI restarts the daemon after config changes via +# "sudo --non-interactive systemctl restart openhop-repeater"; the daemon's +# code expects exactly this sudoers file to exist. +- name: allow repeater user to restart its own service + become: yes + copy: + dest: "/etc/sudoers.d/openhop-repeater" + content: | + {{repeater_user}} ALL=(root) NOPASSWD: /usr/bin/systemctl restart openhop-repeater + {{repeater_user}} ALL=(root) NOPASSWD: /usr/bin/systemctl restart openhop-repeater.service + mode: "0440" + validate: "visudo -cf %s" + - name: install openhop-repeater systemd service become: yes template: diff --git a/openhop/repeater/templates/config.yaml.j2 b/openhop/repeater/templates/config.yaml.j2 index ddd2772..a26cd05 100644 --- a/openhop/repeater/templates/config.yaml.j2 +++ b/openhop/repeater/templates/config.yaml.j2 @@ -12,6 +12,20 @@ repeater: score_threshold: 0.3 send_advert_interval_hours: 10 allow_discovery: true +{% if repeater_admin_password or repeater_jwt_secret %} + security: +{% if repeater_admin_password %} + admin_password: "{{ repeater_admin_password }}" +{% endif %} +{% if repeater_jwt_secret %} + jwt_secret: "{{ repeater_jwt_secret }}" +{% endif %} +{% endif %} + +# The daemon defaults its auth DB and telemetry to /var/lib/openhop_repeater +# regardless of other paths, so point it at the role-managed data dir. +storage: + storage_dir: "{{ repeater_data_dir }}" radio_type: sx1262 @@ -24,6 +38,9 @@ sx1262: irq_pin: {{ repeater_sx1262_irq_pin }} txen_pin: {{ repeater_sx1262_txen_pin }} rxen_pin: {{ repeater_sx1262_rxen_pin }} + en_pins: {{ repeater_sx1262_en_pins | to_json }} + gpio_chip: {{ repeater_sx1262_gpio_chip }} + use_gpiod_backend: {{ repeater_sx1262_use_gpiod_backend | string | lower }} en_pin: -1 txled_pin: -1 rxled_pin: -1 @@ -41,11 +58,10 @@ radio: preamble_length: {{ repeater_preamble_length }} implicit_header: false -# Observer/telemetry disabled — repeater-only deployment. -mqtt_brokers: - iata_code: "Test" - status_interval: 300 - brokers: [] +# Observer/telemetry disabled: repeater-only deployment. The daemon enables +# its MQTT pusher whenever an mqtt_brokers/letsmesh/mqtt key is present, even +# with an empty broker list (and then warns on every noise-floor sample), so +# the section must be omitted entirely. glass: enabled: false diff --git a/openhop/repeater/vars/boards/rak6421-slot1.yaml b/openhop/repeater/vars/boards/rak6421-slot1.yaml index 464a194..c49ea9a 100644 --- a/openhop/repeater/vars/boards/rak6421-slot1.yaml +++ b/openhop/repeater/vars/boards/rak6421-slot1.yaml @@ -3,13 +3,23 @@ # Source: meshtastic/firmware bin/config.d/lora-RAK6421-13302-slot1.yaml repeater_sx1262_bus_id: 0 # spidev0.0 repeater_sx1262_cs_id: 0 # CE0 (BCM 8) -repeater_sx1262_cs_pin: 8 +# -1 = hardware CS via spidev. The kernel spi driver owns the CE line, so a +# manual cs_pin here fails with EBUSY; manual CS is only for boards whose NSS +# is wired to a non-CE GPIO (e.g. Waveshare). +repeater_sx1262_cs_pin: -1 repeater_sx1262_reset_pin: 16 repeater_sx1262_busy_pin: 24 repeater_sx1262_irq_pin: 22 # DIO1 repeater_sx1262_use_dio3_tcxo: true repeater_sx1262_dio3_tcxo_voltage: 1.8 repeater_sx1262_use_dio2_rf: true -repeater_sx1262_txen_pin: 12 # SKY66122 FEM enable (verify TX vs RX) -repeater_sx1262_rxen_pin: 13 # SKY66122 FEM enable (verify TX vs RX) +# Per upstream's hardware catalog for this board: both SKY66122 FEM enables are +# asserted together via en_pins and DIO2 does the actual TX/RX switching. +repeater_sx1262_txen_pin: -1 +repeater_sx1262_rxen_pin: -1 +repeater_sx1262_en_pins: [12, 13] +repeater_sx1262_use_gpiod_backend: true +# Upstream's catalog says gpio_chip 1, but on a Pi 4 the 40-pin header is +# gpiochip0 (chip 1 is the 8-line firmware expansion GPIO). +repeater_sx1262_gpio_chip: 0 repeater_sx1262_is_waveshare: false diff --git a/openhop/repeater/vars/boards/rak6421-slot2.yaml b/openhop/repeater/vars/boards/rak6421-slot2.yaml index 71a5fb9..ce03662 100644 --- a/openhop/repeater/vars/boards/rak6421-slot2.yaml +++ b/openhop/repeater/vars/boards/rak6421-slot2.yaml @@ -3,13 +3,23 @@ # Source: meshtastic/firmware bin/config.d/lora-RAK6421-13302-slot2.yaml repeater_sx1262_bus_id: 0 # spidev0.1 repeater_sx1262_cs_id: 1 # CE1 (BCM 7) -repeater_sx1262_cs_pin: 7 +# -1 = hardware CS via spidev. The kernel spi driver owns the CE line, so a +# manual cs_pin here fails with EBUSY; manual CS is only for boards whose NSS +# is wired to a non-CE GPIO (e.g. Waveshare). +repeater_sx1262_cs_pin: -1 repeater_sx1262_reset_pin: 24 repeater_sx1262_busy_pin: 19 repeater_sx1262_irq_pin: 18 # DIO1 repeater_sx1262_use_dio3_tcxo: true repeater_sx1262_dio3_tcxo_voltage: 1.8 repeater_sx1262_use_dio2_rf: true -repeater_sx1262_txen_pin: 26 # SKY66122 FEM enable (verify TX vs RX) -repeater_sx1262_rxen_pin: 23 # SKY66122 FEM enable (verify TX vs RX) +# Per upstream's hardware catalog for this board: both SKY66122 FEM enables are +# asserted together via en_pins and DIO2 does the actual TX/RX switching. +repeater_sx1262_txen_pin: -1 +repeater_sx1262_rxen_pin: -1 +repeater_sx1262_en_pins: [26, 23] +repeater_sx1262_use_gpiod_backend: true +# Upstream's catalog says gpio_chip 1, but on a Pi 4 the 40-pin header is +# gpiochip0 (chip 1 is the 8-line firmware expansion GPIO). +repeater_sx1262_gpio_chip: 0 repeater_sx1262_is_waveshare: false diff --git a/openhop/repeater/vars/rf/us.yaml b/openhop/repeater/vars/rf/us.yaml index e20b1c6..2eecc99 100644 --- a/openhop/repeater/vars/rf/us.yaml +++ b/openhop/repeater/vars/rf/us.yaml @@ -1,11 +1,12 @@ --- -# MeshCore US 902-928 MHz preset. +# MeshCore "USA/Canada (Recommended)" community preset: 910.525 / SF7 / BW62.5 +# / CR5. The wide alternate is SF11 / BW250 / CR5. # WARNING: every node on your mesh MUST share identical frequency / bandwidth / # spreading_factor / coding_rate. Confirm these against your local # MeshCore US community settings before deploying. repeater_frequency_hz: 910525000 # 910.525 MHz -repeater_bandwidth_hz: 250000 -repeater_spreading_factor: 11 # 7-12 +repeater_bandwidth_hz: 62500 +repeater_spreading_factor: 7 # 7-12 repeater_coding_rate: 5 # 5-8 repeater_preamble_length: 32 repeater_tx_power_dbm: 22 # SX1262 register max; SKY66122 boosts to ~1W |
