我一直在尝试使用GNU Radio并遇到了tunnel.py程序。此程序允许您使用Linux TUN / TAP设备通过无线电链路隧道传输IP流量。在大多数情况下,它正在工作,但代码的一部分让我感到困惑。
有一个实现'基本MAC层'的类。该类具有回调函数,该函数将新数据包写入TUN设备。此函数(phy_rx_callback
)从单独的线程调用。
函数main_loop
在发送新数据包之前执行载波检测。我不明白的是它为什么在单独的非重叠传输信道上传输之前感知接收信道。
RX和TX通道都是独立的频率,我们的硬件允许全双工通信。
所以,我的问题是main_loop
正在执行,另一个线程异步调用phy_rx_callback
函数的含义是什么?问题是我试图理解载波侦听循环的目的,我发现评论该代码会严重降低性能。在使用发送通道之前监视接收通道对我来说没有意义,实质上是将其转换为半双工。然后我没有看到使用两个频率的目的,一个用于发送,一个用于接收。我开始怀疑这里是否存在一个奇怪的线程问题。
最初创建cs_mac
类的单个实例。 rx_callback函数的“指针”向下传递给实际调用它的线程类。这是cs_mac类:
class cs_mac(object):
def __init__(self, tun_fd, verbose=False):
self.tun_fd = tun_fd # file descriptor for TUN/TAP interface
self.verbose = verbose
self.tb = None # top block (access to PHY)
def set_top_block(self, tb):
self.tb = tb
def phy_rx_callback(self, ok, payload):
if self.verbose:
print "Rx: ok = %r len(payload) = %4d" % (ok, len(payload))
if ok:
os.write(self.tun_fd, payload)
def main_loop(self):
min_delay = 0.001 # seconds
while 1:
payload = os.read(self.tun_fd, 10*1024)
if not payload:
self.tb.send_pkt(eof=True)
break
if self.verbose:
print "Tx: len(payload) = %4d" % (len(payload),)
delay = min_delay
while self.tb.carrier_sensed():
sys.stderr.write('B')
time.sleep(delay)
if delay < 0.050:
delay = delay * 2 # exponential back-off
self.tb.send_pkt(payload)
好的,所以使用调用ctypes.CDLL('libc.so.6').syscall(186))
的{{1}}我发现调用gettid
函数的线程具有相同的PID,但是具有不同的TID。
问题变成了,让一个单独的线程从主线程中的对象调用一个函数(当该线程不断循环)时有什么含义?
答案 0 :(得分:0)
函数main_loop在发送新数据包之前执行载波侦听。我不明白的是它为什么在单独的非重叠传输信道上传输之前感知接收信道。
CSMA / CA旨在与半双工系统一起使用,其中所有节点对TX和RX使用相同的频率。所以你是对的,如果用不同的传输方式传输RX通道是没有意义的。
在receive_path.py文件中调用carrier_sensed(),因此它应该在RX线程中运行。在我的代码中,我注释掉了sys.stderr.write('B')和time.sleep(延迟)这一行,这似乎并没有影响性能。在我的情况下可能会有所不同,因为我使用的是半双工的XCVR子板。