Adding Vessels

This commit is contained in:
Marc
2026-01-23 06:02:54 -06:00
parent 9134195eb1
commit f724421ce7
16 changed files with 2113 additions and 7 deletions
+26
View File
@@ -203,6 +203,32 @@ SBS_RECONNECT_DELAY = 2.0
# Default pager log file
DEFAULT_PAGER_LOG_FILE = 'pager_messages.log'
# =============================================================================
# AIS (Vessel Tracking)
# =============================================================================
# AIS-catcher TCP server port
AIS_TCP_PORT = 10110
# AIS stream update interval
AIS_UPDATE_INTERVAL = 0.5
# AIS reconnect delay on error
AIS_RECONNECT_DELAY = 2.0
# AIS socket timeout
AIS_SOCKET_TIMEOUT = 5
# AIS frequencies (MHz)
AIS_FREQUENCIES = [161.975, 162.025]
# Maximum age for vessel data before cleanup
MAX_VESSEL_AGE_SECONDS = 600 # 10 minutes
# AIS process termination timeout
AIS_TERMINATE_TIMEOUT = 5
# WiFi capture temp path prefix
WIFI_CAPTURE_PATH_PREFIX = '/tmp/intercept_wifi'
+14
View File
@@ -209,6 +209,20 @@ TOOL_DEPENDENCIES = {
}
}
},
'ais': {
'name': 'Vessel Tracking (AIS)',
'tools': {
'AIS-catcher': {
'required': True,
'description': 'AIS receiver and decoder',
'install': {
'apt': 'Download .deb from https://github.com/jvde-github/AIS-catcher/releases',
'brew': 'brew install aiscatcher',
'manual': 'https://github.com/jvde-github/AIS-catcher/releases'
}
}
}
},
'aprs': {
'name': 'APRS Tracking',
'tools': {
+30
View File
@@ -155,6 +155,36 @@ class AirspyCommandBuilder(CommandBuilder):
return cmd
def build_ais_command(
self,
device: SDRDevice,
gain: Optional[float] = None,
bias_t: bool = False,
tcp_port: int = 10110
) -> list[str]:
"""
Build AIS-catcher command for AIS vessel tracking with Airspy.
Uses AIS-catcher with SoapySDR support.
"""
device_str = self._build_device_string(device)
cmd = [
'AIS-catcher',
'-d', f'soapysdr -d {device_str}',
'-S', str(tcp_port),
'-o', '5',
'-q',
]
if gain is not None and gain > 0:
cmd.extend(['-gr', 'tuner', str(int(gain))])
if bias_t:
cmd.extend(['-gr', 'biastee', '1'])
return cmd
def get_capabilities(self) -> SDRCapabilities:
"""Return Airspy capabilities."""
return self.CAPABILITIES
+22
View File
@@ -159,6 +159,28 @@ class CommandBuilder(ABC):
"""
pass
@abstractmethod
def build_ais_command(
self,
device: SDRDevice,
gain: Optional[float] = None,
bias_t: bool = False,
tcp_port: int = 10110
) -> list[str]:
"""
Build AIS decoder command for vessel tracking.
Args:
device: The SDR device to use
gain: Gain in dB (None for auto)
bias_t: Enable bias-T power (for active antennas)
tcp_port: TCP port for JSON output server
Returns:
Command as list of strings for subprocess
"""
pass
@abstractmethod
def get_capabilities(self) -> SDRCapabilities:
"""Return hardware capabilities for this SDR type."""
+30
View File
@@ -155,6 +155,36 @@ class HackRFCommandBuilder(CommandBuilder):
return cmd
def build_ais_command(
self,
device: SDRDevice,
gain: Optional[float] = None,
bias_t: bool = False,
tcp_port: int = 10110
) -> list[str]:
"""
Build AIS-catcher command for AIS vessel tracking with HackRF.
Uses AIS-catcher with SoapySDR support.
"""
device_str = self._build_device_string(device)
cmd = [
'AIS-catcher',
'-d', f'soapysdr -d {device_str}',
'-S', str(tcp_port),
'-o', '5',
'-q',
]
if gain is not None and gain > 0:
cmd.extend(['-gr', 'tuner', str(int(gain))])
if bias_t:
cmd.extend(['-gr', 'biastee', '1'])
return cmd
def get_capabilities(self) -> SDRCapabilities:
"""Return HackRF capabilities."""
return self.CAPABILITIES
+28
View File
@@ -134,6 +134,34 @@ class LimeSDRCommandBuilder(CommandBuilder):
return cmd
def build_ais_command(
self,
device: SDRDevice,
gain: Optional[float] = None,
bias_t: bool = False,
tcp_port: int = 10110
) -> list[str]:
"""
Build AIS-catcher command for AIS vessel tracking with LimeSDR.
Uses AIS-catcher with SoapySDR support.
Note: LimeSDR does not support bias-T, parameter is ignored.
"""
device_str = self._build_device_string(device)
cmd = [
'AIS-catcher',
'-d', f'soapysdr -d {device_str}',
'-S', str(tcp_port),
'-o', '5',
'-q',
]
if gain is not None and gain > 0:
cmd.extend(['-gr', 'tuner', str(int(gain))])
return cmd
def get_capabilities(self) -> SDRCapabilities:
"""Return LimeSDR capabilities."""
return self.CAPABILITIES
+35
View File
@@ -157,6 +157,41 @@ class RTLSDRCommandBuilder(CommandBuilder):
return cmd
def build_ais_command(
self,
device: SDRDevice,
gain: Optional[float] = None,
bias_t: bool = False,
tcp_port: int = 10110
) -> list[str]:
"""
Build AIS-catcher command for AIS vessel tracking.
Uses AIS-catcher with TCP JSON output for real-time vessel data.
AIS operates on 161.975 MHz and 162.025 MHz (handled automatically).
"""
if device.is_network:
raise ValueError(
"AIS-catcher does not support rtl_tcp. "
"For remote AIS, run AIS-catcher on the remote machine."
)
cmd = [
'AIS-catcher',
'-d', str(device.index),
'-S', str(tcp_port), # TCP server with JSON output
'-o', '5', # JSON output format
'-q', # Quiet mode (less console output)
]
if gain is not None and gain > 0:
cmd.extend(['-gr', 'tuner', str(int(gain))])
if bias_t:
cmd.extend(['-gr', 'biastee', '1'])
return cmd
def get_capabilities(self) -> SDRCapabilities:
"""Return RTL-SDR capabilities."""
return self.CAPABILITIES
+30
View File
@@ -133,6 +133,36 @@ class SDRPlayCommandBuilder(CommandBuilder):
return cmd
def build_ais_command(
self,
device: SDRDevice,
gain: Optional[float] = None,
bias_t: bool = False,
tcp_port: int = 10110
) -> list[str]:
"""
Build AIS-catcher command for AIS vessel tracking with SDRPlay.
Uses AIS-catcher with SoapySDR support.
"""
device_str = self._build_device_string(device)
cmd = [
'AIS-catcher',
'-d', f'soapysdr -d {device_str}',
'-S', str(tcp_port),
'-o', '5',
'-q',
]
if gain is not None and gain > 0:
cmd.extend(['-gr', 'tuner', str(int(gain))])
if bias_t:
cmd.extend(['-gr', 'biastee', '1'])
return cmd
def get_capabilities(self) -> SDRCapabilities:
"""Return SDRPlay capabilities."""
return self.CAPABILITIES