mirror of
https://github.com/smittix/intercept.git
synced 2026-07-21 07:48:11 -07:00
fix: Correct DSC decoder phasing sequence handling, MMSI and position decoding
Strip ITU-R M.493 phasing symbols (120-126) after dot pattern sync before decoding message content. Fix MMSI BCD digit trimming direction and correct test symbol encodings for position and MMSI edge cases.
This commit is contained in:
+8
-5
@@ -313,8 +313,9 @@ class TestDSCDecoder:
|
|||||||
def test_decode_mmsi_with_leading_zeros(self, decoder):
|
def test_decode_mmsi_with_leading_zeros(self, decoder):
|
||||||
"""Test MMSI decoding handles leading zeros."""
|
"""Test MMSI decoding handles leading zeros."""
|
||||||
# Coast station: 002320001
|
# Coast station: 002320001
|
||||||
# 00-23-20-00-01 -> [0, 23, 20, 0, 1]
|
# Padded to 10 digits: 0002320001
|
||||||
symbols = [0, 23, 20, 0, 1]
|
# BCD pairs: 00-02-32-00-01 -> [0, 2, 32, 0, 1]
|
||||||
|
symbols = [0, 2, 32, 0, 1]
|
||||||
result = decoder._decode_mmsi(symbols)
|
result = decoder._decode_mmsi(symbols)
|
||||||
assert result == '002320001'
|
assert result == '002320001'
|
||||||
|
|
||||||
@@ -328,14 +329,16 @@ class TestDSCDecoder:
|
|||||||
# Symbols > 99 should be treated as 0
|
# Symbols > 99 should be treated as 0
|
||||||
symbols = [100, 32, 12, 34, 56]
|
symbols = [100, 32, 12, 34, 56]
|
||||||
result = decoder._decode_mmsi(symbols)
|
result = decoder._decode_mmsi(symbols)
|
||||||
# First symbol becomes 00
|
# First symbol (100) becomes 00, padded result "0032123456",
|
||||||
assert result == '003212345'[-9:]
|
# trim leading pad digit -> "032123456"
|
||||||
|
assert result == '032123456'
|
||||||
|
|
||||||
def test_decode_position_northeast(self, decoder):
|
def test_decode_position_northeast(self, decoder):
|
||||||
"""Test position decoding for NE quadrant."""
|
"""Test position decoding for NE quadrant."""
|
||||||
# Quadrant 10 = NE (lat+, lon+)
|
# Quadrant 10 = NE (lat+, lon+)
|
||||||
# Position: 51°30'N, 0°10'E
|
# Position: 51°30'N, 0°10'E
|
||||||
symbols = [10, 51, 30, 0, 10, 0, 0, 0, 0, 0]
|
# lon_deg = symbols[3]*100 + symbols[4] = 0, lon_min = symbols[5] = 10
|
||||||
|
symbols = [10, 51, 30, 0, 0, 10, 0, 0, 0, 0]
|
||||||
result = decoder._decode_position(symbols)
|
result = decoder._decode_position(symbols)
|
||||||
|
|
||||||
assert result is not None
|
assert result is not None
|
||||||
|
|||||||
+17
-2
@@ -264,6 +264,20 @@ class DSCDecoder:
|
|||||||
symbol_value = self._bits_to_symbol(symbol_bits)
|
symbol_value = self._bits_to_symbol(symbol_bits)
|
||||||
symbols.append(symbol_value)
|
symbols.append(symbol_value)
|
||||||
|
|
||||||
|
# Strip phasing sequence (RX/DX symbols 120-126) from the
|
||||||
|
# start of the message. Per ITU-R M.493, after the dot pattern
|
||||||
|
# there are 7 phasing symbols before the format specifier.
|
||||||
|
msg_start = 0
|
||||||
|
for i, sym in enumerate(symbols):
|
||||||
|
if 120 <= sym <= 126:
|
||||||
|
msg_start = i + 1
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
symbols = symbols[msg_start:]
|
||||||
|
|
||||||
|
if len(symbols) < 5:
|
||||||
|
return None
|
||||||
|
|
||||||
# Look for EOS (End of Sequence) - symbol 127
|
# Look for EOS (End of Sequence) - symbol 127
|
||||||
eos_found = False
|
eos_found = False
|
||||||
eos_index = -1
|
eos_index = -1
|
||||||
@@ -404,9 +418,10 @@ class DSCDecoder:
|
|||||||
digits.append(f'{sym:02d}')
|
digits.append(f'{sym:02d}')
|
||||||
|
|
||||||
mmsi = ''.join(digits)
|
mmsi = ''.join(digits)
|
||||||
# MMSI is 9 digits, might need to trim leading zero
|
# MMSI is 9 digits - trim the leading digit from the 10-digit
|
||||||
|
# BCD result since the first symbol's high digit is always 0
|
||||||
if len(mmsi) > 9:
|
if len(mmsi) > 9:
|
||||||
mmsi = mmsi[-9:]
|
mmsi = mmsi[1:]
|
||||||
|
|
||||||
return mmsi.zfill(9)
|
return mmsi.zfill(9)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user