Revision c4e072e8
| b/gnuradio-core/src/lib/general/gr_framer_sink_1.cc | ||
|---|---|---|
| 52 | 52 |
} |
| 53 | 53 |
|
| 54 | 54 |
inline void |
| 55 |
gr_framer_sink_1::enter_have_header(int payload_len) |
|
| 55 |
gr_framer_sink_1::enter_have_header(int payload_len, int whitener_offset)
|
|
| 56 | 56 |
{
|
| 57 | 57 |
if (VERBOSE) |
| 58 |
fprintf(stderr, "@ enter_have_header (payload_len = %d)\n", payload_len);
|
|
| 58 |
fprintf(stderr, "@ enter_have_header (payload_len = %d) (offset = %d)\n", payload_len, whitener_offset);
|
|
| 59 | 59 |
|
| 60 | 60 |
d_state = STATE_HAVE_HEADER; |
| 61 | 61 |
d_packetlen = payload_len; |
| 62 |
d_packet_whitener_offset = whitener_offset; |
|
| 62 | 63 |
d_packetlen_cnt = 0; |
| 63 | 64 |
d_packet_byte = 0; |
| 64 | 65 |
d_packet_byte_index = 0; |
| ... | ... | |
| 125 | 126 |
|
| 126 | 127 |
// we have a full header, check to see if it has been received properly |
| 127 | 128 |
if (header_ok()){
|
| 128 |
int payload_len = header_payload_len(); |
|
| 129 |
if (payload_len <= MAX_PKT_LEN) // reasonable? |
|
| 130 |
enter_have_header(payload_len); // yes. |
|
| 131 |
else |
|
| 132 |
enter_search(); // no. |
|
| 129 |
int payload_len; |
|
| 130 |
int payload_offset; |
|
| 131 |
header_payload(&payload_len, &payload_offset); |
|
| 132 |
enter_have_header(payload_len, payload_offset); |
|
| 133 | 133 |
} |
| 134 | 134 |
else |
| 135 | 135 |
enter_search(); // no. |
| ... | ... | |
| 151 | 151 |
if (d_packetlen_cnt == d_packetlen){ // packet is filled
|
| 152 | 152 |
|
| 153 | 153 |
// build a message |
| 154 |
gr_message_sptr msg = gr_make_message(0, 0, 0, d_packetlen_cnt); |
|
| 154 |
// NOTE: passing header field as arg1 is not scalable |
|
| 155 |
gr_message_sptr msg = gr_make_message(0, d_packet_whitener_offset, 0, d_packetlen_cnt); |
|
| 155 | 156 |
memcpy(msg->msg(), d_packet, d_packetlen_cnt); |
| 156 | 157 |
|
| 157 | 158 |
d_target_queue->insert_tail(msg); // send it |
| b/gnuradio-core/src/lib/general/gr_framer_sink_1.h | ||
|---|---|---|
| 70 | 70 |
unsigned char d_packet_byte; // byte being assembled |
| 71 | 71 |
int d_packet_byte_index; // which bit of d_packet_byte we're working on |
| 72 | 72 |
int d_packetlen; // length of packet |
| 73 |
int d_packet_whitener_offset; // offset into whitener string to use |
|
| 73 | 74 |
int d_packetlen_cnt; // how many so far |
| 74 | 75 |
|
| 75 | 76 |
protected: |
| ... | ... | |
| 77 | 78 |
|
| 78 | 79 |
void enter_search(); |
| 79 | 80 |
void enter_have_sync(); |
| 80 |
void enter_have_header(int payload_len); |
|
| 81 |
void enter_have_header(int payload_len, int whitener_offset);
|
|
| 81 | 82 |
|
| 82 | 83 |
bool header_ok() |
| 83 | 84 |
{
|
| ... | ... | |
| 85 | 86 |
return ((d_header >> 16) ^ (d_header & 0xffff)) == 0; |
| 86 | 87 |
} |
| 87 | 88 |
|
| 88 |
int header_payload_len()
|
|
| 89 |
void header_payload(int *len, int *offset)
|
|
| 89 | 90 |
{
|
| 90 | 91 |
// header consists of two 16-bit shorts in network byte order |
| 91 |
int t = (d_header >> 16) & 0xffff; |
|
| 92 |
return t; |
|
| 92 |
// payload length is lower 12 bits |
|
| 93 |
// whitener offset is upper 4 bits |
|
| 94 |
*len = (d_header >> 16) & 0x0fff; |
|
| 95 |
*offset = (d_header >> 28) & 0x000f; |
|
| 93 | 96 |
} |
| 94 | 97 |
|
| 95 | 98 |
public: |
| b/gnuradio-core/src/python/gnuradio/blksimpl/pkt.py | ||
|---|---|---|
| 36 | 36 |
|
| 37 | 37 |
Send packets by calling send_pkt |
| 38 | 38 |
""" |
| 39 |
def __init__(self, fg, modulator, access_code=None, msgq_limit=2, pad_for_usrp=True): |
|
| 39 |
def __init__(self, fg, modulator, access_code=None, msgq_limit=2, pad_for_usrp=True, use_whitener_offset=False):
|
|
| 40 | 40 |
""" |
| 41 | 41 |
Hierarchical block for sending packets |
| 42 | 42 |
|
| ... | ... | |
| 52 | 52 |
@param msgq_limit: maximum number of messages in message queue |
| 53 | 53 |
@type msgq_limit: int |
| 54 | 54 |
@param pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples |
| 55 |
|
|
| 55 |
@param use_whitener_offset: If true, start of whitener XOR string is incremented each packet |
|
| 56 |
|
|
| 56 | 57 |
See gmsk_mod for remaining parameters |
| 57 | 58 |
""" |
| 58 | 59 |
self._modulator = modulator |
| 59 | 60 |
self._pad_for_usrp = pad_for_usrp |
| 60 |
|
|
| 61 |
self._use_whitener_offset = use_whitener_offset |
|
| 62 |
self._whitener_offset = 0 |
|
| 63 |
|
|
| 61 | 64 |
if access_code is None: |
| 62 | 65 |
access_code = packet_utils.default_access_code |
| 63 | 66 |
if not packet_utils.is_1_0_string(access_code): |
| ... | ... | |
| 84 | 87 |
self._modulator.samples_per_symbol(), |
| 85 | 88 |
self._modulator.bits_per_symbol(), |
| 86 | 89 |
self._access_code, |
| 87 |
self._pad_for_usrp) |
|
| 90 |
self._pad_for_usrp, |
|
| 91 |
self._whitener_offset) |
|
| 88 | 92 |
#print "pkt =", string_to_hex_list(pkt) |
| 89 | 93 |
msg = gr.message_from_string(pkt) |
| 94 |
if self._use_whitener_offset is True: |
|
| 95 |
self._whitener_offset = (self._whitener_offset + 1) % 16 |
|
| 96 |
|
|
| 90 | 97 |
self._pkt_input.msgq().insert_tail(msg) |
| 91 | 98 |
|
| 92 | 99 |
|
| ... | ... | |
| 151 | 158 |
def run(self): |
| 152 | 159 |
while self.keep_running: |
| 153 | 160 |
msg = self.rcvd_pktq.delete_head() |
| 154 |
ok, payload = packet_utils.unmake_packet(msg.to_string()) |
|
| 161 |
ok, payload = packet_utils.unmake_packet(msg.to_string(), int(msg.arg1()))
|
|
| 155 | 162 |
if self.callback: |
| 156 | 163 |
self.callback(ok, payload) |
| b/gnuradio-core/src/python/gnuradio/packet_utils.py | ||
|---|---|---|
| 86 | 86 |
return map(lambda x: hex(ord(x)), s) |
| 87 | 87 |
|
| 88 | 88 |
|
| 89 |
def whiten(s): |
|
| 89 |
def whiten(s, o):
|
|
| 90 | 90 |
sa = Numeric.fromstring(s, Numeric.UnsignedInt8) |
| 91 |
z = sa ^ random_mask_vec8[0:len(sa)]
|
|
| 91 |
z = sa ^ random_mask_vec8[o:len(sa)+o]
|
|
| 92 | 92 |
return z.tostring() |
| 93 | 93 |
|
| 94 |
def dewhiten(s): |
|
| 95 |
return whiten(s) # self inverse |
|
| 94 |
def dewhiten(s, o):
|
|
| 95 |
return whiten(s, o) # self inverse
|
|
| 96 | 96 |
|
| 97 | 97 |
|
| 98 |
def make_header(payload_len): |
|
| 99 |
return struct.pack('!HH', payload_len, payload_len)
|
|
| 98 |
def make_header(payload_len, whitener_offset=0): |
|
| 99 |
# Upper nibble is offset, lower 12 bits is len |
|
| 100 |
val = ((whitener_offset & 0xf) << 12) | (payload_len & 0x0fff) |
|
| 101 |
#print "offset =", whitener_offset, " len =", payload_len, " val=", val |
|
| 102 |
return struct.pack('!HH', val, val)
|
|
| 100 | 103 |
|
| 101 | 104 |
def make_packet(payload, samples_per_symbol, bits_per_symbol, |
| 102 |
access_code=default_access_code, pad_for_usrp=True): |
|
| 105 |
access_code=default_access_code, pad_for_usrp=True, |
|
| 106 |
whitener_offset=0): |
|
| 103 | 107 |
""" |
| 104 |
Build a packet, given access code and payload.
|
|
| 108 |
Build a packet, given access code, payload, and whitener offset
|
|
| 105 | 109 |
|
| 106 | 110 |
@param payload: packet payload, len [0, 4096] |
| 107 | 111 |
@param samples_per_symbol: samples per symbol (needed for padding calculation) |
| ... | ... | |
| 109 | 113 |
@param bits_per_symbol: (needed for padding calculation) |
| 110 | 114 |
@type bits_per_symbol: int |
| 111 | 115 |
@param access_code: string of ascii 0's and 1's |
| 116 |
@param whitener_offset offset into whitener string to use [0-16) |
|
| 112 | 117 |
|
| 113 | 118 |
Packet will have access code at the beginning, followed by length, payload |
| 114 | 119 |
and finally CRC-32. |
| ... | ... | |
| 116 | 121 |
if not is_1_0_string(access_code): |
| 117 | 122 |
raise ValueError, "access_code must be a string containing only 0's and 1's (%r)" % (access_code,) |
| 118 | 123 |
|
| 124 |
if not whitener_offset >=0 and whitener_offset < 16: |
|
| 125 |
raise ValueError, "whitener_offset must be between 0 and 15, inclusive (%i)" % (whitener_offset,) |
|
| 126 |
|
|
| 119 | 127 |
(packed_access_code, padded) = conv_1_0_string_to_packed_binary_string(access_code) |
| 120 | 128 |
(packed_preamble, ignore) = conv_1_0_string_to_packed_binary_string(preamble) |
| 121 | 129 |
|
| ... | ... | |
| 127 | 135 |
if L > MAXLEN: |
| 128 | 136 |
raise ValueError, "len(payload) must be in [0, %d]" % (MAXLEN,) |
| 129 | 137 |
|
| 130 |
pkt = ''.join((packed_preamble, packed_access_code, make_header(L), whiten(payload_with_crc), '\x55')) |
|
| 138 |
pkt = ''.join((packed_preamble, packed_access_code, make_header(L, whitener_offset), |
|
| 139 |
whiten(payload_with_crc, whitener_offset), '\x55')) |
|
| 131 | 140 |
if pad_for_usrp: |
| 132 | 141 |
pkt = pkt + (_npadding_bytes(len(pkt), samples_per_symbol, bits_per_symbol) * '\x55') |
| 133 | 142 |
|
| ... | ... | |
| 156 | 165 |
return byte_modulus - r |
| 157 | 166 |
|
| 158 | 167 |
|
| 159 |
def unmake_packet(whitened_payload_with_crc): |
|
| 168 |
def unmake_packet(whitened_payload_with_crc, whitener_offset=0):
|
|
| 160 | 169 |
""" |
| 161 | 170 |
Return (ok, payload) |
| 162 | 171 |
|
| 163 | 172 |
@param whitened_payload_with_crc: string |
| 164 | 173 |
""" |
| 165 |
payload_with_crc = dewhiten(whitened_payload_with_crc) |
|
| 174 |
payload_with_crc = dewhiten(whitened_payload_with_crc, whitener_offset)
|
|
| 166 | 175 |
ok, payload = gru.check_crc32(payload_with_crc) |
| 167 | 176 |
|
| 168 | 177 |
if 0: |
| b/gnuradio-examples/python/digital/Makefile.am | ||
|---|---|---|
| 28 | 28 |
pick_bitrate.py \ |
| 29 | 29 |
receive_path.py \ |
| 30 | 30 |
rx_voice.py \ |
| 31 |
run_length.py \ |
|
| 31 | 32 |
transmit_path.py \ |
| 32 | 33 |
tunnel.py \ |
| 33 | 34 |
tx_voice.py |
| b/gnuradio-examples/python/digital/README | ||
|---|---|---|
| 75 | 75 |
|
| 76 | 76 |
This now uses a carrier sense MAC, so you should be able to ssh |
| 77 | 77 |
between the machines, web browse, etc. |
| 78 |
|
|
| 79 |
* run_length.py: This program takes a single argument '-f FILE' and |
|
| 80 |
outputs the number of runs of similar bits within the file. It is |
|
| 81 |
useful as a diagnostic tool when experimenting with line coding or |
|
| 82 |
whitening algorithms. |
|
| 83 |
|
|
| 84 |
|
|
| b/gnuradio-examples/python/digital/benchmark_tx.py | ||
|---|---|---|
| 71 | 71 |
help="set megabytes to transmit [default=%default]") |
| 72 | 72 |
parser.add_option("","--discontinuous", action="store_true", default=False,
|
| 73 | 73 |
help="enable discontinous transmission (bursts of 5 packets)") |
| 74 |
parser.add_option("","--from-file", default=None,
|
|
| 75 |
help="use file for packet contents") |
|
| 74 | 76 |
|
| 75 | 77 |
transmit_path.add_options(parser, expert_grp) |
| 76 | 78 |
|
| ... | ... | |
| 89 | 91 |
parser.print_help(sys.stderr) |
| 90 | 92 |
sys.exit(1) |
| 91 | 93 |
|
| 94 |
if options.from_file is not None: |
|
| 95 |
source_file = open(options.from_file, 'r') |
|
| 96 |
|
|
| 92 | 97 |
# build the graph |
| 93 | 98 |
fg = my_graph(mods[options.modulation], options) |
| 94 | 99 |
|
| ... | ... | |
| 98 | 103 |
|
| 99 | 104 |
fg.start() # start flow graph |
| 100 | 105 |
|
| 101 |
|
|
| 102 | 106 |
# generate and send packets |
| 103 | 107 |
nbytes = int(1e6 * options.megabytes) |
| 104 | 108 |
n = 0 |
| ... | ... | |
| 106 | 110 |
pkt_size = int(options.size) |
| 107 | 111 |
|
| 108 | 112 |
while n < nbytes: |
| 109 |
send_pkt(struct.pack('!H', pktno) + (pkt_size - 2) * chr(pktno & 0xff))
|
|
| 110 |
n += pkt_size |
|
| 113 |
if options.from_file is None: |
|
| 114 |
data = (pkt_size - 2) * chr(pktno & 0xff) |
|
| 115 |
else: |
|
| 116 |
data = source_file.read(pkt_size - 2) |
|
| 117 |
if data == '': |
|
| 118 |
break; |
|
| 119 |
|
|
| 120 |
payload = struct.pack('!H', pktno) + data
|
|
| 121 |
send_pkt(payload) |
|
| 122 |
n += len(payload) |
|
| 111 | 123 |
sys.stderr.write('.')
|
| 112 | 124 |
if options.discontinuous and pktno % 5 == 4: |
| 113 | 125 |
time.sleep(1) |
| b/gnuradio-examples/python/digital/run_length.py | ||
|---|---|---|
| 1 |
#!/usr/bin/env python |
|
| 2 |
# |
|
| 3 |
# Copyright 2007 Free Software Foundation, Inc. |
|
| 4 |
# |
|
| 5 |
# This file is part of GNU Radio |
|
| 6 |
# |
|
| 7 |
# GNU Radio is free software; you can redistribute it and/or modify |
|
| 8 |
# it under the terms of the GNU General Public License as published by |
|
| 9 |
# the Free Software Foundation; either version 2, or (at your option) |
|
| 10 |
# any later version. |
|
| 11 |
# |
|
| 12 |
# GNU Radio is distributed in the hope that it will be useful, |
|
| 13 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 14 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 15 |
# GNU General Public License for more details. |
|
| 16 |
# |
|
| 17 |
# You should have received a copy of the GNU General Public License |
|
| 18 |
# along with GNU Radio; see the file COPYING. If not, write to |
|
| 19 |
# the Free Software Foundation, Inc., 51 Franklin Street, |
|
| 20 |
# Boston, MA 02110-1301, USA. |
|
| 21 |
# |
|
| 22 |
|
|
| 23 |
from optparse import OptionParser |
|
| 24 |
import sys |
|
| 25 |
|
|
| 26 |
def main(): |
|
| 27 |
parser = OptionParser() |
|
| 28 |
parser.add_option("-f", "--file", default=None,
|
|
| 29 |
help="Choose file to read data from.") |
|
| 30 |
(options, args) = parser.parse_args() |
|
| 31 |
|
|
| 32 |
if options.file == None: |
|
| 33 |
print "Must specify file to read from using '-f'." |
|
| 34 |
sys.exit(1) |
|
| 35 |
print "Using", options.file, "for data." |
|
| 36 |
|
|
| 37 |
f = open(options.file, 'r') |
|
| 38 |
runs = [] |
|
| 39 |
count = 0 |
|
| 40 |
current = 0 |
|
| 41 |
bytes = 0 |
|
| 42 |
bits = 0 |
|
| 43 |
|
|
| 44 |
for ch in f.read(): |
|
| 45 |
x = ord(ch) |
|
| 46 |
bytes = bytes + 1 |
|
| 47 |
for i in range(7,-1,-1): |
|
| 48 |
bits = bits + 1 |
|
| 49 |
t = (x >> i) & 0x1 |
|
| 50 |
if t == current: |
|
| 51 |
count = count + 1 |
|
| 52 |
else: |
|
| 53 |
if count > 0: |
|
| 54 |
if len(runs) < count: |
|
| 55 |
for j in range(count - len(runs)): |
|
| 56 |
runs.append(0); |
|
| 57 |
runs[count-1] = runs[count-1] + 1 |
|
| 58 |
|
|
| 59 |
current = 1-current; |
|
| 60 |
count = 1 |
|
| 61 |
|
|
| 62 |
# Deal with last run at EOF |
|
| 63 |
if len(runs) < count and count > 0: |
|
| 64 |
for j in range(count - len(runs)): |
|
| 65 |
runs.append(0); |
|
| 66 |
runs[count-1] = runs[count-1] + 1 |
|
| 67 |
|
|
| 68 |
chk = 0 |
|
| 69 |
print "Bytes read: ", bytes |
|
| 70 |
print "Bits read: ", bits |
|
| 71 |
|
|
| 72 |
for i in range(len(runs)): |
|
| 73 |
chk = chk + runs[i]*(i+1) |
|
| 74 |
print "Runs of length", i+1, ":", runs[i] |
|
| 75 |
|
|
| 76 |
print "Sum of runs:", chk, "bits" |
|
| 77 |
|
|
| 78 |
print "Maximum run length is", len(runs), "bits" |
|
| 79 |
|
|
| 80 |
if __name__ == "__main__": |
|
| 81 |
main() |
|
| 82 |
|
|
| 83 |
|
|
| b/gnuradio-examples/python/digital/transmit_path.py | ||
|---|---|---|
| 50 | 50 |
self._samples_per_symbol = options.samples_per_symbol # desired samples/baud |
| 51 | 51 |
self._fusb_block_size = options.fusb_block_size # usb info for USRP |
| 52 | 52 |
self._fusb_nblocks = options.fusb_nblocks # usb info for USRP |
| 53 |
|
|
| 53 |
self._use_whitener_offset = options.use_whitener_offset # increment start of whitener XOR data |
|
| 54 |
|
|
| 54 | 55 |
self._modulator_class = modulator_class # the modulator_class we are using |
| 55 | 56 |
|
| 56 | 57 |
if self._tx_freq is None: |
| ... | ... | |
| 80 | 81 |
self._modulator_class(fg, **mod_kwargs), |
| 81 | 82 |
access_code=None, |
| 82 | 83 |
msgq_limit=4, |
| 83 |
pad_for_usrp=True) |
|
| 84 |
pad_for_usrp=True, |
|
| 85 |
use_whitener_offset=options.use_whitener_offset) |
|
| 84 | 86 |
|
| 85 | 87 |
|
| 86 | 88 |
# Set the USRP for maximum transmit gain |
| ... | ... | |
| 200 | 202 |
help="set fpga interpolation rate to INTERP [default=%default]") |
| 201 | 203 |
expert.add_option("", "--log", action="store_true", default=False,
|
| 202 | 204 |
help="Log all parts of flow graph to file (CAUTION: lots of data)") |
| 205 |
expert.add_option("","--use-whitener-offset", action="store_true", default=False,
|
|
| 206 |
help="make sequential packets use different whitening") |
|
| 203 | 207 |
|
| 204 | 208 |
# Make a static method to call before instantiation |
| 205 | 209 |
add_options = staticmethod(add_options) |
Also available in: Unified diff