Thomas Kolb
fffea05647
This script manages the interface between the TUN device and GNU Radio. In the future, it will also do node registration, user scheduling and other things necessary to run the network.
131 lines
3.8 KiB
Python
Executable file
131 lines
3.8 KiB
Python
Executable file
#!/usr/bin/env python2
|
|
|
|
import fcntl
|
|
import struct
|
|
import os
|
|
import socket
|
|
import threading
|
|
from select import select
|
|
import sys
|
|
|
|
import logging as log
|
|
|
|
sys.path.append(os.environ.get('GRC_HIER_PATH', os.path.expanduser('~/.grc_gnuradio')))
|
|
from hamnet70_demod import hamnet70_demod # grc-generated hier_block
|
|
from hamnet70_mod import hamnet70_mod # grc-generated hier_block
|
|
|
|
import pmt
|
|
from gnuradio import gr
|
|
from gnuradio import blocks
|
|
|
|
import numpy as np
|
|
|
|
TUNSETIFF = 0x400454ca
|
|
TUNSETOWNER = TUNSETIFF + 2
|
|
IFF_TUN = 0x0001
|
|
IFF_TAP = 0x0002
|
|
IFF_NO_PI = 0x1000
|
|
|
|
|
|
class Hamnet70Controller(gr.basic_block):
|
|
def _tuntap_setup(self):
|
|
tun = open('/dev/net/tun', 'r+b', buffering=0)
|
|
ifr = struct.pack('16sH', self._tuntap_name, IFF_TUN | IFF_NO_PI)
|
|
fcntl.ioctl(tun, TUNSETIFF, ifr)
|
|
fcntl.ioctl(tun, TUNSETOWNER, 1000)
|
|
|
|
self._tuntap = tun
|
|
|
|
def _handle_rx_pdu(self, pdu):
|
|
print(msg)
|
|
os.write(self._tuntap.fileno(), pdu)
|
|
|
|
def _txthread_func(self):
|
|
log.info("tx thread started.")
|
|
while not self.shutdown:
|
|
rlist = [self._tuntap]
|
|
|
|
rready, wready, eready = select(rlist, [], [], 0.1)
|
|
log.info("select returned: {}, {}, {}".format(rready, wready, eready))
|
|
|
|
if rready:
|
|
data = os.read(self._tuntap.fileno(), 65536)
|
|
log.info("packet from TAP: {}".format(data))
|
|
|
|
# convert data to numpy
|
|
npdata = np.zeros(len(data), dtype=np.uint8)
|
|
for i in range(len(data)):
|
|
npdata[i] = ord(data[i])
|
|
|
|
pmt_data = pmt.to_pmt(npdata)
|
|
pmt_pdu = pmt.cons(pmt.PMT_NIL, pmt_data)
|
|
|
|
self.message_port_pub(pmt.intern("packet_tx"), pmt_pdu)
|
|
|
|
def __init__(self, tuntap_name='hamnet70'):
|
|
gr.basic_block.__init__(self, name="Hamnet70 Controller", in_sig=None, out_sig=None)
|
|
|
|
self._tuntap_name = tuntap_name
|
|
self._txthread = None
|
|
|
|
self._tuntap_setup()
|
|
|
|
self.message_port_register_out(pmt.intern("packet_tx"))
|
|
self.message_port_register_in(pmt.intern("packet_rx"))
|
|
|
|
self.set_msg_handler(pmt.intern("packet_rx"), self._handle_rx_pdu)
|
|
|
|
self.start_txthread()
|
|
|
|
def __del__(self):
|
|
self.stop_txthread()
|
|
tun.close()
|
|
|
|
def start_txthread(self):
|
|
if not self._txthread:
|
|
self.shutdown = False
|
|
|
|
self._txthread = threading.Thread(target=self._txthread_func)
|
|
self._txthread.daemon = False
|
|
self._txthread.start()
|
|
|
|
def stop_txthread(self):
|
|
if self._txthread:
|
|
self.shutdown = True
|
|
self._txthread.join()
|
|
self._txthread = None
|
|
|
|
|
|
class Hamnet70TopBlock(gr.top_block):
|
|
def __init__(self):
|
|
gr.top_block.__init__(self, "Top Block")
|
|
|
|
# Create blocks
|
|
|
|
self._controller = Hamnet70Controller()
|
|
|
|
self._mod = hamnet70_mod(samp_rate_0=200e3)
|
|
self._demod = hamnet70_demod(samp_rate=200e3)
|
|
|
|
self._input_fifo = blocks.file_source(gr.sizeof_gr_complex*1, 'rx.fifo', True)
|
|
self._output_fifo = blocks.file_sink(gr.sizeof_gr_complex*1, 'tx.fifo', False)
|
|
|
|
self._throttle = blocks.throttle(gr.sizeof_gr_complex*1, 200e3)
|
|
|
|
# Connect blocks
|
|
self.connect((self._input_fifo, 0), (self._throttle, 0))
|
|
self.connect((self._throttle, 0), (self._demod, 0))
|
|
self.msg_connect((self._demod, 'message_out'), (self._controller, 'packet_rx'))
|
|
|
|
self.msg_connect((self._controller, 'packet_tx'), (self._mod, 'packet_in'))
|
|
self.connect((self._mod, 0), (self._output_fifo, 0))
|
|
|
|
if __name__ == "__main__":
|
|
top_block = Hamnet70TopBlock()
|
|
top_block.start()
|
|
|
|
try:
|
|
top_block.wait()
|
|
except KeyboardInterrupt:
|
|
top_block.stop()
|