diff --git a/.github/instructions/snyk_rules.instructions.md b/.github/instructions/snyk_rules.instructions.md new file mode 100644 index 0000000..eef0634 --- /dev/null +++ b/.github/instructions/snyk_rules.instructions.md @@ -0,0 +1,14 @@ +--- +alwaysApply: true +always_on: true +trigger: always_on +applyTo: "**" +description: Snyk Security At Inception +--- + +# Project security best practices + +- Always run snyk_code_scan tool for new first party code that is generated in a Snyk-supported language. +- If any security issues are found based on newly introduced or modified code or dependencies, attempt to fix the issues using the results context from Snyk. +- Rescan the code after fixing the issues to ensure that the issues were fixed and that there are no newly introduced issues. +- Repeat this process until no new issues are found. diff --git a/manage.sh b/manage.sh index ec61e9d..a95a546 100755 --- a/manage.sh +++ b/manage.sh @@ -70,6 +70,11 @@ is_running() { systemctl is-active "$SERVICE_NAME" >/dev/null 2>&1 } +# Function to check if service is enabled +is_enabled() { + systemctl is-enabled "$SERVICE_NAME" >/dev/null 2>&1 +} + # Function to get current version get_version() { # Try to read from _version.py first (generated by setuptools_scm) @@ -638,6 +643,9 @@ manage_service() { case $action in "start") + if ! is_enabled; then + systemctl enable "$SERVICE_NAME" + fi systemctl start "$SERVICE_NAME" if is_running; then show_info "Service Started" "\n✓ pyMC Repeater service has been started successfully." diff --git a/pyproject.toml b/pyproject.toml index 075c7e8..ca647de 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ keywords = ["mesh", "networking", "lora", "repeater", "daemon", "iot"] dependencies = [ - "pymc_core[hardware] @ git+https://github.com/rightup/pyMC_core.git@dev", + "pymc_core[hardware] @ git+https://github.com/theshaun/pyMC_core.git@dev", "pyyaml>=6.0.0", "cherrypy>=18.0.0", "paho-mqtt>=1.6.0", diff --git a/radio-presets.json b/radio-presets.json index 40b4b7a..99090fd 100644 --- a/radio-presets.json +++ b/radio-presets.json @@ -1 +1,151 @@ -{"config":{"connect_screen":{"info_message":"The default pin for devices without a screen is 123456. Trouble pairing? Forget the bluetooth device in system settings."},"remote_management":{"repeaters":{"guest_login_enabled":true,"guest_login_disabled_message":"Guest login has been temporarily disabled. Please try again later.","guest_login_passwords":[""],"flood_routed_guest_login_enabled":true,"flood_routed_guest_login_disabled_message":"To avoid overwhelming the mesh with flood packets, please set a path to log in to a repeater as a guest."}},"suggested_radio_settings":{"info_message":"These radio settings have been suggested by the community.","entries":[{"title":"Australia","description":"915.800MHz / SF10 / BW250 / CR5","frequency":"915.800","spreading_factor":"10","bandwidth":"250","coding_rate":"5"},{"title":"Australia: Victoria","description":"916.575MHz / SF7 / BW62.5 / CR8","frequency":"916.575","spreading_factor":"7","bandwidth":"62.5","coding_rate":"8"},{"title":"EU/UK (Narrow)","description":"869.618MHz / SF8 / BW62.5 / CR8","frequency":"869.618","spreading_factor":"8","bandwidth":"62.5","coding_rate":"8"},{"title":"EU/UK (Long Range)","description":"869.525MHz / SF11 / BW250 / CR5","frequency":"869.525","spreading_factor":"11","bandwidth":"250","coding_rate":"5"},{"title":"EU/UK (Medium Range)","description":"869.525MHz / SF10 / BW250 / CR5","frequency":"869.525","spreading_factor":"10","bandwidth":"250","coding_rate":"5"},{"title":"Czech Republic (Narrow)","description":"869.525MHz / SF7 / BW62.5 / CR5","frequency":"869.525","spreading_factor":"7","bandwidth":"62.5","coding_rate":"5"},{"title":"EU 433MHz (Long Range)","description":"433.650MHz / SF11 / BW250 / CR5","frequency":"433.650","spreading_factor":"11","bandwidth":"250","coding_rate":"5"},{"title":"New Zealand","description":"917.375MHz / SF11 / BW250 / CR5","frequency":"917.375","spreading_factor":"11","bandwidth":"250","coding_rate":"5"},{"title":"New Zealand (Narrow)","description":"917.375MHz / SF7 / BW62.5 / CR5","frequency":"917.375","spreading_factor":"7","bandwidth":"62.5","coding_rate":"5"},{"title":"Portugal 433","description":"433.375MHz / SF9 / BW62.5 / CR6","frequency":"433.375","spreading_factor":"9","bandwidth":"62.5","coding_rate":"6"},{"title":"Portugal 868","description":"869.618MHz / SF7 / BW62.5 / CR6","frequency":"869.618","spreading_factor":"7","bandwidth":"62.5","coding_rate":"6"},{"title":"Switzerland","description":"869.618MHz / SF8 / BW62.5 / CR8","frequency":"869.618","spreading_factor":"8","bandwidth":"62.5","coding_rate":"8"},{"title":"USA/Canada (Recommended)","description":"910.525MHz / SF7 / BW62.5 / CR5","frequency":"910.525","spreading_factor":"7","bandwidth":"62.5","coding_rate":"5"},{"title":"USA/Canada (Alternate)","description":"910.525MHz / SF11 / BW250 / CR5","frequency":"910.525","spreading_factor":"11","bandwidth":"250","coding_rate":"5"},{"title":"Vietnam","description":"920.250MHz / SF11 / BW250 / CR5","frequency":"920.250","spreading_factor":"11","bandwidth":"250","coding_rate":"5"}]}}} \ No newline at end of file +{ + "config": { + "connect_screen": { + "info_message": "The default pin for devices without a screen is 123456. Trouble pairing? Forget the bluetooth device in system settings." + }, + "remote_management": { + "repeaters": { + "guest_login_enabled": true, + "guest_login_disabled_message": "Guest login has been temporarily disabled. Please try again later.", + "guest_login_passwords": [ + "" + ], + "flood_routed_guest_login_enabled": true, + "flood_routed_guest_login_disabled_message": "To avoid overwhelming the mesh with flood packets, please set a path to log in to a repeater as a guest." + } + }, + "suggested_radio_settings": { + "info_message": "These radio settings have been suggested by the community.", + "entries": [ + { + "title": "Australia", + "description": "915.800MHz / SF10 / BW250 / CR5", + "frequency": "915.800", + "spreading_factor": "10", + "bandwidth": "250", + "coding_rate": "5" + }, + { + "title": "Australia (Narrow)", + "description": "916.575MHz / SF7 / BW62.5 / CR8", + "frequency": "916.575", + "spreading_factor": "7", + "bandwidth": "62.5", + "coding_rate": "8" + }, + { + "title": "Australia: SA, WA, QLD", + "description": "923.125MHz / SF8 / BW62.5 / CR8", + "frequency": "923.125", + "spreading_factor": "8", + "bandwidth": "62.5", + "coding_rate": "8" + }, + { + "title": "EU/UK (Narrow)", + "description": "869.618MHz / SF8 / BW62.5 / CR8", + "frequency": "869.618", + "spreading_factor": "8", + "bandwidth": "62.5", + "coding_rate": "8" + }, + { + "title": "EU/UK (Long Range)", + "description": "869.525MHz / SF11 / BW250 / CR5", + "frequency": "869.525", + "spreading_factor": "11", + "bandwidth": "250", + "coding_rate": "5" + }, + { + "title": "EU/UK (Medium Range)", + "description": "869.525MHz / SF10 / BW250 / CR5", + "frequency": "869.525", + "spreading_factor": "10", + "bandwidth": "250", + "coding_rate": "5" + }, + { + "title": "Czech Republic (Narrow)", + "description": "869.525MHz / SF7 / BW62.5 / CR5", + "frequency": "869.525", + "spreading_factor": "7", + "bandwidth": "62.5", + "coding_rate": "5" + }, + { + "title": "EU 433MHz (Long Range)", + "description": "433.650MHz / SF11 / BW250 / CR5", + "frequency": "433.650", + "spreading_factor": "11", + "bandwidth": "250", + "coding_rate": "5" + }, + { + "title": "New Zealand", + "description": "917.375MHz / SF11 / BW250 / CR5", + "frequency": "917.375", + "spreading_factor": "11", + "bandwidth": "250", + "coding_rate": "5" + }, + { + "title": "New Zealand (Narrow)", + "description": "917.375MHz / SF7 / BW62.5 / CR5", + "frequency": "917.375", + "spreading_factor": "7", + "bandwidth": "62.5", + "coding_rate": "5" + }, + { + "title": "Portugal 433", + "description": "433.375MHz / SF9 / BW62.5 / CR6", + "frequency": "433.375", + "spreading_factor": "9", + "bandwidth": "62.5", + "coding_rate": "6" + }, + { + "title": "Portugal 868", + "description": "869.618MHz / SF7 / BW62.5 / CR6", + "frequency": "869.618", + "spreading_factor": "7", + "bandwidth": "62.5", + "coding_rate": "6" + }, + { + "title": "Switzerland", + "description": "869.618MHz / SF8 / BW62.5 / CR8", + "frequency": "869.618", + "spreading_factor": "8", + "bandwidth": "62.5", + "coding_rate": "8" + }, + { + "title": "USA/Canada (Recommended)", + "description": "910.525MHz / SF7 / BW62.5 / CR5", + "frequency": "910.525", + "spreading_factor": "7", + "bandwidth": "62.5", + "coding_rate": "5" + }, + { + "title": "USA/Canada (Alternate)", + "description": "910.525MHz / SF11 / BW250 / CR5", + "frequency": "910.525", + "spreading_factor": "11", + "bandwidth": "250", + "coding_rate": "5" + }, + { + "title": "Vietnam", + "description": "920.250MHz / SF11 / BW250 / CR5", + "frequency": "920.250", + "spreading_factor": "11", + "bandwidth": "250", + "coding_rate": "5" + } + ] + } + } +} \ No newline at end of file diff --git a/radio-settings.json b/radio-settings.json index eca0e6f..a532bba 100644 --- a/radio-settings.json +++ b/radio-settings.json @@ -110,6 +110,24 @@ "use_dio3_tcxo": true, "use_dio2_rf": true, "preamble_length": 17 + }, + "femtofox-1W-SX": { + "name": "FemtoFox SX1262 (1W)", + "bus_id": 0, + "cs_id": 0, + "cs_pin": 16, + "gpio_chip": 1, + "use_gpiod_backend": true, + "reset_pin": 25, + "busy_pin": 22, + "irq_pin": 23, + "txen_pin": -1, + "rxen_pin": 24, + "txled_pin": -1, + "rxled_pin": -1, + "tx_power": 30, + "use_dio3_tcxo": true, + "preamble_length": 17 } } } diff --git a/repeater/airtime.py b/repeater/airtime.py index bd8ae26..b1f0040 100644 --- a/repeater/airtime.py +++ b/repeater/airtime.py @@ -53,17 +53,17 @@ def calculate_airtime( Airtime in milliseconds """ sf = spreading_factor or self.spreading_factor - bw_khz = (bandwidth_hz or self.bandwidth) / 1000 + bw_hz = (bandwidth_hz or self.bandwidth) cr = coding_rate or self.coding_rate preamble_len = preamble_len or self.preamble_length crc = 1 if crc_enabled else 0 h = 0 if explicit_header else 1 # H=0 for explicit, H=1 for implicit # Low data rate optimization: required for SF11/SF12 at 125kHz - de = 1 if (sf >= 11 and bandwidth_hz <= 125000) else 0 + de = 1 if (sf >= 11 and bw_hz <= 125000) else 0 # Symbol time in milliseconds: T_sym = 2^SF / BW_kHz - t_sym = (2 ** sf) / bw_khz + t_sym = (2 ** sf) / (bw_hz / 1000) # Preamble time: T_preamble = (n_preamble + 4.25) * T_sym t_preamble = (preamble_len + 4.25) * t_sym diff --git a/repeater/config.py b/repeater/config.py index ffe9268..de24fef 100644 --- a/repeater/config.py +++ b/repeater/config.py @@ -216,6 +216,8 @@ def get_radio_for_board(board_config: dict): "bus_id": spi_config["bus_id"], "cs_id": spi_config["cs_id"], "cs_pin": spi_config["cs_pin"], + "gpio_chip": spi_config.get("gpio_chip", 0), + "use_gpiod_backend": spi_config.get("use_gpiod_backend", False), "reset_pin": spi_config["reset_pin"], "busy_pin": spi_config["busy_pin"], "irq_pin": spi_config["irq_pin"], diff --git a/repeater/data_acquisition/letsmesh_handler.py b/repeater/data_acquisition/letsmesh_handler.py index e3e83d2..32ef579 100644 --- a/repeater/data_acquisition/letsmesh_handler.py +++ b/repeater/data_acquisition/letsmesh_handler.py @@ -5,11 +5,17 @@ import paho.mqtt.client as mqtt import threading -from datetime import datetime, timedelta, UTC +from datetime import datetime, timedelta from nacl.signing import SigningKey from typing import Callable, Optional, List, Dict from .. import __version__ +# Try to import datetime.UTC (Python 3.11+) otherwise fallback to timezone.utc +try: + from datetime import UTC +except Exception: + from datetime import timezone + UTC = timezone.utc # Try to import paho-mqtt error code mappings try: