📄 packet_utils.py
字号:
## Copyright 2005,2006,2007 Free Software Foundation, Inc.# # This file is part of GNU Radio# # GNU Radio is free software; you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation; either version 3, or (at your option)# any later version.# # GNU Radio is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU General Public License for more details.# # You should have received a copy of the GNU General Public License# along with GNU Radio; see the file COPYING. If not, write to# the Free Software Foundation, Inc., 51 Franklin Street,# Boston, MA 02110-1301, USA.# import structimport numpyfrom gnuradio import grudef conv_packed_binary_string_to_1_0_string(s): """ '\xAF' --> '10101111' """ r = [] for ch in s: x = ord(ch) for i in range(7,-1,-1): t = (x >> i) & 0x1 r.append(t) return ''.join(map(lambda x: chr(x + ord('0')), r))def conv_1_0_string_to_packed_binary_string(s): """ '10101111' -> ('\xAF', False) Basically the inverse of conv_packed_binary_string_to_1_0_string, but also returns a flag indicating if we had to pad with leading zeros to get to a multiple of 8. """ if not is_1_0_string(s): raise ValueError, "Input must be a string containing only 0's and 1's" # pad to multiple of 8 padded = False rem = len(s) % 8 if rem != 0: npad = 8 - rem s = '0' * npad + s padded = True assert len(s) % 8 == 0 r = [] i = 0 while i < len(s): t = 0 for j in range(8): t = (t << 1) | (ord(s[i + j]) - ord('0')) r.append(chr(t)) i += 8 return (''.join(r), padded) default_access_code = \ conv_packed_binary_string_to_1_0_string('\xAC\xDD\xA4\xE2\xF2\x8C\x20\xFC')preamble = \ conv_packed_binary_string_to_1_0_string('\xA4\xF2')def is_1_0_string(s): if not isinstance(s, str): return False for ch in s: if not ch in ('0', '1'): return False return Truedef string_to_hex_list(s): return map(lambda x: hex(ord(x)), s)def whiten(s, o): sa = numpy.fromstring(s, numpy.uint8) z = sa ^ random_mask_vec8[o:len(sa)+o] return z.tostring()def dewhiten(s, o): return whiten(s, o) # self inversedef make_header(payload_len, whitener_offset=0): # Upper nibble is offset, lower 12 bits is len val = ((whitener_offset & 0xf) << 12) | (payload_len & 0x0fff) #print "offset =", whitener_offset, " len =", payload_len, " val=", val return struct.pack('!HH', val, val)def make_packet(payload, samples_per_symbol, bits_per_symbol, access_code=default_access_code, pad_for_usrp=True, whitener_offset=0, whitening=True): """ Build a packet, given access code, payload, and whitener offset @param payload: packet payload, len [0, 4096] @param samples_per_symbol: samples per symbol (needed for padding calculation) @type samples_per_symbol: int @param bits_per_symbol: (needed for padding calculation) @type bits_per_symbol: int @param access_code: string of ascii 0's and 1's @param whitener_offset offset into whitener string to use [0-16) Packet will have access code at the beginning, followed by length, payload and finally CRC-32. """ if not is_1_0_string(access_code): raise ValueError, "access_code must be a string containing only 0's and 1's (%r)" % (access_code,) if not whitener_offset >=0 and whitener_offset < 16: raise ValueError, "whitener_offset must be between 0 and 15, inclusive (%i)" % (whitener_offset,) (packed_access_code, padded) = conv_1_0_string_to_packed_binary_string(access_code) (packed_preamble, ignore) = conv_1_0_string_to_packed_binary_string(preamble) payload_with_crc = gru.gen_and_append_crc32(payload) #print "outbound crc =", string_to_hex_list(payload_with_crc[-4:]) L = len(payload_with_crc) MAXLEN = len(random_mask_tuple) if L > MAXLEN: raise ValueError, "len(payload) must be in [0, %d]" % (MAXLEN,) if whitening: pkt = ''.join((packed_preamble, packed_access_code, make_header(L, whitener_offset), whiten(payload_with_crc, whitener_offset), '\x55')) else: pkt = ''.join((packed_preamble, packed_access_code, make_header(L, whitener_offset), (payload_with_crc), '\x55')) if pad_for_usrp: pkt = pkt + (_npadding_bytes(len(pkt), samples_per_symbol, bits_per_symbol) * '\x55') #print "make_packet: len(pkt) =", len(pkt) return pktdef _npadding_bytes(pkt_byte_len, samples_per_symbol, bits_per_symbol): """ Generate sufficient padding such that each packet ultimately ends up being a multiple of 512 bytes when sent across the USB. We send 4-byte samples across the USB (16-bit I and 16-bit Q), thus we want to pad so that after modulation the resulting packet is a multiple of 128 samples. @param ptk_byte_len: len in bytes of packet, not including padding. @param samples_per_symbol: samples per bit (1 bit / symbolwidth GMSK) @type samples_per_symbol: int @param bits_per_symbol: bits per symbol (log2(modulation order)) @type bits_per_symbol: int @returns number of bytes of padding to append. """ modulus = 128 byte_modulus = gru.lcm(modulus/8, samples_per_symbol) * bits_per_symbol / samples_per_symbol r = pkt_byte_len % byte_modulus if r == 0: return 0 return byte_modulus - r def unmake_packet(whitened_payload_with_crc, whitener_offset=0, dewhitening=True): """ Return (ok, payload) @param whitened_payload_with_crc: string """ if dewhitening: payload_with_crc = dewhiten(whitened_payload_with_crc, whitener_offset) else: payload_with_crc = (whitened_payload_with_crc) ok, payload = gru.check_crc32(payload_with_crc) if 0: print "payload_with_crc =", string_to_hex_list(payload_with_crc) print "ok = %r, len(payload) = %d" % (ok, len(payload)) print "payload =", string_to_hex_list(payload) return ok, payload# FYI, this PN code is the output of a 15-bit LFSRrandom_mask_tuple = ( 255, 63, 0, 16, 0, 12, 0, 5, 192, 3, 16, 1, 204, 0, 85, 192, 63, 16, 16, 12, 12, 5, 197, 195, 19, 17, 205, 204, 85, 149, 255, 47, 0, 28, 0, 9, 192, 6, 208, 2, 220, 1, 153, 192, 106, 208, 47, 28, 28, 9, 201, 198, 214, 210, 222, 221, 152, 89, 170, 186, 255, 51, 0, 21, 192, 15, 16, 4, 12, 3, 69, 193, 243, 16, 69, 204, 51, 21, 213, 207, 31, 20, 8, 15, 70, 132, 50, 227, 85, 137, 255, 38, 192, 26, 208, 11, 28, 7, 73, 194, 182, 209, 182, 220, 118, 217, 230, 218, 202, 219, 23, 27, 78, 139, 116, 103, 103, 106, 170, 175, 63, 60, 16, 17, 204, 12, 85, 197, 255, 19, 0, 13, 192, 5, 144, 3, 44, 1, 221, 192, 89, 144, 58, 236, 19, 13, 205, 197, 149, 147, 47, 45, 220, 29, 153, 201, 170, 214, 255, 30, 192, 8, 80, 6, 188, 2, 241, 193, 132, 80, 99, 124, 41, 225, 222, 200, 88, 86, 186, 190, 243, 48, 69, 212, 51, 31, 85, 200, 63, 22, 144, 14, 236, 4, 77, 195, 117, 145, 231, 44, 74, 157, 247, 41, 134, 158, 226, 232, 73, 142, 182, 228, 118, 203, 102, 215, 106, 222, 175, 24, 124, 10, 161, 199, 56, 82, 146, 189, 173, 177, 189, 180, 113, 183, 100, 118, 171, 102, 255, 106, 192, 47, 16, 28, 12, 9, 197, 198, 211, 18, 221, 205, 153, 149, 170, 239, 63, 12, 16, 5, 204, 3, 21, 193, 207, 16, 84, 12, 63, 69, 208, 51, 28, 21, 201, 207, 22, 212, 14, 223, 68, 88, 51, 122, 149, 227, 47, 9, 220, 6, 217, 194, 218, 209, 155, 28, 107, 73, 239, 118, 204, 38, 213, 218, 223, 27, 24, 11, 74, 135, 119, 34, 166, 153, 186, 234, 243, 15, 5, 196, 3, 19, 65, 205, 240, 85, 132, 63, 35, 80, 25, 252, 10, 193, 199, 16, 82, 140, 61, 165, 209, 187, 28, 115, 73, 229, 246, 203, 6, 215, 66, 222, 177, 152, 116, 106, 167, 111, 58, 172, 19, 61, 205, 209, 149, 156, 111, 41, 236, 30, 205, 200, 85, 150, 191, 46, 240, 28, 68, 9, 243, 70, 197, 242, 211, 5, 157, 195, 41, 145, 222, 236, 88, 77, 250, 181, 131, 55, 33, 214, 152, 94, 234, 184, 79, 50, 180, 21, 183, 79, 54, 180, 22, 247, 78, 198, 180, 82, 247, 125, 134, 161, 162, 248, 121, 130, 162, 225, 185, 136, 114, 230, 165, 138, 251, 39, 3, 90, 129, 251, 32, 67, 88, 49, 250, 148, 67, 47, 113, 220, 36, 89, 219, 122, 219, 99, 27, 105, 203, 110, 215, 108, 94, 173, 248, 125, 130, 161, 161, 184, 120, 114, 162, 165, 185, 187, 50, 243, 85, 133, 255, 35, 0, 25, 192, 10, 208, 7, 28, 2, 137, 193, 166, 208, 122, 220,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -