""" 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