2
# Copyright 2005,2006 Free Software Foundation, Inc.
4
# This file is part of GNU Radio
6
# GNU Radio is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 3, or (at your option)
11
# GNU Radio is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
# GNU General Public License for more details.
16
# You should have received a copy of the GNU General Public License
17
# along with GNU Radio; see the file COPYING. If not, write to
18
# the Free Software Foundation, Inc., 51 Franklin Street,
19
# Boston, MA 02110-1301, USA.
25
from gnuradio import gr, packet_utils
26
import gnuradio.gr.gr_threading as _threading
29
# /////////////////////////////////////////////////////////////////////////////
30
# mod/demod with packets as i/o
31
# /////////////////////////////////////////////////////////////////////////////
33
class mod_pkts(gr.hier_block):
35
Wrap an arbitrary digital modulator in our packet handling framework.
37
Send packets by calling send_pkt
39
def __init__(self, fg, modulator, access_code=None, msgq_limit=2, pad_for_usrp=True):
41
Hierarchical block for sending packets
43
Packets to be sent are enqueued by calling send_pkt.
44
The output is the complex modulated signal at baseband.
48
@param modulator: instance of modulator class (gr_block or hier_block)
49
@type modulator: complex baseband out
50
@param access_code: AKA sync vector
51
@type access_code: string of 1's and 0's between 1 and 64 long
52
@param msgq_limit: maximum number of messages in message queue
54
@param pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples
56
See gmsk_mod for remaining parameters
58
self._modulator = modulator
59
self._pad_for_usrp = pad_for_usrp
61
if access_code is None:
62
access_code = packet_utils.default_access_code
63
if not packet_utils.is_1_0_string(access_code):
64
raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,)
65
self._access_code = access_code
67
# accepts messages from the outside world
68
self._pkt_input = gr.message_source(gr.sizeof_char, msgq_limit)
69
fg.connect(self._pkt_input, self._modulator)
70
gr.hier_block.__init__(self, fg, None, self._modulator)
72
def send_pkt(self, payload='', eof=False):
76
@param payload: data to send
80
msg = gr.message(1) # tell self._pkt_input we're not sending any more packets
82
# print "original_payload =", string_to_hex_list(payload)
83
pkt = packet_utils.make_packet(payload,
84
self._modulator.samples_per_symbol(),
85
self._modulator.bits_per_symbol(),
88
#print "pkt =", string_to_hex_list(pkt)
89
msg = gr.message_from_string(pkt)
90
self._pkt_input.msgq().insert_tail(msg)
94
class demod_pkts(gr.hier_block):
96
Wrap an arbitrary digital demodulator in our packet handling framework.
98
The input is complex baseband. When packets are demodulated, they are passed to the
102
def __init__(self, fg, demodulator, access_code=None, callback=None, threshold=-1):
104
Hierarchical block for demodulating and deframing packets.
106
The input is the complex modulated signal at baseband.
107
Demodulated packets are sent to the handler.
109
@param fg: flow graph
111
@param demodulator: instance of demodulator class (gr_block or hier_block)
112
@type demodulator: complex baseband in
113
@param access_code: AKA sync vector
114
@type access_code: string of 1's and 0's
115
@param callback: function of two args: ok, payload
116
@type callback: ok: bool; payload: string
117
@param threshold: detect access_code with up to threshold bits wrong (-1 -> use default)
121
self._demodulator = demodulator
122
if access_code is None:
123
access_code = packet_utils.default_access_code
124
if not packet_utils.is_1_0_string(access_code):
125
raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,)
126
self._access_code = access_code
129
threshold = 12 # FIXME raise exception
131
self._rcvd_pktq = gr.msg_queue() # holds packets from the PHY
132
self.correlator = gr.correlate_access_code_bb(access_code, threshold)
134
self.framer_sink = gr.framer_sink_1(self._rcvd_pktq)
135
fg.connect(self._demodulator, self.correlator, self.framer_sink)
137
gr.hier_block.__init__(self, fg, self._demodulator, None)
138
self._watcher = _queue_watcher_thread(self._rcvd_pktq, callback)
141
class _queue_watcher_thread(_threading.Thread):
142
def __init__(self, rcvd_pktq, callback):
143
_threading.Thread.__init__(self)
145
self.rcvd_pktq = rcvd_pktq
146
self.callback = callback
147
self.keep_running = True
152
while self.keep_running:
153
msg = self.rcvd_pktq.delete_head()
154
ok, payload = packet_utils.unmake_packet(msg.to_string())
156
self.callback(ok, payload)