def decodeAX25(bits): ax = ax25.AX25() ax.info = "bad packet" bitsu = ax25.bit_unstuff(bits[8:-8]) if (genfcs(bitsu[:-16]).tobytes() == bitsu[-16:].tobytes()) == False: #print("failed fcs") return ax bytes = bitsu.tobytes() ax.destination = ax.callsign_decode(bitsu[:56]) source = ax.callsign_decode(bitsu[56:112]) if source[-1].isdigit() and source[-1]!="0": ax.source = b"".join((source[:-1],'-',source[-1])) else: ax.source = source[:-1] digilen=0 if bytes[14]=='\x03' and bytes[15]=='\xf0': digilen = 0 else: for n in range(14,len(bytes)-1): if ord(bytes[n]) & 1: digilen = (n-14)+1 break # if digilen > 56: # return ax ax.digipeaters = ax.callsign_decode(bitsu[112:112+digilen*8]) ax.info = bitsu[112+digilen*8+16:-16].tobytes() return ax
def detectFrames(NRZI): # function looks for packets in an NRZI sequence and validates their checksum # compute finite differences of the digital NRZI to detect zero-crossings dNRZI = NRZI[1:] - NRZI[:-1] # find the position of the non-zero components. These are the indexes of the zero-crossings. transit = np.nonzero(dNRZI)[0] # Transition time is the difference between zero-crossings transTime = transit[1:]-transit[:-1] # loop over transitions, convert to bit streams and extract packets dict = { 1:bitarray.bitarray([0]), 2:bitarray.bitarray([1,0]), 3:bitarray.bitarray([1,1,0]), 4:bitarray.bitarray([1,1,1,0]),5:bitarray.bitarray([1,1,1,1,0]),6:bitarray.bitarray([1,1,1,1,1,0]) ,7:bitarray.bitarray([1,1,1,1,1,1,0])} state = 0; # no flag detected yet packets =[] tmppkt = bitarray.bitarray([0]) lastFlag = 0 # position of the last flag found. for n in range(0,len(transTime)): Nb = round(transTime[n]/36.75) # maps intervals to bits. Assume 44100Hz and 1200baud if (Nb == 7 and state ==0): # detected flag frame, start collecting a packet tmppkt = tmppkt + dict[7] state = 1 # packet detected lastFlag = transit[n-1] continue if (Nb == 7 and state == 1): # detected end frame successfully tmppkt = tmppkt + dict[7] # validate checksum bitsu = ax25.bit_unstuff(tmppkt[8:-8]) # unstuff bits if (genfcs(bitsu[:-16]).tobytes() == bitsu[-16:].tobytes()) : # valid packet packets.append(tmppkt) tmppkt = bitarray.bitarray([0]) state = 0 continue if (state == 1 and Nb < 7 and Nb > 0): # valid bits tmppkt = tmppkt + dict[Nb] continue else: # not valid bits reset state = 0 tmppkt = bitarray.bitarray([0]) continue if state == 0: lastFlag = -1 # if the state is 1, which means that we detected a packet, but the buffer ended, then # we return the position of the beginning of the flag within the buffer to let the caller # know that there's a packet that overlapps between two buffer frames. return packets, lastFlag
def decodeAX25(self,bits, deepsearch=False): ax = ax25.AX25() ax.info = "bad packet" bitsu = ax25.bit_unstuff(bits[8:-8]) foundPacket = False if (self.genfcs(bitsu[:-16]).tobytes() == bitsu[-16:].tobytes()): foundPacket = True elif deepsearch: tbits = bits[8:-8] for n in range(0,len(tbits)): tbits[n] = not tbits[n] if (self.genfcs(bitsu[:-16]).tobytes() == bitsu[-16:].tobytes()): foundPacket = True print("Success deep search") break tbits[n] = not tbits[n] if foundPacket == False: return ax bytes = bitsu.tobytes() ax.destination = ax.callsign_decode(bitsu[:56]) source = ax.callsign_decode(bitsu[56:112]) if source[-1].isdigit() and source[-1]!="0": ax.source = b"".join((source[:-1],'-',source[-1])) else: ax.source = source[:-1] digilen=0 if bytes[14]=='\x03' and bytes[15]=='\xf0': digilen = 0 else: for n in range(14,len(bytes)-1): if ord(bytes[n]) & 1: digilen = (n-14)+1 break # if digilen > 56: # return ax ax.digipeaters = ax.callsign_decode(bitsu[112:112+digilen*8]) ax.info = bitsu[112+digilen*8+16:-16].tobytes() return ax
def decodeAX25(self, bits, deepsearch=False): ax = ax25.AX25() ax.info = "bad packet" bitsu = ax25.bit_unstuff(bits[8:-8]) foundPacket = False if (self.genfcs(bitsu[:-16]).tobytes() == bitsu[-16:].tobytes()): foundPacket = True elif deepsearch: tbits = bits[8:-8] for n in range(0, len(tbits)): tbits[n] = not tbits[n] if (self.genfcs( bitsu[:-16]).tobytes() == bitsu[-16:].tobytes()): foundPacket = True print("Success deep search") break tbits[n] = not tbits[n] if foundPacket == False: return ax bytes = bitsu.tobytes() ax.destination = ax.callsign_decode(bitsu[:56]) source = ax.callsign_decode(bitsu[56:112]) source = str(source) if source[-1].isdigit() and source[-1] != "0": ax.source = b"".join((source[:-1], '-', source[-1])) else: ax.source = source[:-1] digilen = 0 if bytes[14] == '\x03' and bytes[15] == '\xf0': digilen = 0 else: for n in range(14, len(bytes) - 1): if bytes[n] & 1: digilen = (n - 14) + 1 break utils.print_msg("Digilen = " + str(digilen), DEBUG) # if digilen > 56: # return ax ax.digipeaters = ax.callsign_decode(bitsu[112:112 + digilen * 8]) ax.info = bitsu[112 + digilen * 8 + 16:-16].tobytes() return ax
def findPackets(bits, rs=reedsolo.RSCodec(NUM_ERRORS*2)): if len(bits) == 0: return [] flag = "01111110" bitstream = iter(bits) b = bitstream.next() packets = [] while True: try: if b == 0: for _ in range(6): b = bitstream.next() if b != 1: break else: b = bitstream.next() if b == 0: # Flag found begin collecting data data = bitarray.bitarray() done = False while not done: for _ in range(8): data.append(bitstream.next()) while data[-8:].to01() != flag: data.append(bitstream.next()) if data[:8].to01() == flag: data = data[8:] if len(data[:-8]) > 16: done = True data = data[:-8] data = ax25.bit_unstuff(data) try: # print "received", data data = bitarray.bitarray(np.unpackbits(rs.decode(bytearray(bitarray.bitarray(data.to01()).tobytes()))).tolist()) # print "decoded ", data if len(data) > 8 and checksum(data[:-8]) == data[-8:]: packets.append(data[:-8]) except: pass # print "error" # print data else: b = bitstream.next() except StopIteration: break return packets
def checkPacket(bitstream, leftFlag, rightFlag, rs=reedsolo.RSCodec(NUM_ERRORS*2)): # print leftFlag, rightFlag, bitstream[:16].to01(), bitstream[-16:].to01() if leftFlag <= 0 or rightFlag <= 0: # print "out of flag" return None try: p = bitstream.copy() p = ax25.bit_unstuff(p[8:-8]) p = bitarray.bitarray(np.unpackbits(rs.decode(bytearray(bitarray.bitarray(p.to01()).tobytes()))).tolist()) # print "decoded" return p except: # print "decoding failed" p = bitstream.copy() p = checkPacket(p[8:], leftFlag - 1, rightFlag) if p: # print "gone left" return p p = checkPacket(p[:-8], leftFlag, rightFlag - 1) if p: # print "gone right" return p # print "recursion failed" return None