def __init__(self,imsg): self.__dict__=imsg.__dict__ if self.msgtype == "MS": self.poly=messaging_bch_poly elif self.msgtype == "RA": self.poly=ringalert_bch_poly elif self.msgtype == "BC": self.poly=ringalert_bch_poly elif self.msgtype == "DA": self.poly=acch_bch_poly else: raise ParserError("unknown Iridium message type(canthappen)") self.bitstream_messaging="" self.bitstream_bch="" self.oddbits="" self.fixederrs=0 for block in self.descrambled: if len(block)!=32 and len(block)!=31: raise ParserError("unknown BCH block len:%d"%len(block)) if len(block)==32: bits=block[:31] else: bits=block (errs,data,bch)=bch_repair(self.poly, bits) if errs>0: self.fixederrs+=1 if(errs<0): if len(self.bitstream_bch) == 0: self._new_error("BCH decode failed") break parity=(data+bch).count('1') % 2 if len(block)==32: parity=(int(block[31])+parity)%2 #if parity==1: raise ParserError("Parity error") self.bitstream_bch+=data self.bitstream_messaging+=data[1:] self.oddbits+=data[0] if len(self.bitstream_bch)==0: self._new_error("No data to descramble")
def __init__(self, imsg): self.__dict__ = copy.deepcopy(imsg.__dict__) if self.msgtype == "MS": self.poly = messaging_bch_poly elif self.msgtype == "RA": self.poly = ringalert_bch_poly elif self.msgtype == "BC": self.poly = ringalert_bch_poly elif self.msgtype == "DA": self.poly = acch_bch_poly else: raise ParserError("unknown Iridium message type(canthappen)") self.bitstream_messaging = "" self.bitstream_bch = "" self.oddbits = "" self.fixederrs = 0 for block in self.descrambled: if len(block) != 32 and len(block) != 31: raise ParserError("unknown BCH block len:%d" % len(block)) if len(block) == 32: bits = block[:31] else: bits = block (errs, data, bch) = bch_repair(self.poly, bits) if errs > 0: self.fixederrs += 1 if (errs < 0): self._new_error("BCH decode failed") parity = (data + bch).count('1') % 2 if len(block) == 32: parity = (int(block[31]) + parity) % 2 #if parity==1: raise ParserError("Parity error") self.bitstream_bch += data self.bitstream_messaging += data[1:] self.oddbits += data[0] if len(self.bitstream_bch) == 0: self._new_error("No data to descramble")
def __init__(self, msg): self.__dict__ = copy.deepcopy(msg.__dict__) data = self.bitstream_raw[len(iridium_access):] # Try to detect packet type if data[:32] == header_messaging: self.msgtype = "MS" elif 1626229167 < self.frequency < 1626312500: self.msgtype = "RA" elif len( data ) > 64: # XXX: heuristic based on LCW / first BCH block, can we do better? (o_lcw1, o_lcw2, o_lcw3) = de_interleave_lcw(data[:46]) (e1, lcw1, bch) = bch_repair(29, o_lcw1) (e2, lcw2, bch) = bch_repair(465, o_lcw2 + '0') # One bit missing, so we guess if (e2 == 1): # Maybe the other one... (e2, lcw2, bch) = bch_repair(465, o_lcw2 + '1') (e3, lcw3, bch) = bch_repair(41, o_lcw3) # if e1>=0 and e2>=0 and e3>=0: # Valid LCW if e1 == 0 and e2 == 0 and e3 == 0: # GOOD LCW self.msgtype = "DA" elif len(data) > 6 + 64 and ndivide( ringalert_bch_poly, de_interleave(data[6:6 + 64])[0][:31]) == 0: self.msgtype = "BC" else: raise ParserError("unknown Iridium message type") else: raise ParserError("Iridium message too short") if self.msgtype == "MS": hdrlen = 32 self.header = data[:hdrlen] self.descrambled = [] (blocks, self.descramble_extra) = slice_extra(data[hdrlen:], 64) for x in blocks: self.descrambled += de_interleave(x) elif self.msgtype == "RA": firstlen = 3 * 32 if len(data) < firstlen: self._new_error("No data to descramble") self.header = "" self.descrambled = de_interleave3(data[:firstlen]) (blocks, self.descramble_extra) = slice_extra(data[firstlen:], 64) for x in blocks: self.descrambled += de_interleave(x) elif self.msgtype == "BC": hdrlen = 6 self.header = data[:hdrlen] self.descrambled = [] (blocks, self.descramble_extra) = slice_extra(data[hdrlen:], 64) for x in blocks: self.descrambled += de_interleave(x) elif self.msgtype == "DA": lcwlen = 46 (o_lcw1, o_lcw2, o_lcw3) = de_interleave_lcw(data[:lcwlen]) (e1, self.lcw1, bch) = bch_repair(29, o_lcw1) (e2, self.lcw2, bch) = bch_repair(465, o_lcw2 + '0') # One bit error expected if e2 == 1: (e2, self.lcw2, bch) = bch_repair(465, o_lcw2 + '1') # Other bit flip? (e3, self.lcw3, bch) = bch_repair(41, o_lcw3) self.ft = int(self.lcw1, 2) # Frame type if e1 < 0 or e2 < 0 or e3 < 0: self._new_error("LCW decode failed") self.header = "LCW(%s %s/%02d E%d,%s %sx/%03d E%d,%s %s/%02d E%d)" % ( o_ft[:3], o_ft[3:], ndivide(29, o_ft), e1, o_lcw2[:6], o_lcw2[6:], ndivide(465, o_lcw2 + '0'), e2, o_lcw3[:21], o_lcw3[21:], ndivide(41, o_lcw3), e3) else: self.header = "LCW(%d,%s,%s E%d)" % (self.ft, self.lcw2, self.lcw3, e1 + e2 + e3) self.descrambled = [] data = data[lcwlen:] def symbol_reverse(bits): r = '' for symbol in grouped(bits, 2): r += symbol[1] + symbol[0] return r if self.ft <= 2 and len(data) < 312: self._new_error("Not enough data in data packet") if self.ft == 0: # Voice self.msgtype = "VO" self.voice = data[:312] self.descramble_extra = data[312:] elif self.ft == 1: # IP via PPP self.msgtype = "IP" for x in slice(symbol_reverse(data[:312]), 8): self.descrambled += [x[::-1]] self.descramble_extra = data[312:] elif self.ft == 2: # DAta (SBD) self.descramble_extra = data[124 * 2 + 64:] data = data[:124 * 2 + 64] blocks = slice(data, 124) end = blocks.pop() for x in blocks: (b1, b2) = de_interleave(x) (b1, b2, b3, b4) = slice(b1 + b2, 31) self.descrambled += [b4, b2, b3, b1] (b1, b2) = de_interleave(end) self.descrambled += [b2[1:], b1[1:]] # Throw away the extra bit else: # Need to check what other ft are self.msgtype = "UK" self.descrambled = slice(data, 64) self.descramble_extra = "" self.lead_out_ok = self.descramble_extra.startswith(iridium_lead_out) if self.msgtype != "VO" and self.msgtype != "IP" and len( self.descrambled) == 0: self._new_error("No data to descramble")
def __init__(self,msg): self.__dict__=copy.deepcopy(msg.__dict__) data=self.bitstream_raw[len(iridium_access):] # Try to detect packet type if data[:32] == header_messaging: self.msgtype="MS" elif 1626229167<self.frequency<1626312500: self.msgtype="RA" elif len(data)>64: # XXX: heuristic based on LCW / first BCH block, can we do better? (lcw1,lcw2,lcw3)=de_interleave_lcw(data[:46]) (e1,lcw1,bch)= bch_repair( 29,lcw1) (e2,lcw2,bch)= bch_repair(465,lcw2+'0') # One bit error expected (e3,lcw3,bch)= bch_repair( 41,lcw3) # if e1>=0 and e2>=0 and e3>=0: # Valid LCW if e1==0 and 0<=e2<=1 and e3==0: # GOOD LCW self.msgtype="DA" elif len(data)>6+64 and ndivide(ringalert_bch_poly,de_interleave(data[6:6+64])[0][:31])==0: self.msgtype="BC" else: raise ParserError("unknown Iridium message type") else: raise ParserError("Iridium message too short") if self.msgtype=="MS": hdrlen=32 self.header=data[:hdrlen] self.descrambled=[] (blocks,self.descramble_extra)=slice_extra(data[hdrlen:],64) for x in blocks: self.descrambled+=de_interleave(x) elif self.msgtype=="RA": firstlen=3*32 if len(data)<firstlen: self._new_error("No data to descramble") self.header="" self.descrambled=de_interleave3(data[:firstlen]) (blocks,self.descramble_extra)=slice_extra(data[firstlen:],64) for x in blocks: self.descrambled+=de_interleave(x) elif self.msgtype=="BC": hdrlen=6 self.header=data[:hdrlen] self.descrambled=[] (blocks,self.descramble_extra)=slice_extra(data[hdrlen:],64) for x in blocks: self.descrambled+=de_interleave(x) elif self.msgtype=="DA": lcwlen=46 (o_lcw1,o_lcw2,o_lcw3)=de_interleave_lcw(data[:lcwlen]) (e1,self.lcw1,bch)= bch_repair( 29,o_lcw1) (e2,self.lcw2,bch)= bch_repair(465,o_lcw2+'0') # One bit error expected (e3,self.lcw3,bch)= bch_repair( 41,o_lcw3) self.ft=int(self.lcw1,2) # Frame type if e1<0 or e2<0 or e3<0: self._new_error("LCW decode failed") self.header="LCW(%s %s/%02d E%d,%s %sx/%03d E%d,%s %s/%02d E%d)"%(o_ft[:3],o_ft[3:],ndivide(29,o_ft),e1,o_lcw2[:6],o_lcw2[6:],ndivide(465,o_lcw2+'0'),e2,o_lcw3[:21],o_lcw3[21:],ndivide(41,o_lcw3),e3) else: self.header="LCW(%d,%s,%s E%d)"%(self.ft,self.lcw2,self.lcw3,e1+e2+e3) self.descrambled=[] data=data[lcwlen:] if self.ft==0: # Voice self.msgtype="VO" self.voice=data[:312] self.descramble_extra=data[312:] elif self.ft==2: if len(data)<124*2+64: self._new_error("Not enough data in DA packet") self.descramble_extra=data[124*2+64:] data=data[:124*2+64] blocks=slice(data,124) end=blocks.pop() for x in blocks: for i in de_interleave(x): # Not clear what block order is correct self.descrambled+=[i[:31],i[31:62]] self.descrambled+=de_interleave(end) else: # Need to check what ft=1 is self.descrambled=blocks=slice(data,64) self.descramble_extra="" self._new_error("Unknown frame_type") self.lead_out_ok= self.descramble_extra.startswith(iridium_lead_out) if self.msgtype!="VO" and len(self.descrambled)==0: self._new_error("No data to descramble")
def __init__(self, msg): self.__dict__ = copy.deepcopy(msg.__dict__) data = self.bitstream_raw[len(iridium_access):] # Try to detect packet type if data[:32] == header_messaging: self.msgtype = "MS" elif 1626229167 < self.frequency < 1626312500: self.msgtype = "RA" elif len( data ) > 64: # XXX: heuristic based on LCW / first BCH block, can we do better? (lcw1, lcw2, lcw3) = de_interleave_lcw(data[:46]) (e1, lcw1, bch) = bch_repair(29, lcw1) (e2, lcw2, bch) = bch_repair(465, lcw2 + '0') # One bit error expected (e3, lcw3, bch) = bch_repair(41, lcw3) # if e1>=0 and e2>=0 and e3>=0: # Valid LCW if e1 == 0 and 0 <= e2 <= 1 and e3 == 0: # GOOD LCW self.msgtype = "DA" elif len(data) > 6 + 64 and ndivide( ringalert_bch_poly, de_interleave(data[6:6 + 64])[0][:31]) == 0: self.msgtype = "BC" else: raise ParserError("unknown Iridium message type") else: raise ParserError("Iridium message too short") if self.msgtype == "MS": hdrlen = 32 self.header = data[:hdrlen] self.descrambled = [] (blocks, self.descramble_extra) = slice_extra(data[hdrlen:], 64) for x in blocks: self.descrambled += de_interleave(x) elif self.msgtype == "RA": firstlen = 3 * 32 if len(data) < firstlen: self._new_error("No data to descramble") self.header = "" self.descrambled = de_interleave3(data[:firstlen]) (blocks, self.descramble_extra) = slice_extra(data[firstlen:], 64) for x in blocks: self.descrambled += de_interleave(x) elif self.msgtype == "BC": hdrlen = 6 self.header = data[:hdrlen] self.descrambled = [] (blocks, self.descramble_extra) = slice_extra(data[hdrlen:], 64) for x in blocks: self.descrambled += de_interleave(x) elif self.msgtype == "DA": lcwlen = 46 (o_lcw1, o_lcw2, o_lcw3) = de_interleave_lcw(data[:lcwlen]) (e1, self.lcw1, bch) = bch_repair(29, o_lcw1) (e2, self.lcw2, bch) = bch_repair(465, o_lcw2 + '0') # One bit error expected (e3, self.lcw3, bch) = bch_repair(41, o_lcw3) self.ft = int(self.lcw1, 2) # Frame type if e1 < 0 or e2 < 0 or e3 < 0: self._new_error("LCW decode failed") self.header = "LCW(%s %s/%02d E%d,%s %sx/%03d E%d,%s %s/%02d E%d)" % ( o_ft[:3], o_ft[3:], ndivide(29, o_ft), e1, o_lcw2[:6], o_lcw2[6:], ndivide(465, o_lcw2 + '0'), e2, o_lcw3[:21], o_lcw3[21:], ndivide(41, o_lcw3), e3) else: self.header = "LCW(%d,%s,%s E%d)" % (self.ft, self.lcw2, self.lcw3, e1 + e2 + e3) self.descrambled = [] data = data[lcwlen:] if self.ft == 0: # Voice self.msgtype = "VO" self.voice = data[:312] self.descramble_extra = data[312:] elif self.ft == 2: if len(data) < 124 * 2 + 64: self._new_error("Not enough data in DA packet") self.descramble_extra = data[124 * 2 + 64:] data = data[:124 * 2 + 64] blocks = slice(data, 124) end = blocks.pop() for x in blocks: for i in de_interleave( x): # Not clear what block order is correct self.descrambled += [i[:31], i[31:62]] self.descrambled += de_interleave(end) else: # Need to check what ft=1 is self.descrambled = blocks = slice(data, 64) self.descramble_extra = "" self._new_error("Unknown frame_type") self.lead_out_ok = self.descramble_extra.startswith(iridium_lead_out) if self.msgtype != "VO" and len(self.descrambled) == 0: self._new_error("No data to descramble")
def __init__(self,msg): self.__dict__=msg.__dict__ if (self.uplink): data=self.bitstream_raw[len(uplink_access):] else: data=self.bitstream_raw[len(iridium_access):] # Try to detect packet type. # XXX: will not detect packets with correctable bit errors at the beginning if "msgtype" not in self.__dict__: if data[:32] == header_messaging: self.msgtype="MS" if "msgtype" not in self.__dict__: hdrlen=6 blocklen=64 if len(data)>hdrlen+blocklen: (o_bc1,o_bc2)=de_interleave(data[hdrlen:hdrlen+blocklen]) if ndivide(ringalert_bch_poly,o_bc1[:31])==0: if ndivide(ringalert_bch_poly,o_bc2[:31])==0: self.msgtype="BC" if "msgtype" not in self.__dict__: if len(data)>64: # XXX: heuristic based on LCW / first BCH block, can we do better? (o_lcw1,o_lcw2,o_lcw3)=de_interleave_lcw(data[:46]) if ndivide( 29,o_lcw1)==0: if ndivide( 41,o_lcw3)==0: (e2,lcw2,bch)= bch_repair(465,o_lcw2+'0') # One bit missing, so we guess if (e2==1): # Maybe the other one... (e2,lcw2,bch)= bch_repair(465,o_lcw2+'1') if e2==0: self.msgtype="DA" if "msgtype" not in self.__dict__: firstlen=3*32 if len(data)>=3*32: (o_ra1,o_ra2,o_ra3)=de_interleave3(data[:firstlen]) if ndivide(ringalert_bch_poly,o_ra1[:31])==0: if ndivide(ringalert_bch_poly,o_ra2[:31])==0: if ndivide(ringalert_bch_poly,o_ra3[:31])==0: self.msgtype="RA" if "msgtype" not in self.__dict__: if len(data)<64: raise ParserError("Iridium message too short") else: raise ParserError("unknown Iridium message type") if self.msgtype=="MS": hdrlen=32 self.header=data[:hdrlen] self.descrambled=[] (blocks,self.descramble_extra)=slice_extra(data[hdrlen:],64) for x in blocks: self.descrambled+=de_interleave(x) elif self.msgtype=="RA": firstlen=3*32 if len(data)<firstlen: self._new_error("No data to descramble") self.header="" self.descrambled=de_interleave3(data[:firstlen]) (blocks,self.descramble_extra)=slice_extra(data[firstlen:],64) for x in blocks: self.descrambled+=de_interleave(x) elif self.msgtype=="BC": hdrlen=6 self.header=data[:hdrlen] self.descrambled=[] (blocks,self.descramble_extra)=slice_extra(data[hdrlen:],64) for x in blocks: self.descrambled+=de_interleave(x) elif self.msgtype=="DA": lcwlen=46 (o_lcw1,o_lcw2,o_lcw3)=de_interleave_lcw(data[:lcwlen]) (e1,self.lcw1,bch)= bch_repair( 29,o_lcw1) (e2,self.lcw2,bch)= bch_repair(465,o_lcw2+'0') # One bit error expected if e2==1: (e2,self.lcw2,bch)= bch_repair(465,o_lcw2+'1') # Other bit flip? (e3,self.lcw3,bch)= bch_repair( 41,o_lcw3) self.ft=int(self.lcw1,2) # Frame type if e1<0 or e2<0 or e3<0: # LCW:=xx[type] yyyy[code] # 0: maint # 6: geoloc # f: "no text" # c: maint [lqi[x1c,2], power[[x19,3]] # 789abde: reserved # 0: sync [status[xa,1], dtoa[xc,10], dfoa[x16,8]] # 3: maint [lqi[xa,2], power[xc,3], fine dtoa[xf,7], fine dfoa[x16,3]] # 245: reserved # 1: switch [dtoa[xc,10], dfoa[x16,8]] # 1: acchl # 1: acchl # *: reserved # 2: handoff # c: handoff cand. # f: "no text" # 3: handoff resp. [cand[%c[0=P,1=S::0xb,1]], denied[0xc,1], ref[xd,1], slot[xf,2]+1, subband up[x11,5], subband down[x16,5], access[x1b,3]+1] # *: reserved # 3: reserved self._new_error("LCW decode failed") self.header="LCW(%s %s/%02d E%d,%s %sx/%03d E%d,%s %s/%02d E%d)"%(o_ft[:3],o_ft[3:],ndivide(29,o_ft),e1,o_lcw2[:6],o_lcw2[6:],ndivide(465,o_lcw2+'0'),e2,o_lcw3[:21],o_lcw3[21:],ndivide(41,o_lcw3),e3) else: # self.header="LCW(%d,%s,%s E%d)"%(self.ft,self.lcw2,self.lcw3,e1+e2+e3) self.lcw_ft=int(self.lcw2[:2],2) self.lcw_code=int(self.lcw2[2:],2) if self.lcw_ft == 0: ty="maint" if self.lcw_code == 6: code="geoloc" elif self.lcw_code == 15: code="<silent>" elif self.lcw_code == 12: code="maint[1]" code+="[lqi:%d,power:%d]"%(int(self.lcw3[19:21],2),int(self.lcw3[16:19],2)) elif self.lcw_code == 0: code="sync" code+="[status:%d,dtoa:%d,dfoa:%d]"%(int(self.lcw3[1:2],2),int(self.lcw3[3:13],2),int(self.lcw3[13:21],2)) elif self.lcw_code == 3: code="maint[2]" code+="[lqi:%d,power:%d,f_dtoa:%d,f_dfoa:%d]"%(int(self.lcw3[1:3],2),int(self.lcw3[3:6],2),int(self.lcw3[6:13],2),int(self.lcw3[13:20],2)) elif self.lcw_code == 1: code="switch" code+="[dtoa:%d,dfoa:%d]"%(int(self.lcw3[3:13],2),int(self.lcw3[13:21],2)) else: code="rsrvd" elif self.lcw_ft == 1: ty="acchl" if self.lcw_code == 1: code="acchl" else: code="rsrvd" elif self.lcw_ft == 2: ty="hndof" if self.lcw_code == 12: code="handoff_cand" elif self.lcw_code == 3: code="handoff_resp" code+="[cand:%d,denied:%d,ref:%d,slot:%d,sband_up:%d,sband_dn:%d,access:%d]"%(int(self.lcw3[2:3],2),int(self.lcw3[3:4],2),int(self.lcw3[4:5],2),1+int(self.lcw3[6:8],2),int(self.lcw3[8:13],2),int(self.lcw3[13:18],2),1+int(self.lcw3[18:21],2)) elif self.lcw_code == 15: code="<silent>" else: code="rsrvd" elif self.lcw_ft == 3: ty="rsrvd" code="<>" self.header="LCW(%d,T:%s,C:%s(%s),%s E%d)"%(self.ft,ty,code,int(self.lcw2,2),int(self.lcw3,2),e1+e2+e3) self.header="%-110s "%self.header self.descrambled=[] data=data[lcwlen:] def symbol_reverse(bits): r = '' for symbol in grouped(bits, 2): r += symbol[1] + symbol[0] return r if self.ft<=2 and len(data)<312: self._new_error("Not enough data in data packet") if self.ft==0: # Voice self.msgtype="VO" self.voice=data[:312] self.descramble_extra=data[312:] elif self.ft==1: # IP via PPP self.msgtype="IP" for x in slice(symbol_reverse(data[:312]),8): self.descrambled+=[x[::-1]] self.descramble_extra=data[312:] elif self.ft==2: # DAta (SBD) self.descramble_extra=data[124*2+64:] data=data[:124*2+64] blocks=slice(data,124) end=blocks.pop() for x in blocks: (b1,b2)=de_interleave(x) (b1,b2,b3,b4)=slice(b1+b2,31) self.descrambled+=[b4,b2,b3,b1] (b1,b2)=de_interleave(end) self.descrambled+=[b2[1:],b1[1:]] # Throw away the extra bit elif self.ft==7: # Synchronisation self.msgtype="SY" self.descrambled=data[:312] self.sync=[int(x,2) for x in slice(self.descrambled, 8)] self.descramble_extra=data[312:] else: # Need to check what other ft are self.msgtype="UK" self.descrambled=symbol_reverse(data[:312]) self.descramble_extra=data[312:] self.lead_out_ok= self.descramble_extra.startswith(iridium_lead_out) if self.msgtype!="VO" and self.msgtype!="IP" and len(self.descrambled)==0: self._new_error("No data to descramble")
def __init__(self,msg): self.__dict__=copy.deepcopy(msg.__dict__) data=self.bitstream_raw[len(iridium_access):] # Try to detect packet type if data[:32] == header_messaging: self.msgtype="MS" elif 1626229167<self.frequency<1626312500: self.msgtype="RA" elif len(data)>64: # XXX: heuristic based on LCW / first BCH block, can we do better? (o_lcw1,o_lcw2,o_lcw3)=de_interleave_lcw(data[:46]) (e1,lcw1,bch)= bch_repair( 29,o_lcw1) (e2,lcw2,bch)= bch_repair(465,o_lcw2+'0') # One bit missing, so we guess if (e2==1): # Maybe the other one... (e2,lcw2,bch)= bch_repair(465,o_lcw2+'1') (e3,lcw3,bch)= bch_repair( 41,o_lcw3) # if e1>=0 and e2>=0 and e3>=0: # Valid LCW if e1==0 and e2==0 and e3==0: # GOOD LCW self.msgtype="DA" elif len(data)>6+64 and ndivide(ringalert_bch_poly,de_interleave(data[6:6+64])[0][:31])==0: self.msgtype="BC" else: raise ParserError("unknown Iridium message type") else: raise ParserError("Iridium message too short") if self.msgtype=="MS": hdrlen=32 self.header=data[:hdrlen] self.descrambled=[] (blocks,self.descramble_extra)=slice_extra(data[hdrlen:],64) for x in blocks: self.descrambled+=de_interleave(x) elif self.msgtype=="RA": firstlen=3*32 if len(data)<firstlen: self._new_error("No data to descramble") self.header="" self.descrambled=de_interleave3(data[:firstlen]) (blocks,self.descramble_extra)=slice_extra(data[firstlen:],64) for x in blocks: self.descrambled+=de_interleave(x) elif self.msgtype=="BC": hdrlen=6 self.header=data[:hdrlen] self.descrambled=[] (blocks,self.descramble_extra)=slice_extra(data[hdrlen:],64) for x in blocks: self.descrambled+=de_interleave(x) elif self.msgtype=="DA": lcwlen=46 (o_lcw1,o_lcw2,o_lcw3)=de_interleave_lcw(data[:lcwlen]) (e1,self.lcw1,bch)= bch_repair( 29,o_lcw1) (e2,self.lcw2,bch)= bch_repair(465,o_lcw2+'0') # One bit error expected if e2==1: (e2,self.lcw2,bch)= bch_repair(465,o_lcw2+'1') # Other bit flip? (e3,self.lcw3,bch)= bch_repair( 41,o_lcw3) self.ft=int(self.lcw1,2) # Frame type if e1<0 or e2<0 or e3<0: self._new_error("LCW decode failed") self.header="LCW(%s %s/%02d E%d,%s %sx/%03d E%d,%s %s/%02d E%d)"%(o_ft[:3],o_ft[3:],ndivide(29,o_ft),e1,o_lcw2[:6],o_lcw2[6:],ndivide(465,o_lcw2+'0'),e2,o_lcw3[:21],o_lcw3[21:],ndivide(41,o_lcw3),e3) else: self.header="LCW(%d,%s,%s E%d)"%(self.ft,self.lcw2,self.lcw3,e1+e2+e3) self.descrambled=[] data=data[lcwlen:] def symbol_reverse(bits): r = '' for symbol in grouped(bits, 2): r += symbol[1] + symbol[0] return r if self.ft<=2 and len(data)<312: self._new_error("Not enough data in data packet") if self.ft==0: # Voice self.msgtype="VO" self.voice=data[:312] self.descramble_extra=data[312:] elif self.ft==1: # IP via PPP self.msgtype="IP" for x in slice(symbol_reverse(data[:312]),8): self.descrambled+=[x[::-1]] self.descramble_extra=data[312:] elif self.ft==2: # DAta (SBD) self.descramble_extra=data[124*2+64:] data=data[:124*2+64] blocks=slice(data,124) end=blocks.pop() for x in blocks: (b1,b2)=de_interleave(x) (b1,b2,b3,b4)=slice(b1+b2,31) self.descrambled+=[b4,b2,b3,b1] (b1,b2)=de_interleave(end) self.descrambled+=[b2[1:],b1[1:]] # Throw away the extra bit else: # Need to check what other ft are self.msgtype="UK" self.descrambled=slice(data,64) self.descramble_extra="" self.lead_out_ok= self.descramble_extra.startswith(iridium_lead_out) if self.msgtype!="VO" and self.msgtype!="IP" and len(self.descrambled)==0: self._new_error("No data to descramble")