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 2, 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., 59 Temple Place - Suite 330,
19 # Boston, MA 02111-1307, USA.
25 from gnuradio import gr, packet_utils
26 import gnuradio.gr.gr_threading as _threading
30 def _deprecation_warning(old_name, new_name):
32 print '# Warning: %s is deprecated and will be removed soon.' % (old_name,)
33 print '# Please use the modulation independent block, %s.' % (new_name,)
37 # /////////////////////////////////////////////////////////////////////////////
38 # GMSK mod/demod with packets as i/o
39 # /////////////////////////////////////////////////////////////////////////////
41 class gmsk2_mod_pkts(gr.hier_block):
43 GSM modulator that is a GNU Radio source.
45 Send packets by calling send_pkt
47 def __init__(self, fg, access_code=None, msgq_limit=2, pad_for_usrp=True, *args, **kwargs):
49 Hierarchical block for Gaussian Minimum Shift Key (GMSK) modulation.
51 Packets to be sent are enqueued by calling send_pkt.
52 The output is the complex modulated signal at baseband.
56 @param access_code: AKA sync vector
57 @type access_code: string of 1's and 0's between 1 and 64 long
58 @param msgq_limit: maximum number of messages in message queue
60 @param pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples
62 See gmsk_mod for remaining parameters
64 _deprecation_warning('gmsk2_mod_pkts', 'mod_pkts')
66 self.pad_for_usrp = pad_for_usrp
67 if access_code is None:
68 access_code = packet_utils.default_access_code
69 if not packet_utils.is_1_0_string(access_code):
70 raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,)
71 self._access_code = access_code
73 # accepts messages from the outside world
74 self.pkt_input = gr.message_source(gr.sizeof_char, msgq_limit)
75 self.gmsk_mod = gmsk2.gmsk2_mod(fg, *args, **kwargs)
76 fg.connect(self.pkt_input, self.gmsk_mod)
77 gr.hier_block.__init__(self, fg, None, self.gmsk_mod)
79 def send_pkt(self, payload='', eof=False):
83 @param payload: data to send
87 msg = gr.message(1) # tell self.pkt_input we're not sending any more packets
89 # print "original_payload =", string_to_hex_list(payload)
90 pkt = packet_utils.make_packet(payload,
91 self.gmsk_mod.samples_per_baud(),
92 self.gmsk_mod.bits_per_baud(),
95 #print "pkt =", string_to_hex_list(pkt)
96 msg = gr.message_from_string(pkt)
97 self.pkt_input.msgq().insert_tail(msg)
101 class gmsk2_demod_pkts(gr.hier_block):
103 GSM demodulator that is a GNU Radio sink.
105 The input is complex baseband. When packets are demodulated, they are passed to the
106 app via the callback.
109 def __init__(self, fg, access_code=None, callback=None, threshold=-1, *args, **kwargs):
111 Hierarchical block for Gaussian Minimum Shift Key (GMSK)
114 The input is the complex modulated signal at baseband.
115 Demodulated packets are sent to the handler.
117 @param fg: flow graph
119 @param access_code: AKA sync vector
120 @type access_code: string of 1's and 0's
121 @param callback: function of two args: ok, payload
122 @type callback: ok: bool; payload: string
123 @param threshold: detect access_code with up to threshold bits wrong (-1 -> use default)
126 See gmsk_demod for remaining parameters.
129 _deprecation_warning('gmsk2_demod_pkts', 'demod_pkts')
131 if access_code is None:
132 access_code = packet_utils.default_access_code
133 if not packet_utils.is_1_0_string(access_code):
134 raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,)
135 self._access_code = access_code
138 threshold = 12 # FIXME raise exception
140 self._rcvd_pktq = gr.msg_queue() # holds packets from the PHY
141 self.gmsk_demod = gmsk2.gmsk2_demod(fg, *args, **kwargs)
142 self.correlator = gr.correlate_access_code_bb(access_code, threshold)
144 self.framer_sink = gr.framer_sink_1(self._rcvd_pktq)
145 fg.connect(self.gmsk_demod, self.correlator, self.framer_sink)
147 gr.hier_block.__init__(self, fg, self.gmsk_demod, None)
148 self._watcher = _queue_watcher_thread(self._rcvd_pktq, callback)
150 def carrier_sensed(self):
152 Return True if we detect carrier.
157 class _queue_watcher_thread(_threading.Thread):
158 def __init__(self, rcvd_pktq, callback):
159 _threading.Thread.__init__(self)
161 self.rcvd_pktq = rcvd_pktq
162 self.callback = callback
163 self.keep_running = True
167 # self.keep_running = False
170 while self.keep_running:
171 msg = self.rcvd_pktq.delete_head()
172 ok, payload = packet_utils.unmake_packet(msg.to_string())
174 self.callback(ok, payload)