mirror of
https://github.com/smittix/intercept.git
synced 2026-07-06 08:38:14 -07:00
96172ca593
First-time run of ruff-format via pre-commit hook normalises quote style, trailing commas, and whitespace across 188 Python files. No logic changes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
468 lines
13 KiB
Python
468 lines
13 KiB
Python
"""
|
|
DSC (Digital Selective Calling) constants per ITU-R M.493.
|
|
|
|
This module contains all DSC-specific constants including format codes,
|
|
distress nature codes, telecommand definitions, and MID (Maritime
|
|
Identification Digits) country mappings.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
# =============================================================================
|
|
# DSC Format Codes (Category)
|
|
# Per ITU-R M.493-15 Table 1
|
|
# =============================================================================
|
|
|
|
FORMAT_CODES = {
|
|
102: "ALL_SHIPS", # All ships call
|
|
112: "INDIVIDUAL", # Individual call
|
|
114: "INDIVIDUAL_ACK", # Individual acknowledgement
|
|
116: "GROUP", # Group call (including geographic area)
|
|
120: "DISTRESS", # Distress alert
|
|
123: "ALL_SHIPS_URGENCY_SAFETY", # All ships urgency/safety
|
|
}
|
|
|
|
# Valid ITU-R M.493 format specifiers
|
|
VALID_FORMAT_SPECIFIERS = {102, 112, 114, 116, 120, 123}
|
|
|
|
# Valid EOS (End of Sequence) symbols per ITU-R M.493
|
|
VALID_EOS = {117, 122, 127}
|
|
|
|
# Category priority (lower = higher priority)
|
|
CATEGORY_PRIORITY = {
|
|
"DISTRESS": 0,
|
|
"ALL_SHIPS_URGENCY_SAFETY": 2,
|
|
"ALL_SHIPS": 5,
|
|
"GROUP": 5,
|
|
"INDIVIDUAL": 5,
|
|
"INDIVIDUAL_ACK": 5,
|
|
}
|
|
|
|
|
|
# =============================================================================
|
|
# Nature of Distress Codes
|
|
# Per ITU-R M.493-15 Table 3
|
|
# =============================================================================
|
|
|
|
DISTRESS_NATURE_CODES = {
|
|
100: "UNDESIGNATED", # Undesignated distress
|
|
101: "FIRE", # Fire, explosion
|
|
102: "FLOODING", # Flooding
|
|
103: "COLLISION", # Collision
|
|
104: "GROUNDING", # Grounding
|
|
105: "LISTING", # Listing, in danger of capsizing
|
|
106: "SINKING", # Sinking
|
|
107: "DISABLED", # Disabled and adrift
|
|
108: "ABANDONING", # Abandoning ship
|
|
109: "PIRACY", # Piracy/armed robbery attack
|
|
110: "MOB", # Man overboard
|
|
112: "EPIRB", # EPIRB emission
|
|
}
|
|
|
|
|
|
# =============================================================================
|
|
# Telecommand Codes (First and Second)
|
|
# Per ITU-R M.493-15 Tables 4-5
|
|
# =============================================================================
|
|
|
|
TELECOMMAND_CODES = {
|
|
# First telecommand (type of subsequent communication)
|
|
100: "F3E_G3E_ALL", # F3E/G3E all modes (VHF telephony)
|
|
101: "F3E_G3E_DUPLEX", # F3E/G3E duplex
|
|
102: "POLLING", # Polling
|
|
103: "UNABLE_TO_COMPLY", # Unable to comply
|
|
104: "END_OF_CALL", # End of call
|
|
105: "DATA", # Data
|
|
106: "J3E_TELEPHONY", # J3E telephony (SSB)
|
|
107: "DISTRESS_ACK", # Distress acknowledgement
|
|
108: "DISTRESS_RELAY", # Distress relay
|
|
109: "F1B_J2B_FEC", # F1B/J2B FEC NBDP telegraphy
|
|
110: "F1B_J2B_ARQ", # F1B/J2B ARQ NBDP telegraphy
|
|
111: "TEST", # Test
|
|
112: "SHIP_POSITION", # Ship position request
|
|
113: "NO_INFO", # No information
|
|
118: "FREQ_ANNOUNCEMENT", # Frequency announcement
|
|
126: "NO_REASON", # No reason given
|
|
# Second telecommand (additional info)
|
|
200: "F3E_G3E_SIMPLEX", # Simplex VHF telephony requested
|
|
201: "POLL_RESPONSE", # Poll response
|
|
}
|
|
|
|
# Full 0-127 telecommand lookup (maps unknown codes to "UNKNOWN")
|
|
TELECOMMAND_CODES_FULL = {i: TELECOMMAND_CODES.get(i, "UNKNOWN") for i in range(128)}
|
|
|
|
# Format codes that carry telecommand fields
|
|
TELECOMMAND_FORMATS = {112, 114, 116, 120, 123}
|
|
|
|
# Minimum symbols (after phasing strip) before an EOS can be accepted
|
|
MIN_SYMBOLS_FOR_FORMAT = 12
|
|
|
|
|
|
# =============================================================================
|
|
# DSC Symbol Definitions
|
|
# Per ITU-R M.493-15
|
|
# =============================================================================
|
|
|
|
# Special symbols
|
|
DSC_SYMBOLS = {
|
|
120: "DX", # Dot pattern (synchronization)
|
|
121: "RX", # Phasing sequence RX
|
|
122: "SX", # Phasing sequence SX
|
|
123: "S0", # Phasing sequence S0
|
|
124: "S1", # Phasing sequence S1
|
|
125: "S2", # Phasing sequence S2
|
|
126: "S3", # Phasing sequence S3
|
|
127: "EOS", # End of sequence
|
|
}
|
|
|
|
|
|
# =============================================================================
|
|
# MID (Maritime Identification Digits) Country Mapping
|
|
# First 3 digits of MMSI identify the country
|
|
# Per ITU MID table (partial list of common codes)
|
|
# =============================================================================
|
|
|
|
MID_COUNTRY_MAP = {
|
|
# Americas
|
|
"201": "Albania",
|
|
"202": "Andorra",
|
|
"203": "Austria",
|
|
"204": "Azores",
|
|
"205": "Belgium",
|
|
"206": "Belarus",
|
|
"207": "Bulgaria",
|
|
"208": "Vatican City",
|
|
"209": "Cyprus",
|
|
"210": "Cyprus",
|
|
"211": "Germany",
|
|
"212": "Cyprus",
|
|
"213": "Georgia",
|
|
"214": "Moldova",
|
|
"215": "Malta",
|
|
"216": "Armenia",
|
|
"218": "Germany",
|
|
"219": "Denmark",
|
|
"220": "Denmark",
|
|
"224": "Spain",
|
|
"225": "Spain",
|
|
"226": "France",
|
|
"227": "France",
|
|
"228": "France",
|
|
"229": "Malta",
|
|
"230": "Finland",
|
|
"231": "Faroe Islands",
|
|
"232": "United Kingdom",
|
|
"233": "United Kingdom",
|
|
"234": "United Kingdom",
|
|
"235": "United Kingdom",
|
|
"236": "Gibraltar",
|
|
"237": "Greece",
|
|
"238": "Croatia",
|
|
"239": "Greece",
|
|
"240": "Greece",
|
|
"241": "Greece",
|
|
"242": "Morocco",
|
|
"243": "Hungary",
|
|
"244": "Netherlands",
|
|
"245": "Netherlands",
|
|
"246": "Netherlands",
|
|
"247": "Italy",
|
|
"248": "Malta",
|
|
"249": "Malta",
|
|
"250": "Ireland",
|
|
"251": "Iceland",
|
|
"252": "Liechtenstein",
|
|
"253": "Luxembourg",
|
|
"254": "Monaco",
|
|
"255": "Madeira",
|
|
"256": "Malta",
|
|
"257": "Norway",
|
|
"258": "Norway",
|
|
"259": "Norway",
|
|
"261": "Poland",
|
|
"262": "Montenegro",
|
|
"263": "Portugal",
|
|
"264": "Romania",
|
|
"265": "Sweden",
|
|
"266": "Sweden",
|
|
"267": "Slovakia",
|
|
"268": "San Marino",
|
|
"269": "Switzerland",
|
|
"270": "Czech Republic",
|
|
"271": "Turkey",
|
|
"272": "Ukraine",
|
|
"273": "Russia",
|
|
"274": "North Macedonia",
|
|
"275": "Latvia",
|
|
"276": "Estonia",
|
|
"277": "Lithuania",
|
|
"278": "Slovenia",
|
|
"279": "Serbia",
|
|
# North America
|
|
"301": "Anguilla",
|
|
"303": "USA",
|
|
"304": "Antigua and Barbuda",
|
|
"305": "Antigua and Barbuda",
|
|
"306": "Curacao",
|
|
"307": "Aruba",
|
|
"308": "Bahamas",
|
|
"309": "Bahamas",
|
|
"310": "Bermuda",
|
|
"311": "Bahamas",
|
|
"312": "Belize",
|
|
"314": "Barbados",
|
|
"316": "Canada",
|
|
"319": "Cayman Islands",
|
|
"321": "Costa Rica",
|
|
"323": "Cuba",
|
|
"325": "Dominica",
|
|
"327": "Dominican Republic",
|
|
"329": "Guadeloupe",
|
|
"330": "Grenada",
|
|
"331": "Greenland",
|
|
"332": "Guatemala",
|
|
"334": "Honduras",
|
|
"336": "Haiti",
|
|
"338": "USA",
|
|
"339": "Jamaica",
|
|
"341": "Saint Kitts and Nevis",
|
|
"343": "Saint Lucia",
|
|
"345": "Mexico",
|
|
"347": "Martinique",
|
|
"348": "Montserrat",
|
|
"350": "Nicaragua",
|
|
"351": "Panama",
|
|
"352": "Panama",
|
|
"353": "Panama",
|
|
"354": "Panama",
|
|
"355": "Panama",
|
|
"356": "Panama",
|
|
"357": "Panama",
|
|
"358": "Puerto Rico",
|
|
"359": "El Salvador",
|
|
"361": "Saint Pierre and Miquelon",
|
|
"362": "Trinidad and Tobago",
|
|
"364": "Turks and Caicos",
|
|
"366": "USA",
|
|
"367": "USA",
|
|
"368": "USA",
|
|
"369": "USA",
|
|
"370": "Panama",
|
|
"371": "Panama",
|
|
"372": "Panama",
|
|
"373": "Panama",
|
|
"374": "Panama",
|
|
"375": "Saint Vincent and the Grenadines",
|
|
"376": "Saint Vincent and the Grenadines",
|
|
"377": "Saint Vincent and the Grenadines",
|
|
"378": "British Virgin Islands",
|
|
"379": "US Virgin Islands",
|
|
# Asia
|
|
"401": "Afghanistan",
|
|
"403": "Saudi Arabia",
|
|
"405": "Bangladesh",
|
|
"408": "Bahrain",
|
|
"410": "Bhutan",
|
|
"412": "China",
|
|
"413": "China",
|
|
"414": "China",
|
|
"416": "Taiwan",
|
|
"417": "Sri Lanka",
|
|
"419": "India",
|
|
"422": "Iran",
|
|
"423": "Azerbaijan",
|
|
"425": "Iraq",
|
|
"428": "Israel",
|
|
"431": "Japan",
|
|
"432": "Japan",
|
|
"434": "Turkmenistan",
|
|
"436": "Kazakhstan",
|
|
"437": "Uzbekistan",
|
|
"438": "Jordan",
|
|
"440": "South Korea",
|
|
"441": "South Korea",
|
|
"443": "Palestine",
|
|
"445": "North Korea",
|
|
"447": "Kuwait",
|
|
"450": "Lebanon",
|
|
"451": "Kyrgyzstan",
|
|
"453": "Macao",
|
|
"455": "Maldives",
|
|
"457": "Mongolia",
|
|
"459": "Nepal",
|
|
"461": "Oman",
|
|
"463": "Pakistan",
|
|
"466": "Qatar",
|
|
"468": "Syria",
|
|
"470": "UAE",
|
|
"471": "UAE",
|
|
"472": "Tajikistan",
|
|
"473": "Yemen",
|
|
"475": "Yemen",
|
|
"477": "Hong Kong",
|
|
"478": "Bosnia and Herzegovina",
|
|
# Oceania
|
|
"501": "Adelie Land",
|
|
"503": "Australia",
|
|
"506": "Myanmar",
|
|
"508": "Brunei",
|
|
"510": "Micronesia",
|
|
"511": "Palau",
|
|
"512": "New Zealand",
|
|
"514": "Cambodia",
|
|
"515": "Cambodia",
|
|
"516": "Christmas Island",
|
|
"518": "Cook Islands",
|
|
"520": "Fiji",
|
|
"523": "Cocos Islands",
|
|
"525": "Indonesia",
|
|
"529": "Kiribati",
|
|
"531": "Laos",
|
|
"533": "Malaysia",
|
|
"536": "Northern Mariana Islands",
|
|
"538": "Marshall Islands",
|
|
"540": "New Caledonia",
|
|
"542": "Niue",
|
|
"544": "Nauru",
|
|
"546": "French Polynesia",
|
|
"548": "Philippines",
|
|
"550": "Timor-Leste",
|
|
"553": "Papua New Guinea",
|
|
"555": "Pitcairn Island",
|
|
"557": "Solomon Islands",
|
|
"559": "American Samoa",
|
|
"561": "Samoa",
|
|
"563": "Singapore",
|
|
"564": "Singapore",
|
|
"565": "Singapore",
|
|
"566": "Singapore",
|
|
"567": "Thailand",
|
|
"570": "Tonga",
|
|
"572": "Tuvalu",
|
|
"574": "Vietnam",
|
|
"576": "Vanuatu",
|
|
"577": "Vanuatu",
|
|
"578": "Wallis and Futuna",
|
|
# Africa
|
|
"601": "South Africa",
|
|
"603": "Angola",
|
|
"605": "Algeria",
|
|
"607": "St. Paul and Amsterdam Islands",
|
|
"608": "Ascension Island",
|
|
"609": "Burundi",
|
|
"610": "Benin",
|
|
"611": "Botswana",
|
|
"612": "Central African Republic",
|
|
"613": "Cameroon",
|
|
"615": "Congo",
|
|
"616": "Comoros",
|
|
"617": "Cabo Verde",
|
|
"618": "Crozet Archipelago",
|
|
"619": "Ivory Coast",
|
|
"620": "Comoros",
|
|
"621": "Djibouti",
|
|
"622": "Egypt",
|
|
"624": "Ethiopia",
|
|
"625": "Eritrea",
|
|
"626": "Gabon",
|
|
"627": "Ghana",
|
|
"629": "Gambia",
|
|
"630": "Guinea-Bissau",
|
|
"631": "Equatorial Guinea",
|
|
"632": "Guinea",
|
|
"633": "Burkina Faso",
|
|
"634": "Kenya",
|
|
"635": "Kerguelen Islands",
|
|
"636": "Liberia",
|
|
"637": "Liberia",
|
|
"638": "South Sudan",
|
|
"642": "Libya",
|
|
"644": "Lesotho",
|
|
"645": "Mauritius",
|
|
"647": "Madagascar",
|
|
"649": "Mali",
|
|
"650": "Mozambique",
|
|
"654": "Mauritania",
|
|
"655": "Malawi",
|
|
"656": "Niger",
|
|
"657": "Nigeria",
|
|
"659": "Namibia",
|
|
"660": "Reunion",
|
|
"661": "Rwanda",
|
|
"662": "Sudan",
|
|
"663": "Senegal",
|
|
"664": "Seychelles",
|
|
"665": "Saint Helena",
|
|
"666": "Somalia",
|
|
"667": "Sierra Leone",
|
|
"668": "Sao Tome and Principe",
|
|
"669": "Swaziland",
|
|
"670": "Chad",
|
|
"671": "Togo",
|
|
"672": "Tunisia",
|
|
"674": "Tanzania",
|
|
"675": "Uganda",
|
|
"676": "Democratic Republic of Congo",
|
|
"677": "Tanzania",
|
|
"678": "Zambia",
|
|
"679": "Zimbabwe",
|
|
# South America
|
|
"701": "Argentina",
|
|
"710": "Brazil",
|
|
"720": "Bolivia",
|
|
"725": "Chile",
|
|
"730": "Colombia",
|
|
"735": "Ecuador",
|
|
"740": "Falkland Islands",
|
|
"745": "Guiana",
|
|
"750": "Guyana",
|
|
"755": "Paraguay",
|
|
"760": "Peru",
|
|
"765": "Suriname",
|
|
"770": "Uruguay",
|
|
"775": "Venezuela",
|
|
}
|
|
|
|
|
|
# =============================================================================
|
|
# VHF Channel Frequencies (MHz) for DSC follow-up
|
|
# =============================================================================
|
|
|
|
VHF_CHANNELS = {
|
|
6: 156.300, # Intership safety
|
|
8: 156.400, # Commercial working
|
|
9: 156.450, # Calling
|
|
10: 156.500, # Commercial working
|
|
12: 156.600, # Port operations
|
|
13: 156.650, # Bridge-to-bridge navigation safety
|
|
14: 156.700, # Port operations
|
|
16: 156.800, # Distress, safety and calling (VHF voice)
|
|
67: 156.375, # UK small craft safety
|
|
68: 156.425, # Marina/yacht club
|
|
70: 156.525, # DSC distress, safety and calling
|
|
71: 156.575, # Port operations
|
|
72: 156.625, # Intership
|
|
73: 156.675, # Port operations
|
|
74: 156.725, # Port operations
|
|
77: 156.875, # Intership
|
|
}
|
|
|
|
|
|
# =============================================================================
|
|
# DSC Modulation Parameters
|
|
# =============================================================================
|
|
|
|
DSC_BAUD_RATE = 1200 # 1200 bps per ITU-R M.493
|
|
|
|
# FSK tone frequencies (Hz) on 1700 Hz subcarrier
|
|
DSC_MARK_FREQ = 2100 # B (mark) - binary 1
|
|
DSC_SPACE_FREQ = 1300 # Y (space) - binary 0
|
|
|
|
# Audio sample rate for decoding
|
|
DSC_AUDIO_SAMPLE_RATE = 48000
|
|
|
|
# Frame structure
|
|
DSC_DOT_PATTERN_LENGTH = 200 # 200 bits of alternating pattern
|
|
DSC_PHASING_LENGTH = 7 # 7 symbols phasing sequence
|
|
DSC_MESSAGE_MAX_SYMBOLS = 180 # Maximum message length in symbols
|