Hi,
I am testing the carrier sense mechanism on USRP based on code from
benchmark_tx.py and tunnel.py. My scenario is to receive packets from two
distinctive nodes simultaneously at the third node. I am prefixing the
payload with sender node name to identify the sender.
When I am trying to send the packets from two nodes simultaneously, the
packets are still colliding, though I have incorporated carrier sense
mechanism in to my code. Please help me in this respect and if possible
suggest me a solution.
I think, packets are being sent by the lower level C++ processing blocks and
send_pkt() just enqueues the packets. So rather than holding sending of
packet, this code is just holding the packet from getting enqueued in
message queue. Which is not really the holding of packet till carrier is
free. Once packets are in message queue, they are transmitted irrespective
of carrier availability. So there is still possibility of packet collision.
Am I correct in my understanding of this real-time scenario?
Attached following is the code of sender application. Receiving application
is more or less similar to benchmark_rx.py with ability to identify the
packets.
Tx_carrier_sense.py
class my_top_block(gr.top_block):
def __init__(self, modulator, demodulator, rx_callback, options):
gr.top_block.__init__(self)
self.txpath = transmit_path(modulator, options)
self.rxpath = receive_path(demodulator, rx_callback, options)
self.connect(self.txpath)
self.connect(self.rxpath)
#
/////////////////////////////////////////////////////////////////////////////
# main
#
/////////////////////////////////////////////////////////////////////////////
def main():
def send_pkt(payload='', eof=False):
return tb.txpath.send_pkt(payload, eof)
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
pass
def rx_callback(ok, payload):
print "ok = %r" % (ok)
def carrier_sensed():
""" Return True if the receive path thinks there's carrier """
return tb.rxpath.carrier_sensed()
demods = modulation_utils.type_1_demods()
mods = modulation_utils.type_1_mods()
parser = OptionParser(option_class=eng_option,
conflict_handler="resolve")
expert_grp = parser.add_option_group("Expert")
parser.add_option("-m", "--modulation", type="choice",
choices=mods.keys(),
default='gmsk',
help="Select modulation from: %s [default=%%default]"
% (', '.join(mods.keys()),))
parser.add_option("-s", "--size", type="eng_float", default=1500,
help="set packet size [default=%default]")
parser.add_option("-M", "--megabytes", type="eng_float", default=1.0,
help="set megabytes to transmit [default=%default]")
parser.add_option("","--discontinuous", action="store_true",
default=False,
help="enable discontinous transmission (bursts of 5
packets)")
parser.add_option("","--from-file", default=None,
help="use file for packet contents")
receive_path.add_options(parser, expert_grp)
transmit_path.add_options(parser, expert_grp)
for mod in mods.values():
mod.add_options(expert_grp)
fusb_options.add_options(expert_grp)
(options, args) = parser.parse_args ()
if len(args) != 0:
parser.print_help()
sys.exit(1)
if options.tx_freq is None:
sys.stderr.write("You must specify -f FREQ or --freq FREQ\n")
parser.print_help(sys.stderr)
sys.exit(1)
if options.from_file is not None:
source_file = open(options.from_file, 'r')
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
pass
# build the graph
tb = my_top_block(mods[options.modulation], demods[options.modulation],
rx_callback, options)
r = gr.enable_realtime_scheduling()
if r != gr.RT_OK:
print "Warning: failed to enable realtime scheduling"
tb.start() # start flow graph
# generate and send packets
nbytes = int(1e6 * options.megabytes)
n = 0
pktno = 0
pkt_size = int(options.size)
min_delay = 0.0001
while n < nbytes:
if options.from_file is None:
data = "C-node" + (pkt_size - 8) * chr(pktno & 0xff)
else:
data = source_file.read(pkt_size - 2)
if data == '':
break;
payload = struct.pack('!H', pktno & 0xffff) + data
delay = min_delay
while carrier_sensed():
print "sensed"
time.sleep(delay)
if delay < 0.050:
delay = delay * 2 # exponential back-off
send_pkt(payload)
n += len(payload)
sys.stderr.write('.')
if options.discontinuous and pktno % 5 == 4:
time.sleep(0.3) # default = 1
pktno += 1
delay = min_delay
while carrier_sensed():
time.sleep(delay)
if delay < 0.050:
delay = delay * 2 # exponential back-off
send_pkt(eof=True)
tb.wait() # wait for it to finish
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
pass