GNURadio全双工ARQ通信

原github项目链接: FDMATunnel,这个项目提供了非常棒的底层网络框架,后续只需要向 /dev/net/tun 写入IP数据包既可完成传输。不过这个2019年的项目居然使用了 Python2 ,因此我用 LLM 将它改成了 Python3 版本。

代码解读

项目结构

.
├── FDMA.rar
├── README.md
├── __pycache__
│?? ├── constant_client.cpython-310.pyc
│?? └── constant_server.cpython-310.pyc
├── client_test.py
├── client_test2.py
├── constant_client.py
├── constant_client2.py
├── constant_server.py
├── ofdm
│?? ├── __pycache__
│?? ├── benchmark_add_channel.py
│?? ├── benchmark_rx.py
│?? ├── benchmark_tx.py
│?? ├── constant_client.py
│?? ├── constant_server.py
│?? ├── gr_plot_ofdm.py
│?? ├── original_data.txt
│?? ├── receive_path.py
│?? ├── receive_path.py.backup
│?? ├── received_data.txt
│?? ├── transmit_path.py
│?? ├── transmit_path.py.backup
│?? ├── tunnel_client.py	# 客户端入口程序
│?? ├── tunnel_server.py	# 服务端入口程序
│?? └── uhd_interface.py
└── server_test.py

核心工作循环

def main_loop(self):
    """
    Main loop for MAC.
    Only returns if we get an error reading from TUN.

    FIXME: may want to check for EINTR and EAGAIN and reissue read
    """
    # min_delay = 0.001               # seconds

    # if we have recv ack, we can get next pkt
    if self.recv_ack:
        while 1:
            payload = os.read(self.tun_fd, 10 * 1024)
            src_addr, dest_addr = get_addr(payload)

            if not payload:  # something goes wrong
                self.tb.txpath.send_pkt(eof=True)
                return

            # should I trans this pkt?
            if self.tx_accept_pkt(dest_addr):
                control = CTL_NORM
                pkt_cnt = self.tx_id

                # it's a control pkt?
                if self.tx_change_bandwidth(payload):
                    """
                    change bandwidth 
                    TODO
                    """
                    control = CTL_CHANGE_BW

                # pkt process: add header et.
                header = [pkt_cnt] + src_addr + dest_addr + [control]
                self.tx_pdu = add_header(header, payload)
                break

    # trans data
    if self.verbose:
        print("Send time: %.6f" % time.time())

    self.tb.txpath.send_pkt(self.tx_pdu)
    self.recv_ack = 0
    # self.tb.txpath.send_pkt(data)

    if self.verbose:
        print("Tx: len(payload) = %4d" % (len(payload),))

    self.timer = threading.Timer(WAIT_INTERVAL, self.arq_fsm)