Imported Upstream version 3.2.2
[debian/gnuradio] / gnuradio-core / src / python / gnuradio / packet_utils.py
index 2602f1fecde0406a77ee75bb52776c9b901b0bf2..1417c17fa5b1d731a70bd07571040b66b710d5ed 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2005,2006 Free Software Foundation, Inc.
+# Copyright 2005,2006,2007 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -20,7 +20,7 @@
 # 
 
 import struct
-import Numeric
+import numpy
 from gnuradio import gru
 
 
@@ -72,7 +72,7 @@ def conv_1_0_string_to_packed_binary_string(s):
 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('\xAA\xAA\xAA\xAB')
+  conv_packed_binary_string_to_1_0_string('\xA4\xF2')
 
 def is_1_0_string(s):
     if not isinstance(s, str):
@@ -86,22 +86,26 @@ def string_to_hex_list(s):
     return map(lambda x: hex(ord(x)), s)
 
 
-def whiten(s):
-    sa = Numeric.fromstring(s, Numeric.UnsignedInt8)
-    z = sa ^ random_mask_vec8[0:len(sa)]
+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):
-    return whiten(s)        # self inverse
+def dewhiten(s, o):
+    return whiten(s, o)        # self inverse
 
 
-def make_header(payload_len):
-    return struct.pack('!HH', payload_len, payload_len)
+def 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):
+                access_code=default_access_code, pad_for_usrp=True,
+                whitener_offset=0, whitening=True):
     """
-    Build a packet, given access code and payload.
+    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)
@@ -109,6 +113,7 @@ def make_packet(payload, samples_per_symbol, bits_per_symbol,
     @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.
@@ -116,6 +121,9 @@ def make_packet(payload, samples_per_symbol, bits_per_symbol,
     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)
     
@@ -127,7 +135,13 @@ def make_packet(payload, samples_per_symbol, bits_per_symbol,
     if L > MAXLEN:
         raise ValueError, "len(payload) must be in [0, %d]" % (MAXLEN,)
 
-    pkt = ''.join((packed_preamble, packed_access_code, make_header(L), whiten(payload_with_crc), '\x55'))
+    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')
 
@@ -143,8 +157,10 @@ def _npadding_bytes(pkt_byte_len, samples_per_symbol, bits_per_symbol):
     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 / symbolwith GMSK)
+    @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.
     """
@@ -156,13 +172,18 @@ def _npadding_bytes(pkt_byte_len, samples_per_symbol, bits_per_symbol):
     return byte_modulus - r
     
 
-def unmake_packet(whitened_payload_with_crc):
+def unmake_packet(whitened_payload_with_crc, whitener_offset=0, dewhitening=True):
     """
     Return (ok, payload)
 
     @param whitened_payload_with_crc: string
     """
-    payload_with_crc = dewhiten(whitened_payload_with_crc)
+
+    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:
@@ -432,5 +453,5 @@ random_mask_tuple = (
   199, 113, 146, 164, 109, 187, 109, 179, 109, 181, 237, 183,  13, 182, 133, 182, 
   227,  54, 201, 214, 214, 222, 222, 216,  88,  90, 186, 187,  51,  51, 255,  63 )
 
-random_mask_vec8 = Numeric.array(random_mask_tuple, Numeric.UnsignedInt8)
+random_mask_vec8 = numpy.array(random_mask_tuple, numpy.uint8)