def vesselIDfill(self, deduct_offset, bits): self.vesselID = bits[0:3] self.tablebin.append([ self.bitlabel(91, 93, deduct_offset), self.vesselID, 'Vessel ID Type', Func.getVesselid(self.vesselID) ]) ############################################## # Vessel 0: No aircraft or maritime identity # ############################################## if self.vesselID == '000': if Func.checkzeros(bits[3:47]): self.tablebin.append([ self.bitlabel(94, 137, deduct_offset), bits[3:47], 'Vessel ID type is none', 'All 0 - OK' ]) else: self.tablebin.append([ self.bitlabel(94, 137, deduct_offset), bits[3:47], 'Vessel ID type is none', 'Error! Should be all 0' ]) ########################### # Vessel 1: Maritime MMSI # ########################### elif self.vesselID == '001': self.mmsi = Func.bin2dec(bits[3:33]) if self.mmsi == 111111: self.tablebin.append([ self.bitlabel(94, 123, deduct_offset), bits[3:33], 'MMSI:', 'No MMSI available' ]) else: self.mmsi_string = str(self.mmsi).zfill(9) self.tablebin.append([ self.bitlabel(94, 123, deduct_offset), bits[3:33], 'Unique ship station identity MIDxxYYYY:', self.mmsi_string ]) self.mmsi_country = Func.countryname(int( self.mmsi_string[0:3])) self.tablebin.append([ '', '', 'Flag state of vessel:', self.mmsi_string[0:3] + ' ' + self.mmsi_country ]) self.tablebin.append( ['', '', 'Unique vessel number', self.mmsi_string[3:]]) self.epirb_ais = Func.bin2dec(bits[33:47]) if self.epirb_ais == 10922: self.tablebin.append([ self.bitlabel(124, 137, deduct_offset), bits[33:47], 'EPIRB-AIS System Identity:', 'No EPIRB-AIS System' ]) else: self.epirb_ais_str = str(self.epirb_ais).zfill(4) self.epirb_ais_str = '974xx' + self.epirb_ais_str self.tablebin.append([ self.bitlabel(124, 137, deduct_offset), bits[33:47], 'EPIRB-AIS System Identity', self.epirb_ais_str ]) ############################# # Vessel 2: Radio Call Sign # ############################# elif self.vesselID == '010': self.callsign = Func.getCallsign(bits[3:45]) self.tablebin.append([ self.bitlabel(94, 135, deduct_offset), bits[3:45], 'Radio Callsign', self.callsign ]) if Func.checkzeros(bits[45:47]): status_check = 'OK' else: status_check = 'ERROR' self.tablebin.append([ self.bitlabel(136, 137, deduct_offset), bits[45:47], 'Spare should be 0', status_check ]) ######################################################### # Vessel 3: Aricraft Registration Marking (Tail Number) # ######################################################### elif self.vesselID == '011': self.tailnum = Func.getTailNum(bits[3:45]) self.tablebin.append([ self.bitlabel(94, 135, deduct_offset), bits[3:45], 'Aircraft Registration Marking:', self.tailnum ]) if bits[45:47] == '00': status_check = 'OK' else: status_check = 'ERROR' self.tablebin.append([ self.bitlabel(136, 137, deduct_offset), bits[45:47], 'Spare should be 0', status_check ]) ############################################## # Vessel 4: Aircraft Aviation 24 Bit Address # ############################################## elif self.vesselID == '100': self.aviationBitAddress = Func.bin2dec(bits[3:27]) self.tablebin.append([ self.bitlabel(94, 117, deduct_offset), bits[3:27], 'Aviation 24 bit address', str(self.aviationBitAddress) ]) if Func.checkzeros(bits[27:47]): status_check = 'OK' else: status_check = 'ERROR' self.tablebin.append([ self.bitlabel(118, 137, deduct_offset), bits[27:47], 'Spare should be 0', status_check ]) ################################################# # Vessel 5: Aircraft Operator and Serial Number # ################################################# elif self.vesselID == '101': self.operator = Func.baudot2str(bits[3:21], 3) self.serialnum = Func.bin2dec(bits[21:33]) self.tablebin.append([ self.bitlabel(94, 111, deduct_offset), bits[3:21], 'Aircraft operator:', self.operator ]) self.tablebin.append([ self.bitlabel(112, 123, deduct_offset), bits[21:33], 'Serial number:', str(self.serialnum) ]) if Func.checkones(bits[33:47]): status_check = 'OK' else: status_check = 'ERROR' self.tablebin.append([ self.bitlabel(124, 137, deduct_offset), bits[33:47], 'Spare all should be 1', status_check ])
def vesselIDfill(self, deduct_offset, bits): self.vesselID = bits[0:3] self.tablebin.append([ self.bitlabel(91, 93, deduct_offset), self.vesselID, 'Vessel ID Type', Func.getVesselid(self.vesselID) ]) if self.vesselID == '111' and self.bits[ 43] == '0' and deduct_offset != 45: e = 'ERROR! Bit 43 is 0 for system testing message. When vessel ID bits are set to 111, vessel id field is reserved for system testing and the test bit 43 must be 1 for non-operational use.' self.tablebin.append( ['', 'Vessel ID', 'Reserved for system testing', e]) self.errors.append(e) self.validhex = False elif self.vesselID == '111' and self.bits[ 45] == '0' and deduct_offset == 45: e = 'ERROR! Test flag bit 45 in SGB 23 Hex ID (bit 43 in full message) set to 0 for system testing message. When vessel ID bits are set to 111, vessel id field is reserved for system testing and the test bit 45 must be 1 for non-operational use.' self.tablebin.append( ['', 'Vessel ID', 'Reserved for system testing', e]) self.errors.append(e) self.validhex = False ############################################## # Vessel 0: No aircraft or maritime identity # ############################################## if self.vesselID == '000': if Func.checkzeros(bits[3:47]): self.tablebin.append([ self.bitlabel(94, 137, deduct_offset), bits[3:47], 'Vessel ID', 'With vessel id type set to none (000), bits 94-137 all 0. Valid' ]) else: e = 'Warning: With Vessel ID type set to none (000), bits 94-137 should be all 0 (unless national assigned)' self.tablebin.append([ self.bitlabel(94, 137, deduct_offset), bits[3:47], 'Vessel ID', e ]) self.errors.append(e) self.validhex = False ########################### # Vessel 1: Maritime MMSI # ########################### elif self.vesselID == '001': self.mmsi = Func.bin2dec(bits[3:33]) if self.mmsi == 111111: self.mmsi_string = 'No MMSI available' self.tablebin.append([ self.bitlabel(94, 123, deduct_offset), bits[3:33], 'MMSI:', self.mmsi_string ]) else: self.mmsi_string = str(self.mmsi).zfill(9) self.tablebin.append([ self.bitlabel(94, 123, deduct_offset), bits[3:33], 'Unique ship station identity where the first 3 digits are MID (MIDxxxxxx):', self.mmsi_string ]) self.mmsi_country = Func.countryname(int( self.mmsi_string[0:3])) self.tablebin.append([ '', '', 'Flag state of vessel:', self.mmsi_string[0:3] + ' ' + self.mmsi_country ]) self.tablebin.append( ['', '', 'Unique vessel number', self.mmsi_string[3:]]) self.epirb_ais = Func.bin2dec(bits[33:47]) if self.epirb_ais == 10922: self.epirb_ais_str = 'No EPIRB-AIS System' self.tablebin.append([ self.bitlabel(124, 137, deduct_offset), bits[33:47], 'EPIRB-AIS System Identity:', self.epirb_ais_str ]) else: self.epirb_ais_str = str(self.epirb_ais).zfill(4) self.epirb_ais_str = '974xx' + self.epirb_ais_str self.tablebin.append([ self.bitlabel(124, 137, deduct_offset), bits[33:47], 'EPIRB-AIS System Identity', self.epirb_ais_str ]) self._id = '{}-{}'.format(self.mmsi_string, self.epirb_ais_str) ############################# # Vessel 2: Radio Call Sign # ############################# elif self.vesselID == '010': self.callsign = Func.getCallsign(bits[3:45]) self._id = self.callsign self.tablebin.append([ self.bitlabel(94, 135, deduct_offset), bits[3:45], 'Radio Callsign', self.callsign, definitions.moreinfo['sgb_radio_callsign'] ]) if Func.checkzeros(bits[45:47]): status_check = 'OK' else: status_check = 'ERROR' self.validhex = False self.tablebin.append([ self.bitlabel(136, 137, deduct_offset), bits[45:47], 'Spare should be 0', status_check ]) ######################################################### # Vessel 3: Aricraft Registration Marking (Tail Number) # ######################################################### elif self.vesselID == '011': self.tailnum = Func.getTailNum(bits[3:45]) self._id = self.tailnum self.tablebin.append([ self.bitlabel(94, 135, deduct_offset), bits[3:45], 'Aircraft Registration Marking:', self.tailnum ]) if bits[45:47] == '00': status_check = 'OK' else: status_check = 'ERROR' self.validhex = False self.tablebin.append([ self.bitlabel(136, 137, deduct_offset), bits[45:47], 'Spare should be 00', status_check ]) ############################################################ # Vessel 4: Aircraft Aviation 24 Bit Address (and ICAO 3LD)# ############################################################ elif self.vesselID == '100': self.aviationBitAddress = Func.bin2dec(bits[3:27]) h = Func.bin2hex(bits[3:27]) self._id = ' Decimal: {} Hex: {}'.format(self.aviationBitAddress, h) self.tablebin.append([ self.bitlabel(94, 117, deduct_offset), bits[3:27], 'Aviation 24 bit address', self._id ]) if Func.checkzeros(bits[27:47]): status_check = 'OK' self.tablebin.append([ self.bitlabel(118, 137, deduct_offset), bits[27:47], 'Spare should be 0 ', status_check ]) elif not Func.checkzeros(bits[27:47]): self.operator = Func.baudotshort2str(bits[27:42], 3) self.tablebin.append([ self.bitlabel(138, 152, deduct_offset + 20), bits[27:42], 'Aircraft operator designator:', self.operator ]) if not Func.checkzeros(bits[42:47]): status_check = 'ERROR' self.validhex = False else: status_check = 'OK' self.tablebin.append([ self.bitlabel(153, 157, deduct_offset + 20), bits[42:47], 'Spare should be 0 ', status_check ]) ################################################# # Vessel 5: Aircraft Operator and Serial Number # ################################################# elif self.vesselID == '101': self.operator = Func.baudotshort2str(bits[3:18], 3) self._id = 'Aircraft Operator: {} Aircraft Serial No. #{}'.format( self.operator, Func.bin2dec(bits[21:33])) # self.SerialNum = Func.bin2dec(bits[21:33]) self.tablebin.append([ self.bitlabel(94, 108, deduct_offset), bits[3:18], 'Aircraft operator designator:', self.operator ]) self.tablebin.append([ self.bitlabel(109, 120, deduct_offset), bits[21:33], 'Aircraft serial number:', str(Func.bin2dec(bits[21:33])) ]) if Func.checkones(bits[33:50]): status_check = 'OK' else: status_check = 'ERROR' self.validhex = False self.tablebin.append([ self.bitlabel(124, 137, deduct_offset), bits[33:47], 'Spare 17 bits all should be 1', status_check ]) elif self.vesselID == '111' and self.bits[43] == '1': self.tablebin.append([ self.bitlabel(94, 137, deduct_offset), bits[3:47], 'Vessel ID', 'Reserved for system testing and test protocol bit 43 set to 1. Bits may contain information whereas default bits 94-137 normally 0s' ]) elif self.vesselID == '111' and self.bits[43] == '0': self.tablebin.append([ self.bitlabel(94, 137, deduct_offset), bits[3:47], 'Vessel ID', 'Reserved for system testing' ]) elif self.vesselID == '110': e = 'ERROR! Vessel ID type 110 not defined by T.018. Should not be used' self.tablebin.append([ self.bitlabel(94, 137, deduct_offset), bits[3:47], 'Spare', e ]) self.errors.append(e) self.validhex = False
def processHex(self, strhex): ##All second generation beacon messages must be EXACTLY 250 bits ##in length for the program to function properly. self.bits = Func.hex2bin(strhex) self.bchstring = '' self.tablebin = [] self.rotatingbin = [] self.longitude = self.latitude = 'na' self.location = (0, 0) self.courseloc = ('na', 'na') self.errors = [] self.fixedbits = '' self.testprotocol = '' if len(self.bits) == 252 or len(self.bits) == 204: self.type = "Complete message" pbit = self.bits[0:2] if pbit == '00': padding = 'OK' else: padding = 'ERROR! left padding should be 00' self.errors.append(padding) ##Add an additional bit to ensure that bits in array line up with bits in documentation and only include important bits 1-202 self.bits = "0" + self.bits[2:] ##Add the 23 Hex ID to our table self.beaconHexID = self.uinSgb() self.tablebin.append( ['', '', 'Beacon 23 Hex ID:', self.beaconHexID]) self.tablebin.append(['left padding', pbit, '', padding]) ##BIT 1-20 Type Approval Certificate # self.tac = Func.bin2dec(self.bits[1:21]) if self.tac < 10000: warn = 'WARNING!: SGB requires TAC No >=10,000' else: warn = '' self.tablebin.append([ '1-20', self.bits[1:21], 'Type Approval Cert No: ' + str(self.tac), warn ]) ##BIT 21-30 Serial Number self.serialNum = Func.bin2dec(self.bits[21:31]) self.tablebin.append([ '21-30', self.bits[21:31], 'Serial Number:', str(self.serialNum) ]) ##BIT 31-40 Country code self.countryCode = Func.bin2dec(self.bits[31:41]) self.countryName = Func.countryname(self.countryCode) self.tablebin.append([ '31-40', self.bits[31:41], 'Country code:', str(self.countryCode) + ' ' + str(self.countryName) ]) ##BIT 41 Status of homing device self.status = Func.homing(self.bits[41]) self.tablebin.append( ['41', self.bits[41], 'Status of homing device:', self.status]) ##BIT 42 Self-test function self.selfTestStatus = Func.selfTest(self.bits[42]) self.tablebin.append( ['42', self.bits[42], 'Self-test flag:', self.selfTestStatus]) ##BIT 43 Test protocol self.testprotocol = Func.testProtocol(self.bits[43]) self.tablebin.append([ '43', self.bits[43], 'Test protocol flag:', self.testprotocol ]) ##BIT 44-90 Encoded GNSS location self.latitude = Func.getlatitude(self.bits[44:67]) self.tablebin.append( ['44-66', self.bits[44:67], 'Latitude:', self.latitude[0]]) self.longitude = Func.getlongitude(self.bits[67:91]) self.tablebin.append( ['67-90', self.bits[67:91], 'Longitude:', self.longitude[0]]) self.location = (self.latitude[1], self.longitude[1]) ################################ # # # BIT 91-137 VESSEL ID FIELD # # # ################################ self.vesselIDfill(0, self.bits[91:138]) ## BIT 138-139 Beacon Type self.tablebin.append([ '138-139', self.bits[138:140], 'Beacon Type:', Func.getBeaconType(self.bits[138:140]) ]) ## BIT 140 RLS capability self.tablebin.append([ '140', self.bits[140], 'RLS capability:', Func.rls(self.bits[140]) ]) ##BIT 140-154 Spare bits if Func.checkones(self.bits[141:155]) and not Func.checkones( self.bits[155:159]): self.tablebin.append([ '141-154', self.bits[141:155], 'Spare bits', 'OK - all bits 1 and rotating field not a cancellation message' ]) elif Func.checkones(self.bits[141:155]) and Func.checkones( self.bits[155:159]): e = 'ERROR! - all bits 1 and rotatating field is a cancellation message (for a cancellation message these bits should be set to 0)' self.errors.append(e) self.tablebin.append( ['141-154', self.bits[141:155], 'Spare bits', e]) elif Func.checkzeros(self.bits[141:155]) and Func.checkones( self.bits[155:159]): self.tablebin.append([ '141-154', self.bits[141:155], 'Spare bits', 'OK - all bits 0 and rotating field is cancellation message (unless this is a cancellation message, these bits should be set to 1' ]) elif Func.checkzeros(self.bits[141:155]) and not Func.checkones( self.bits[155:159]): e = 'ERROR!- all bits 0 and rotating field is not cancellation message' self.errors.append(e) self.tablebin.append( ['141-154', self.bits[141:155], 'Spare bits', e]) else: e = 'ERROR: Bits 141-154 should be set to all 1 or all 0 in the case that the rotating field is a cancellation message' self.errors.append(e) self.tablebin.append([ '141-154', self.bits[141:155], 'Cancellation message status:', e ]) ####################################### # # # BIT 155-202 48 BIT ROTATING FIELD # # # ####################################### self.rotatingID = Func.bin2dec(self.bits[155:159]) ###################################################### # Rotating Field 0: C/S G.008 Objective Requirements # ###################################################### if self.rotatingID == 0: self.tablebin.append([ '155-158 (Rotating field 1-4)', self.bits[155:159], 'Rotating Field Type:', '(#0) C/S G.008 Objective Requirements' ]) self.rotatingbin = rotating.rotating0(self.bits[155:203]) ######################################## # Rotating Field 1: Inflight Emergency # ######################################## elif self.rotatingID == 1: self.tablebin.append([ '155-158 (Rotating field 1-4)', self.bits[155:159], 'Rotating Field Type:', '(#1) Inflight Emergency' ]) self.rotatingbin = rotating.rotating1(self.bits[155:203]) ######################### # Rotating Field 2: RLS # ######################### elif self.rotatingID == 2: self.tablebin.append([ '155-158 (Rotating field 1-4)', self.bits[155:159], 'Rotating Field Type:', '(#2) RLS' ]) self.rotatingbin = rotating.rotating2(self.bits[155:203]) ################################## # Rotating Field 3: National Use # ################################## elif self.rotatingID == 3: self.tablebin.append([ '155-158 (Rotating field 1-4)', self.bits[155:159], 'Rotating Field Type:', '(#3) National Use' ]) self.rotatingbin = rotating.rotating3(self.bits[155:203]) ########################################### # Rotating Field 15: Cancellation Message # ########################################### elif self.rotatingID == 15: self.tablebin.append([ '155-158 (Rotating field 1-4)', self.bits[155:159], 'Rotating Field Type:', '(#15) Cancellation Message' ]) self.rotatingbin = rotating.rotating15(self.bits[155:203]) ################################## # All other rotating fields spare # ################################## else: self.tablebin.append([ '155-158 (Rotating field 1-4)', self.bits[155:159], 'Rotating Field Type:', 'Spare' ]) ##Add rotating field data to our list self.tablebin.extend(self.rotatingbin) #################################### # 48-BIT BCH ERROR CORRECTING CODE # #################################### if len(self.bits) == 251: self.tablebin.append( ['203-250', self.bits[203:], 'Encoded BCH', 'Encoded BCH']) ##Calculate the BCH self.calculatedBCH = Func.calcBCH(self.bits[1:], 0, 202, 250) self.bchstring = writebch.calcBCH(self.bits[1:], 0, 202, 250)[1] self.tablebin.append( ['Calculated', self.calculatedBCH, 'Computed', '']) ##Compare to the BCH in the beacon message bcherr = self.BCHerrors = Func.errors(self.calculatedBCH, self.bits[203:]) if bcherr > 0: bcherror = 'COMPUTED BCH DOES NOT MATCH ENCODED BCH!!' self.errors.append(bcherror) self.tablebin.append(['', '', '', bcherror]) elif len(self.bits) == 92: self.type = 'uin' ##Add an additional bit to ensure that bits in array line up with bits in documentation self.bits = "0" + self.bits self.latitude = self.longitude = 'No data available' self.tablebin.append(['Unique ID', 'Second Generation', '', '']) self.tablebin.append([ '1', self.bits[1], 'should be 1', ['ERROR', 'OK'][int(self.bits[1])] ]) ##BIT 2-11 Country code self.countryCode = Func.bin2dec(self.bits[2:12]) self.countryName = Func.countryname(self.countryCode) self.tablebin.append([ '2-11', self.bits[2:12], 'Country code:', str(self.countryCode) + ' ' + str(self.countryName) ]) ##BIT 12-14 Should be 101 if self.bits[12:15] == '101': status_check = 'OK' else: status_check = 'ERROR' self.tablebin.append( ['12-14', self.bits[12:15], 'Should be 101', status_check]) ##BIT 15-34 Type Approval Certificate # self.tac = Func.bin2dec(self.bits[15:35]) if self.tac < 10000: warn = 'WARNING! SGB specifications requires TAC No >=10,000' else: warn = '' self.tablebin.append([ '15-34', self.bits[15:35], 'Type Approval Cert No: ' + str(self.tac), warn ]) ##BIT 35-44 Beacon Serial Number self.serialNum = Func.bin2dec(self.bits[35:45]) self.tablebin.append([ '35-44', self.bits[35:45], 'Serial Number', str(self.serialNum) ]) if self.bits[61:] == '0' * 32: print('truncated sgb 15 hex id') self.tablebin.append([ '45-47', self.bits[45:48], 'Vessel ID Type', Func.getVesselid(self.bits[45:48]) ]) self.tablebin.append([ '48-60', self.bits[48:], 'Remaining bits', 'Truncated SGB Hex ID does not allow vessel ID information to be decoded' ]) else: ##BIT 45-91 Aircraft / Vessel ID self.vesselIDfill(46, self.bits[45:92]) ##BIT 92 Fixed value 1 if self.bits[92] == '1': status_check = 'OK' else: status_check = 'ERROR' self.tablebin.append( ['92', self.bits[92], 'Fixed 1', status_check]) else: self.type = ( 'Hex string length of ' + str(len(strhex)) + '.' + '\nBit string length of ' + str(len(self.bits)) + '.' + '\nLength of First Gen Beacon Hex String must be 15, 22 or 30' + '\nLength of Second Gen Beacon Bit String must be 204 or 252 bits' ) raise Gen2Error('LengthError', self.type)
def processHex(self, strhex): ##All second generation beacon messages must be EXACTLY 250 bits ##in length for the program to function properly. self.bits = Func.hex2bin(strhex) if len(self.bits) == 250 or len(self.bits) == 202: self.tablebin = [] self.rotatingbin = [] ##Add an additional bit to ensure that bits in array line up with bits in documentation self.bits = "0" + self.bits ##BIT 1-20 Type Approval Certificate # self.tac = Func.bin2dec(self.bits[1:21]) self.tablebin.append([ '1-20', self.bits[1:21], 'Type Approval Certificate #:', str(self.tac) ]) ##BIT 21-30 Serial Number self.serialNum = Func.bin2dec(self.bits[21:31]) self.tablebin.append([ '21-30', self.bits[21:31], 'Serial Number:', str(self.serialNum) ]) ##BIT 31-40 Country code self.countryCode = Func.bin2dec(self.bits[31:41]) self.countryName = Func.countryname(self.countryCode) self.tablebin.append([ '31-40', self.bits[31:41], 'Country code:', str(self.countryCode) + ' ' + str(self.countryName) ]) ##BIT 41 Status of homing device self.status = Func.homing(self.bits[41]) self.tablebin.append( ['41', self.bits[41], 'Status of homing device:', self.status]) ##BIT 42 Self-test function self.selfTestStatus = Func.selfTest(self.bits[42]) self.tablebin.append([ '42', self.bits[42], 'Self-test function:', self.selfTestStatus ]) ##BIT 43 User cancellation self.cancel = Func.cancellation(self.bits[43]) self.tablebin.append( ['43', self.bits[43], 'User cancellation:', self.cancel]) ##BIT 44-90 Encoded GNSS location self.latitude = Func.getlatitude(self.bits[44:67]) self.tablebin.append( ['44-66', self.bits[44:67], 'Latitude:', self.latitude[0]]) self.longitude = Func.getlongitude(self.bits[67:91]) self.tablebin.append( ['67-90', self.bits[67:91], 'Longitude:', self.longitude[0]]) self.location = (self.latitude[1], self.longitude[1]) ################################ # # # BIT 91-137 VESSEL ID FIELD # # # ################################ self.vesselID = self.bits[91:94] ############################################## # Vessel 0: No aircraft or maritime identity # ############################################## if self.vesselID == '000': self.tablebin.append([ '91-93', self.bits[91:94], 'Vessel ID:', 'No aircraft or maritime identity' ]) if Func.checkzeros(self.bits[94:138]): self.tablebin.append( ['94-137', self.bits[94:138], 'Spare:', 'All 0 - OK']) else: self.tablebin.append([ '94-137', self.bits[94:138], 'Spare:', 'ERROR: Bits 94-137 should be 0' ]) ########################### # Vessel 1: Maritime MMSI # ########################### elif self.vesselID == '001': self.tablebin.append( ['91-93', self.bits[91:94], 'Vessel ID:', 'MMSI']) self.mmsi = Func.bin2dec(self.bits[94:124]) if self.mmsi == 111111: self.tablebin.append([ '94-123', self.bits[94:124], 'MMSI:', 'No MMSI available' ]) else: self.mmsi_string = str(self.mmsi).zfill(9) self.tablebin.append([ '94-123', self.bits[94:124], 'Unique ship station identity M1I2D3X4X5X6X7X8X9:', self.mmsi_string ]) self.mmsi_country = Func.countryname( int(self.mmsi_string[0:3])) self.tablebin.append([ '', '', 'Flag state of vessel:', self.mmsi_string[0:3] + ' ' + self.mmsi_country ]) self.tablebin.append([ '', '', 'Unique vessel number:', self.mmsi_string[3:] ]) self.epirb_ais = Func.bin2dec(self.bits[124:138]) if self.epirb_ais == 10922: self.tablebin.append([ '124-137', self.bits[124:138], 'EPIRB-AIS System Identity:', 'No EPIRB-AIS System' ]) else: self.epirb_ais_str = str(self.epirb_ais).zfill(4) self.epirb_ais_str = '974' + self.mmsi_string[ 3:5] + self.epirb_ais_str self.tablebin.append([ '124-137', self.bits[123:137], 'EPIRB-AIS System Identity:', self.epirb_ais_str ]) ############################# # Vessel 2: Radio Call Sign # ############################# elif self.vesselID == '010': self.tablebin.append([ '91-93', self.bits[91:94], 'Vessel ID:', 'Radio Call Sign' ]) self.callsign = Func.getCallsign(self.bits[94:136]) self.tablebin.append([ '94-135', self.bits[94:136], 'Radio Callsign:', self.callsign ]) if Func.checkzeros(self.bits[136:138]): self.tablebin.append([ '136-137', self.bits[136:138], 'Spare:', 'All 0 - OK' ]) else: self.tablebin.append([ '136-137', self.bits[136:138], 'Spare:', 'ERROR: Bits 136-137 should be all 0s' ]) ######################################################### # Vessel 3: Aricraft Registration Marking (Tail Number) # ######################################################### elif self.vesselID == '011': self.tablebin.append([ '91-93', self.bits[91:94], 'Vessel ID:', 'Aircraft Registration Marking (Tail Number)' ]) self.tailnum = Func.getTailNum(self.bits[94:136]) self.tablebin.append([ '94-135', self.bits[94:136], 'Aircraft Registration Marking:', self.tailnum ]) if Func.checkzeros(self.bits[135:137]): self.tablebin.append( ['136-137', self.bits[136:138], 'Spare:', 'OK']) else: self.tablebin.append([ '136-137', self.bits[136:138], 'Spare:', 'ERROR: Bits 136-137 should be all 0s' ]) ############################################## # Vessel 4: Aircraft Aviation 24 Bit Address # ############################################## elif self.vesselID == '100': self.tablebin.append([ '91-93', self.bits[91:94], 'Vessel ID:', 'Aircraft Aviation 24 Bit Address' ]) self.aviationBitAddress = Func.bin2dec(self.bits[93:117]) self.tablebin.append([ '94-117', self.bits[94:118], 'Aviation 24 bit address:', str(self.aviationBitAddress) ]) if Func.checkzeros(self.bits[117:137]): self.tablebin.append( ['118-137', self.bits[118:138], 'Spare:', 'OK']) else: self.tablebin.append([ '118-137', self.bits[118:138], 'Spare:', 'ERROR: Bits 118-137 following aviation 24 bit address should be 0' ]) ################################################# # Vessel 5: Aircraft Operator and Serial Number # ################################################# elif self.vesselID == '101': self.tablebin.append([ '91-93', self.bits[91:94], 'Vessel ID:', 'Aircraft Operator and Serial Number' ]) self.operator = Func.baudot2str(self.bits[94:112], 3) self.serialnum = Func.bin2dec(self.bits[112:124]) self.tablebin.append([ '94-111', self.bits[94:112], 'Aircraft operator:', self.operator ]) self.tablebin.append([ '112-123', self.bits[112:124], 'Serial number:', str(self.serialnum) ]) if Func.checkones(self.bits[124:138]): self.tablebin.append( ['124-137', self.bits[124:138], 'Spare:', 'OK']) else: self.tablebin.append([ '124-137', self.bits[124:138], 'Spare:', 'ERROR: Bits 124-137 following aircraft operator and serial numbers should be 1' ]) ########################## # Other Vessel IDs Spare # ########################## else: self.tablebin.append( ['91-93', self.bits[91:94], 'Vessel ID:', 'Spare']) ##BIT 138-154 Spare bits [137-153] if Func.checkones(self.bits[138:155]): self.tablebin.append( ['138-154', self.bits[138:155], 'Spare:', 'OK']) else: self.tablebin.append([ '138-154', self.bits[138:155], 'Spare:', 'ERROR: Bits 138-154 should be 1s' ]) ####################################### # # # BIT 155-202 48 BIT ROTATING FIELD # # # ####################################### self.rotatingID = Func.bin2dec(self.bits[155:159]) ###################################################### # Rotating Field 0: C/S G.008 Objective Requirements # ###################################################### if self.rotatingID == 0: self.tablebin.append([ '155-158 (Rotating field 1-4)', self.bits[155:159], 'Rotating Field Type:', '(#0) C/S G.008 Objective Requirements' ]) self.rotatingbin = rotating.rotating0(self.bits[155:203]) ######################################## # Rotating Field 1: Inflight Emergency # ######################################## elif self.rotatingID == 1: self.tablebin.append([ '155-158 (Rotating field 1-4)', self.bits[155:159], 'Rotating Field Type:', '(#1) Inflight Emergency' ]) self.rotatingbin = rotating.rotating1(self.bits[155:203]) ######################### # Rotating Field 2: RLS # ######################### elif self.rotatingID == 2: self.tablebin.append([ '155-158 (Rotating field 1-4)', self.bits[155:159], 'Rotating Field Type:', '(#2) RLS' ]) self.rotatingbin = rotating.rotating2(self.bits[155:203]) ################################## # Rotating Field 3: National Use # ################################## elif self.rotatingID == 3: self.tablebin.append([ '155-158 (Rotating field 1-4)', self.bits[155:159], 'Rotating Field Type:', '(#3) National Use' ]) self.rotatingbin = rotating.rotating3(self.bits[155:203]) ########################################### # Rotating Field 15: Cancellation Message # ########################################### elif self.rotatingID == 15: self.tablebin.append([ '155-158 (Rotating field 1-4)', self.bits[155:159], 'Rotating Field Type:', '(#15) Cancellation Message' ]) self.rotatingbin = rotating.rotating15(self.bits[155:203]) ################################## # All other roating fields spare # ################################## else: self.tablebin.append([ '155-158 (Rotating field 1-4)', self.bits[155:159], 'Rotating Field Type:', 'Spare' ]) ##Add rotating field data to our list self.tablebin.extend(self.rotatingbin) #################### # BEACON 23 HEX ID # #################### self.hexID = [] ##Hex ID BIT 1 = fixed binary 1 self.hexID.append('1') ##Hex ID BIT 2-11 = BITS 31-40 (C/S Country Code) self.hexID.append(self.bits[31:41]) ##Hex ID BIT 12 = fixed binary 1 self.hexID.append('1') ##Hex ID BIT 13 = fixed binary 0 self.hexID.append('0') ##Hex ID BIT 14 = fixed binary 1 self.hexID.append('1') ##Hex ID BIT 15-34 = BITS 1-20 (C/S TAC No) self.hexID.append(self.bits[1:21]) ##Hex ID BIT 35-44 = BITS 21-30 (Beacon Serial Number) self.hexID.append(self.bits[21:31]) ##Hex ID BIT 45-47 = BITS 91-93 (Aircraft/Vessel ID Type) self.hexID.append(self.bits[91:94]) ##Hex ID BIT 48-91 = BITS 94-137 (Aircraft/Vessel ID) self.hexID.append(self.bits[94:138]) ##Hex ID BIT 92 = fixed binary 1 self.hexID.append('1') ##Join list together and convert to Hexadecimal self.beaconHexID = Func.bin2hex(''.join(self.hexID)) ##Add the 23 Hex ID to our table self.tablebin.append( ['', '', 'Beacon 23 Hex ID:', self.beaconHexID]) #################################### # 48-BIT BCH ERROR CORRECTING CODE # #################################### if len(self.bits) == 251: ##Calculate the BCH self.calculatedBCH = Func.calcBCH(self.bits[1:], 0, 202, 250) ##Compare to the BCH in the beacon message self.BCHerrors = Func.errors(self.calculatedBCH, self.bits[203:]) ##Write the number of errors to our table self.tablebin.append( ['', '', 'Number of BCH errors:', str(self.BCHerrors)]) else: self.type = ( 'Hex string length of ' + str(len(strhex)) + '.' + '\nBit string length of ' + str(len(self.bits)) + '.' + '\nLength of First Gen Beacon Hex String must be 15, 22 or 30' + '\nLength of Second Gen Beacon Bit String must be 250 bits') raise Gen2Error('LengthError', self.type)
def processHex(self, strhex): ##All second generation beacon messages must be EXACTLY 250 bits ##in length for the program to function properly. self.bits = Func.hex2bin(strhex) self.inputhex = strhex self.bchstring = '' self.tablebin = [] self.rotatingbin = [] self.longitude = self.latitude = 'na' self.location = (0, 0) self.courseloc = ('na', 'na') self.errors = [] self.warnings = [] self.fixedbits = '' self.testprotocol = '' self._id = 'na' self.SerialNum = 0 self.tac = 0 if len(self.bits) == 252 or len(self.bits) == 204: self.type = "Complete SGB message" pbit = self.bits[0:2] if pbit == '00': padding = 'Normal mode transmission (i.e., operational mode)' elif pbit == '10': padding = 'Self-test mode transmission' else: padding = 'ERROR! first two bits not 00 nor 10' self.errors.append(padding) self.tablebin.append(['Left pad', pbit, '', padding]) ##Add an additional bit to ensure that bits in array line up with bits in documentation and only include important bits 1-202 self.bits = "0" + self.bits[2:] ##Add the 23 Hex ID to our table self.beaconHexID = self.uinSgb() #self.tablebin.append(['','','Beacon 23 Hex ID:',self.beaconHexID]) #self.tablebin.append(['left padding',pbit,'',padding]) ##T018 Issue 1 - Rev 4: Bit 1-16 Type Approval Certificate # (previously BIT 1-20 Type Approval Certificate #) self.tac = Func.bin2dec(self.bits[1:17]) if self.tac < 10000: warn = '# {} Warning: SGB specifications stipulate TAC No should be greater than 10,000'.format( self.tac) self.warnings.append('TAC ' + warn) elif self.tac > 65520: warn = '# {} - System beacon'.format(self.tac) else: warn = '# {}'.format(self.tac) self.tablebin.append( ['1-16', self.bits[1:17], 'Type Approval Cert No: ', warn]) ##T018 Issue 1 - Rev 4: Bit 17-30 Serial Number (previously bit 21-30 Serial Number) self.SerialNum = Func.bin2dec(self.bits[17:31]) self.tablebin.append([ '17-30', self.bits[17:31], 'Beacon serial number:', str(self.SerialNum) ]) ##BIT 31-40 Country code self.countryCode = Func.bin2dec(self.bits[31:41]) self.countryName = Func.countryname(self.countryCode) self.tablebin.append([ '31-40', self.bits[31:41], 'Country code:', str(self.countryCode) + ' ' + str(self.countryName), definitions.moreinfo['country_code'] ]) ##BIT 41 Status of homing device self.status = Func.homing(self.bits[41]) self.tablebin.append( ['41', self.bits[41], 'Status of homing device:', self.status]) ####T018 Issue 1 - Rev 4: Bit 42: RLS Function ( previously Bit 42 Self-test function ) self.tablebin.append([ '42', self.bits[42], 'RLS function capability:', Func.rls(self.bits[42]) ]) ##BIT 43 Test protocol self.testprotocol = Func.testProtocol(self.bits[43]) self.tablebin.append([ '43', self.bits[43], 'Test protocol flag:', self.testprotocol ]) ##BIT 44-90 Encoded GNSS location self.latitude = Func.getlatitude(self.bits[44:67]) if 'Invalid' in self.latitude[0]: self.errors.append(self.latitude[0]) self.tablebin.append( ['44-66', self.bits[44:67], 'Latitude:', self.latitude[0]]) self.longitude = Func.getlongitude(self.bits[67:91]) if 'Invalid' in self.longitude[0]: self.errors.append(self.longitude[0]) self.tablebin.append( ['67-90', self.bits[67:91], 'Longitude:', self.longitude[0]]) self.location = (self.latitude[1], self.longitude[1]) ################################ # # # BIT 91-137 VESSEL ID FIELD # # # ################################ self.vesselIDfill(0, self.bits[91:138]) ## T018 Iss.1 Rev.4 Bit 138-140 Beacon Type (previous (Bit 138-139 Beacon Type) self.tablebin.append([ '138-140', self.bits[138:141], 'Beacon Type:', Func.getBeaconType(self.bits[138:141]) ]) ## T018 Iss.1 Rev.4 removed ''' self.tablebin.append(['140', self.bits[140], 'RLS capability:', Func.rls(self.bits[140])]) ''' ##BIT 141-154 Spare bits if Func.checkones(self.bits[141:155]) and not Func.checkones( self.bits[155:159]): self.tablebin.append([ '141-154', self.bits[141:155], 'Spare bits', 'OK - all bits 1 and rotating field not a cancellation message' ]) elif Func.checkones(self.bits[141:155]) and Func.checkones( self.bits[155:159]): e = 'ERROR! - all bits 1 and rotatating field is a cancellation message (for a cancellation message these bits should be set to 0)' self.errors.append(e) self.tablebin.append( ['141-154', self.bits[141:155], 'Spare bits', e]) elif Func.checkzeros(self.bits[141:155]) and Func.checkones( self.bits[155:159]): self.tablebin.append([ '141-154', self.bits[141:155], 'Spare bits', 'OK - all bits 0 and rotating field is cancellation message (unless this is a cancellation message, these bits should be set to 1' ]) elif Func.checkzeros(self.bits[141:155]) and not Func.checkones( self.bits[155:159]): e = 'ERROR!- all bits 0 and rotating field is not cancellation message' self.errors.append(e) self.tablebin.append( ['141-154', self.bits[141:155], 'Spare bits', e]) else: e = 'ERROR: Bits 141-154 should be set to all 1 or all 0 in the case that the rotating field is a cancellation message' self.errors.append(e) self.tablebin.append([ '141-154', self.bits[141:155], 'Cancellation message status:', e ]) ####################################### # # # BIT 155-202 48 BIT ROTATING FIELD # # # ####################################### self.rotatingID = Func.bin2dec(self.bits[155:159]) ###################################################### # Rotating Field 0: C/S G.008 Objective Requirements # ###################################################### if self.rotatingID == 0: self.tablebin.append([ '155-158 (Rotating field 1-4)', self.bits[155:159], 'Rotating Field Type:', '(#0) C/S G.008 Objective Requirements' ]) self.rotatingbin = rotating.rotating0(self.bits[155:203]) ######################################## # Rotating Field 1: Inflight Emergency # ######################################## elif self.rotatingID == 1: self.tablebin.append([ '155-158 (Rotating field 1-4)', self.bits[155:159], 'Rotating Field Type:', '(#1) ELT(DT) In-flight Emergency' ]) self.rotatingbin = rotating.rotating1(self.bits[155:203]) ######################### # Rotating Field 2: RLS # ######################### elif self.rotatingID == 2: self.tablebin.append([ '155-158 (Rotating field 1-4)', self.bits[155:159], 'Rotating Field Type:', '(#2) RLS' ]) self.rotatingbin = rotating.rotating2(self.bits[155:203]) ################################## # Rotating Field 3: National Use # ################################## elif self.rotatingID == 3: self.tablebin.append([ '155-158 (Rotating field 1-4)', self.bits[155:159], 'Rotating Field Type:', '(#3) National Use' ]) self.rotatingbin = rotating.rotating3(self.bits[155:203]) ########################################### # Rotating Field 15: Cancellation Message # ########################################### elif self.rotatingID == 15: self.tablebin.append([ '155-158 (Rotating field 1-4)', self.bits[155:159], 'Rotating Field Type:', '(#15) Cancellation Message' ]) self.rotatingbin = rotating.rotating15(self.bits[155:203]) ################################## # All other rotating fields spare # ################################## else: self.tablebin.append([ '155-158 (Rotating field 1-4)', self.bits[155:159], 'Rotating Field Type:', 'Spare' ]) ##Add rotating field data to our list self.tablebin.extend(self.rotatingbin) #################################### # 48-BIT BCH ERROR CORRECTING CODE # #################################### if len(self.bits) == 251: # 251 length means 250 plus the stub 0, minus the extra 2 digits of front padding in self.bits self.tablebin.append( ['203-250', self.bits[203:], 'Encoded BCH', 'Encoded BCH']) ##Calculate the BCH self.calculatedBCH = Func.calcBCH(self.bits[1:], 0, 202, 250) self.bchstring = writebch.calcBCH(self.bits[1:], 0, 202, 250)[1] self.tablebin.append( ['Calculated', self.calculatedBCH, 'Computed', '']) #self.tablebin.append(['','','','self.calculatedBCH {} : self.bchstring {} {}'.format(self.calculatedBCH,self.bchstring,self.calculatedBCH==self.bchstring)]) ##Compare to the BCH in the beacon message bcherr = self.BCHerrors = Func.errors(self.calculatedBCH, self.bits[203:]) if bcherr > 0: bcherror = 'ERROR! COMPUTED BCH DOES NOT MATCH ENCODED BCH!!' self.errors.append(bcherror) else: bcherror = 'VALID BCH: COMPUTED BCH MATCHES' self.tablebin.append(['', '', '', bcherror]) elif len(self.bits) == 203: # if user enters a hex 51 excluding bch, then this ,means 202 information bits plus stub 0 minues the 2 digits of front padding self.tablebin.append([ '203-250', 'NA', 'Encoded BCH', 'Not provided in a 51 Hex. Computed below' ]) self.calculatedBCH = Func.calcBCH(self.bits[1:], 0, 202, 250) hexBCH = Func.bin2hex(self.calculatedBCH) self.tablebin.append([ '203-250', self.calculatedBCH, 'Calculated BCH', 'Hex Value: {}'.format(hexBCH) ]) self.tablebin.append([ 'Complete Message', '', 'Hex Value: {}{}'.format(self.inputhex, hexBCH), '' ]) elif len(self.bits) == 92: self.type = 'uin' ##Add an additional bit to ensure that bits in array line up with bits in documentation self.bits = "0" + self.bits self.latitude = self.longitude = 'No data available' self.tablebin.append(['Unique ID', 'Second Generation', '', '']) self.tablebin.append([ '1', self.bits[1], 'SGB requires this bit value be 1', ['ERROR', 'OK'][int(self.bits[1])] ]) if self.bits[1] == '0': self.validhex = False self.errors.append( 'Error: SGB beacon UIN fixed first bit not set to 1') ##BIT 2-11 Country code self.countryCode = Func.bin2dec(self.bits[2:12]) self.countryName = Func.countryname(self.countryCode) if self.countryName == 'Unknown MID': self.validhex = False self.errors.append('Error: Bad country code: ' + self.countryName) self.tablebin.append([ '2-11', self.bits[2:12], 'Country code:', str(self.countryCode) + ' ' + str(self.countryName), definitions.moreinfo['country_code'] ]) ##BIT 12-14 Should be 101 status check for SGB if self.bits[12:15] == '101': status_check = 'OK' else: status_check = 'ERROR' self.validhex = False self.errors.append('Error: Bits 12-14 should be 101') self.tablebin.append( ['12-14', self.bits[12:15], 'Should be 101', status_check]) ##BIT 15-30 Type Approval Certificate # self.tac = Func.bin2dec(self.bits[15:31]) if self.tac < 10000: warn = 'Type Approval # {} :: WARNING! SGB specifications requires TAC No >=10,000'.format( self.tac) self.validhex = False self.errors.append(warn) else: warn = str(self.tac) self.tablebin.append( ['15-30', self.bits[15:31], 'Type Approval Cert No: ', warn]) ##BIT 31-44 Beacon Serial Number self.SerialNum = Func.bin2dec(self.bits[31:45]) self.tablebin.append([ '31-44', self.bits[35:45], 'Beacon serial number', str(self.SerialNum) ]) self.testprotocol = Func.testProtocol(self.bits[45]) self.tablebin.append([ '45', self.bits[45], 'Test protocol flag:', str(self.testprotocol) ]) if self.bits[45] == '1': self.validhex = False if self.bits[61:] == '0' * 32 and self.bits[46:49] != '111': self.tablebin.append([ '46-48', self.bits[46:49], 'Vessel ID Type', Func.getVesselid(self.bits[46:49]) ]) self.tablebin.append([ '49-60', self.bits[49:61], 'Partial vessel ID', 'WARNING!! = No Identification information or truncated SGB 15 Hex (incomplete partial vessel ID. ' ]) self.tablebin.append( ['61-92', self.bits[61:], 'Remaining bits', '']) #self.vesselIDfill(46, self.bits[46:93]) else: ##BIT 45-91 Aircraft / Vessel ID self.vesselIDfill(45, self.bits[46:93]) ##T018 Iss.1 Rev 4 removed : (was BIT 92 Fixed value 1) ''' if self.bits[92]=='1': status_check = 'OK' else: status_check = 'ERROR' self.tablebin.append(['92', self.bits[92], 'Fixed 1', status_check]) ''' else: self.type = ( 'Hex string length of ' + str(len(strhex)) + '.' + '\nBit string length of ' + str(len(self.bits)) + '.' + '\nLength of First Gen Beacon Hex String must be 15, 22 or 30' + '\nLength of Second Gen Beacon Bit String must be 204 or 252 bits' ) raise Gen2Error('LengthError', self.type)
try: userInput = raw_input('\nPlease enter country code: ') except EOFError: userInput = 0 try: countrycode = int(userInput) except ValueError: print 'Error: value must be an integer' countrycode = 0 else: bits_countrycode = Func1.dec2bin(countrycode).zfill(10) if len(bits_countrycode) != 10: print 'Error: input too high.' else: break printtxt('Country: {} {} - binary: {}\n'.format(str(countrycode),Func2.countryname(countrycode),bits_countrycode)) ################################ # BIT 91-137 VESSEL ID FIELD # ################################ while next_step == False: vesselID_list=['0: No aircraft or maritime identity', '1: Maritime MMSI', '2: Radio Call Sign', '3: Aircraft Registration Marking (Tail Number)', '4: Aircraft Aviation 24 Bit Address', '5: Aircraft Operator and Serial Number', '6: Spare',
##BIT 31-40 Country code while next_step == False: userInput = raw_input('\nPlease enter country code: ') try: countrycode = int(userInput) except ValueError: print 'Error: value must be an integer' countrycode = 0 else: bits_countrycode = Func1.dec2bin(countrycode).zfill(10) if len(bits_countrycode) != 10: print 'Error: input too high.' else: break print 'You entered: ' + str(countrycode) + ' ' +Func2.countryname(countrycode) ##BIT 41 Status of homing device while next_step == False: print '\nPlease enter homing status: ' print '0: Beacon is not equipped with any homing signals or they have been deliberately disabled. If beacon has been activated, no homing device is functional or it has been deliberately disabled' print '1: Beacon is equipped with at least one homing signal. If beacon has been activated, at least one homing device is functional and transmitting' userInput = raw_input() try: status = int(userInput) except ValueError: print 'Error: value must be an integer' status = 0 else: bits_status = str(status)
def vesselIDfill(self,deduct_offset,bits): self.vesselID = bits[0:3] self.tablebin.append([self.bitlabel(91,93,deduct_offset), self.vesselID , 'Vessel ID Type', Func.getVesselid(self.vesselID)]) if self.vesselID == '111' and self.bits[43]=='0': self.tablebin.append(['','','Reserved for system testing','ERROR! Test protocol bit 43 is zero']) self.validhex=False ############################################## # Vessel 0: No aircraft or maritime identity # ############################################## if self.vesselID == '000': if Func.checkzeros(bits[3:47]): self.tablebin.append([self.bitlabel(94,137,deduct_offset), bits[3:47], 'Vessel ID type is none', 'All 0 - OK']) else: self.tablebin.append([self.bitlabel(94, 137,deduct_offset), bits[3:47], 'Vessel ID type is none', 'Unless national assigned, should be all 0']) self.validhex = False ########################### # Vessel 1: Maritime MMSI # ########################### elif self.vesselID == '001': self.mmsi = Func.bin2dec(bits[3:33]) if self.mmsi == 111111: self.tablebin.append([self.bitlabel(94,123,deduct_offset), bits[3:33], 'MMSI:', 'No MMSI available']) else: self.mmsi_string = str(self.mmsi).zfill(9) self.tablebin.append([self.bitlabel(94,123,deduct_offset), bits[3:33], 'Unique ship station identity where the first 3 digits are MID (MIDxxxxxx):', self.mmsi_string]) self.mmsi_country = Func.countryname(int(self.mmsi_string[0:3])) self.tablebin.append(['', '', 'Flag state of vessel:', self.mmsi_string[0:3] + ' ' + self.mmsi_country]) self.tablebin.append(['', '', 'Unique vessel number', self.mmsi_string[3:]]) self.epirb_ais = Func.bin2dec(bits[33:47]) if self.epirb_ais == 10922: self.tablebin.append([self.bitlabel(124,137,deduct_offset), bits[33:47], 'EPIRB-AIS System Identity:', 'No EPIRB-AIS System']) else: self.epirb_ais_str = str(self.epirb_ais).zfill(4) self.epirb_ais_str = '974xx' + self.epirb_ais_str self.tablebin.append([self.bitlabel(124,137,deduct_offset), bits[33:47], 'EPIRB-AIS System Identity', self.epirb_ais_str]) ############################# # Vessel 2: Radio Call Sign # ############################# elif self.vesselID == '010': self.callsign = Func.getCallsign(bits[3:45]) self.tablebin.append([self.bitlabel(94,135,deduct_offset), bits[3:45], 'Radio Callsign', self.callsign, definitions.moreinfo['sgb_radio_callsign']]) if Func.checkzeros(bits[45:47]): status_check='OK' else: status_check = 'ERROR' self.validhex = False self.tablebin.append([self.bitlabel(136,137,deduct_offset), bits[45:47], 'Spare should be 0', status_check]) ######################################################### # Vessel 3: Aricraft Registration Marking (Tail Number) # ######################################################### elif self.vesselID == '011': self.tailnum = Func.getTailNum(bits[3:45]) self.tablebin.append([self.bitlabel(94,135,deduct_offset), bits[3:45], 'Aircraft Registration Marking:', self.tailnum]) if bits[45:47]=='00': status_check = 'OK' else: status_check = 'ERROR' self.validhex = False self.tablebin.append([self.bitlabel(136,137,deduct_offset), bits[45:47], 'Spare should be 00', status_check]) ############################################## # Vessel 4: Aircraft Aviation 24 Bit Address # ############################################## elif self.vesselID == '100': self.aviationBitAddress = Func.bin2dec(bits[3:27]) self.tablebin.append([self.bitlabel(94,117,deduct_offset), bits[3:27], 'Aviation 24 bit address', str(self.aviationBitAddress)]) if Func.checkzeros(bits[27:47]): status_check = 'OK' else: status_check = 'ERROR' self.validhex = False self.tablebin.append([self.bitlabel(118,137,deduct_offset), bits[27:47], 'Spare should be 0', status_check]) ################################################# # Vessel 5: Aircraft Operator and Serial Number # ################################################# elif self.vesselID == '101': self.operator = Func.baudot2str(bits[3:21], 3) self.serialnum = Func.bin2dec(bits[21:33]) self.tablebin.append([self.bitlabel(94,111,deduct_offset), bits[3:21], 'Aircraft operator designator:', self.operator]) self.tablebin.append([self.bitlabel(112,123,deduct_offset), bits[21:33], 'Aircraft Serial number:', str(self.serialnum)]) if Func.checkones(bits[33:47]): status_check = 'OK' else: status_check = 'ERROR' self.validhex = False self.tablebin.append([self.bitlabel(124,137,deduct_offset), bits[33:47], 'Spare all should be 1', status_check]) elif self.vesselID == '111' and self.bits[43]=='1': self.tablebin.append([self.bitlabel(94, 137, deduct_offset), bits[3:47], 'Reserved for system testing','OK. Test protocol bit 43 set to 1. May contain information; default bits 94-137 - 0s']) elif self.vesselID == '111' and self.bits[43]=='0': self.tablebin.append([self.bitlabel(94, 137, deduct_offset), bits[3:47], 'Reserved for system testing', '']) elif self.vesselID == '110': self.tablebin.append([self.bitlabel(94, 137, deduct_offset), bits[3:47], 'Spare', 'ERROR! Not defined by T.018. Should not be used']) self.validhex = False
userInput = raw_input('\nPlease enter country code: ') except EOFError: userInput = 0 try: countrycode = int(userInput) except ValueError: print 'Error: value must be an integer' countrycode = 0 else: bits_countrycode = Func1.dec2bin(countrycode).zfill(10) if len(bits_countrycode) != 10: print 'Error: input too high.' else: break printtxt('Country: {} {} - binary: {}\n'.format(str(countrycode), Func2.countryname(countrycode), bits_countrycode)) ################################ # BIT 91-137 VESSEL ID FIELD # ################################ while next_step == False: vesselID_list = [ '0: No aircraft or maritime identity', '1: Maritime MMSI', '2: Radio Call Sign', '3: Aircraft Registration Marking (Tail Number)', '4: Aircraft Aviation 24 Bit Address', '5: Aircraft Operator and Serial Number', '6: Spare', '7: Spare' ] #91-93 for i in vesselID_list: print i
def processHex(self, strhex): ##All second generation beacon messages must be EXACTLY 250 bits ##in length for the program to function properly. self.bits = Func.hex2bin(strhex) self.tablebin = [] self.rotatingbin = [] if len(self.bits) == 252 or len(self.bits) == 202 or len( self.bits) == 204 or len(self.bits) == 250: ##Add an additional bit to ensure that bits in array line up with bits in documentation self.bits = "0" + self.bits ##BIT 1-20 Type Approval Certificate # self.tac = Func.bin2dec(self.bits[1:21]) self.tablebin.append([ '1-20', self.bits[1:21], 'Type Approval Certificate #:', str(self.tac) ]) ##BIT 21-30 Serial Number self.serialNum = Func.bin2dec(self.bits[21:31]) self.tablebin.append([ '21-30', self.bits[21:31], 'Serial Number:', str(self.serialNum) ]) ##BIT 31-40 Country code self.countryCode = Func.bin2dec(self.bits[31:41]) self.countryName = Func.countryname(self.countryCode) self.tablebin.append([ '31-40', self.bits[31:41], 'Country code:', str(self.countryCode) + ' ' + str(self.countryName) ]) ##BIT 41 Status of homing device self.status = Func.homing(self.bits[41]) self.tablebin.append( ['41', self.bits[41], 'Status of homing device:', self.status]) ##BIT 42 Self-test function self.selfTestStatus = Func.selfTest(self.bits[42]) self.tablebin.append([ '42', self.bits[42], 'Self-test function:', self.selfTestStatus ]) ##BIT 43 User cancellation self.cancel = Func.cancellation(self.bits[43]) self.tablebin.append( ['43', self.bits[43], 'User cancellation:', self.cancel]) ##BIT 44-90 Encoded GNSS location self.latitude = Func.getlatitude(self.bits[44:67]) self.tablebin.append( ['44-66', self.bits[44:67], 'Latitude:', self.latitude[0]]) self.longitude = Func.getlongitude(self.bits[67:91]) self.tablebin.append( ['67-90', self.bits[67:91], 'Longitude:', self.longitude[0]]) self.location = (self.latitude[1], self.longitude[1]) ################################ # # # BIT 91-137 VESSEL ID FIELD # # # ################################ self.vesselIDfill(0, self.bits[91:138]) ##BIT 138-154 Spare bits [137-154] if Func.checkones(self.bits[138:155]): self.tablebin.append( ['138-154', self.bits[138:155], 'Spare:', 'OK']) else: self.tablebin.append([ '138-154', self.bits[138:155], 'Spare:', 'ERROR: Bits 138-154 should be 1s' ]) ####################################### # # # BIT 155-202 48 BIT ROTATING FIELD # # # ####################################### self.rotatingID = Func.bin2dec(self.bits[155:159]) ###################################################### # Rotating Field 0: C/S G.008 Objective Requirements # ###################################################### if self.rotatingID == 0: self.tablebin.append([ '155-158 (Rotating field 1-4)', self.bits[155:159], 'Rotating Field Type:', '(#0) C/S G.008 Objective Requirements' ]) self.rotatingbin = rotating.rotating0(self.bits[155:203]) ######################################## # Rotating Field 1: Inflight Emergency # ######################################## elif self.rotatingID == 1: self.tablebin.append([ '155-158 (Rotating field 1-4)', self.bits[155:159], 'Rotating Field Type:', '(#1) Inflight Emergency' ]) self.rotatingbin = rotating.rotating1(self.bits[155:203]) ######################### # Rotating Field 2: RLS # ######################### elif self.rotatingID == 2: self.tablebin.append([ '155-158 (Rotating field 1-4)', self.bits[155:159], 'Rotating Field Type:', '(#2) RLS' ]) self.rotatingbin = rotating.rotating2(self.bits[155:203]) ################################## # Rotating Field 3: National Use # ################################## elif self.rotatingID == 3: self.tablebin.append([ '155-158 (Rotating field 1-4)', self.bits[155:159], 'Rotating Field Type:', '(#3) National Use' ]) self.rotatingbin = rotating.rotating3(self.bits[155:203]) ########################################### # Rotating Field 15: Cancellation Message # ########################################### elif self.rotatingID == 15: self.tablebin.append([ '155-158 (Rotating field 1-4)', self.bits[155:159], 'Rotating Field Type:', '(#15) Cancellation Message' ]) self.rotatingbin = rotating.rotating15(self.bits[155:203]) ################################## # All other roating fields spare # ################################## else: self.tablebin.append([ '155-158 (Rotating field 1-4)', self.bits[155:159], 'Rotating Field Type:', 'Spare' ]) ##Add rotating field data to our list self.tablebin.extend(self.rotatingbin) #################### # BEACON 23 HEX ID # #################### self.hexID = [] ##Hex ID BIT 1 = fixed binary 1 self.hexID.append('1') ##Hex ID BIT 2-11 = BITS 31-40 (C/S Country Code) self.hexID.append(self.bits[31:41]) ##Hex ID BIT 12 = fixed binary 1 self.hexID.append('1') ##Hex ID BIT 13 = fixed binary 0 self.hexID.append('0') ##Hex ID BIT 14 = fixed binary 1 self.hexID.append('1') ##Hex ID BIT 15-34 = BITS 1-20 (C/S TAC No) self.hexID.append(self.bits[1:21]) ##Hex ID BIT 35-44 = BITS 21-30 (Beacon Serial Number) self.hexID.append(self.bits[21:31]) ##Hex ID BIT 45-47 = BITS 91-93 (Aircraft/Vessel ID Type) self.hexID.append(self.bits[91:94]) ##Hex ID BIT 48-91 = BITS 94-137 (Aircraft/Vessel ID) self.hexID.append(self.bits[94:138]) ##Hex ID BIT 92 = fixed binary 1 self.hexID.append('1') ##Join list together and convert to Hexadecimal self.beaconHexID = Func.bin2hex(''.join(self.hexID)) ##Add the 23 Hex ID to our table self.tablebin.append( ['', '', 'Beacon 23 Hex ID:', self.beaconHexID]) #################################### # 48-BIT BCH ERROR CORRECTING CODE # #################################### if len(self.bits) == 253: self.tablebin.append( ['203-204 (padding)', self.bits[203:205], '', '']) self.tablebin.append([ '205: (bch)', self.bits[205:], 'Encoded BCH', 'Encoded BCH' ]) ##Calculate the BCH self.calculatedBCH = Func.calcBCH(self.bits[1:], 0, 202, 250) self.tablebin.append( ['Calculated', self.calculatedBCH, 'Computed', '']) ##Compare to the BCH in the beacon message self.BCHerrors = Func.errors(self.calculatedBCH, self.bits[205:]) ##Write the number of errors to our table self.tablebin.append( ['', '', 'Number of BCH errors:', str(self.BCHerrors)]) elif len(self.bits) == 92: self.type = ( 'Hex string length of {}. \nBit length of {}. \nThis is a second generation beacon UIN' .format(str(len(strhex)), str(len(self.bits)))) ##Add an additional bit to ensure that bits in array line up with bits in documentation self.bits = "0" + self.bits self.tablebin.append(['Unique ID', 'Second Generation', '', '']) self.tablebin.append([ '1', self.bits[1], 'should be 1', ['ERROR', 'OK'][int(self.bits[1])] ]) ##BIT 2-11 Country code self.countryCode = Func.bin2dec(self.bits[2:12]) self.countryName = Func.countryname(self.countryCode) self.tablebin.append([ '2-11', self.bits[2:12], 'Country code:', str(self.countryCode) + ' ' + str(self.countryName) ]) ##BIT 12-14 Should be 101 if self.bits[12:15] == '101': status_check = 'OK' else: status_check = 'ERROR' self.tablebin.append( ['12-14', self.bits[12:15], 'Should be 101', status_check]) ##BIT 15-34 Type Approval Certificate # self.tac = Func.bin2dec(self.bits[15:35]) self.tablebin.append([ '15-34', self.bits[15:35], 'Type Approval Certificate #', str(self.tac) ]) ##BIT 35-44 Beacon Serial Number self.serialNum = Func.bin2dec(self.bits[35:45]) self.tablebin.append([ '35-44', self.bits[35:45], 'Serial Number', str(self.serialNum) ]) ##BIT 45-91 Aircraft / Vessel ID self.vesselIDfill(46, self.bits[45:92]) ##BIT 92 Fixed value 1 self.tablebin.append( ['92', self.bits[92], 'Fixed 1', self.bits[92] == '1']) else: self.type = ( 'Hex string length of ' + str(len(strhex)) + '.' + '\nBit string length of ' + str(len(self.bits)) + '.' + '\nLength of First Gen Beacon Hex String must be 15, 22 or 30' + '\nLength of Second Gen Beacon Bit String must be 250 bits') raise Gen2Error('LengthError', self.type)