15deb8d18SXianjun Jiao# 25deb8d18SXianjun Jiao# openwifi side info receive and display program 35deb8d18SXianjun Jiao# Xianjun jiao. [email protected]; [email protected] 45deb8d18SXianjun Jiao# 55deb8d18SXianjun Jiaoimport os 65deb8d18SXianjun Jiaoimport sys 75deb8d18SXianjun Jiaoimport socket 85deb8d18SXianjun Jiaoimport numpy as np 95deb8d18SXianjun Jiaoimport matplotlib.pyplot as plt 105deb8d18SXianjun Jiao 115deb8d18SXianjun Jiaodef display_iq(iq0_capture, iq1_capture): 125deb8d18SXianjun Jiao fig_iq_capture = plt.figure(0) 135deb8d18SXianjun Jiao fig_iq_capture.clf() 145deb8d18SXianjun Jiao 155deb8d18SXianjun Jiao ax_iq0 = fig_iq_capture.add_subplot(211) 165deb8d18SXianjun Jiao # ax_iq0.set_xlabel("sample") 175deb8d18SXianjun Jiao ax_iq0.set_ylabel("I/Q") 185deb8d18SXianjun Jiao ax_iq0.set_title("rx0 I/Q") 195deb8d18SXianjun Jiao plt.plot(iq0_capture.real, 'b') 205deb8d18SXianjun Jiao plt.plot(iq0_capture.imag, 'r') 215deb8d18SXianjun Jiao plt.ylim(-32767, 32767) 225deb8d18SXianjun Jiao 235deb8d18SXianjun Jiao ax_iq1 = fig_iq_capture.add_subplot(212) 245deb8d18SXianjun Jiao ax_iq1.set_xlabel("sample") 255deb8d18SXianjun Jiao ax_iq1.set_ylabel("I/Q") 265deb8d18SXianjun Jiao ax_iq1.set_title("rx1 I/Q") 275deb8d18SXianjun Jiao plt.plot(iq1_capture.real, 'b') 285deb8d18SXianjun Jiao plt.plot(iq1_capture.imag, 'r') 295deb8d18SXianjun Jiao plt.ylim(-32767, 32767) 309fde3bffSthavinga fig_iq_capture.canvas.flush_events() 315deb8d18SXianjun Jiao 325deb8d18SXianjun Jiaodef parse_iq(iq, iq_len): 335deb8d18SXianjun Jiao # print(len(iq), iq_len) 345deb8d18SXianjun Jiao num_dma_symbol_per_trans = 1 + iq_len 355deb8d18SXianjun Jiao num_int16_per_trans = num_dma_symbol_per_trans*4 # 64bit per dma symbol 365deb8d18SXianjun Jiao num_trans = round(len(iq)/num_int16_per_trans) 375deb8d18SXianjun Jiao # print(len(iq), iq.dtype, num_trans) 385deb8d18SXianjun Jiao iq = iq.reshape([num_trans, num_int16_per_trans]) 395deb8d18SXianjun Jiao 405deb8d18SXianjun Jiao timestamp = iq[:,0] + pow(2,16)*iq[:,1] + pow(2,32)*iq[:,2] + pow(2,48)*iq[:,3] 41*e556af35SXianjun Jiao iq0_capture = np.int16(iq[:,4::4]) + np.int16(iq[:,5::4])*1j 42*e556af35SXianjun Jiao iq1_capture = np.int16(iq[:,6::4]) + np.int16(iq[:,7::4])*1j 435deb8d18SXianjun Jiao # print(num_trans, iq_len, iq0_capture.shape, iq1_capture.shape) 445deb8d18SXianjun Jiao 455deb8d18SXianjun Jiao iq0_capture = iq0_capture.reshape([num_trans*iq_len,]) 465deb8d18SXianjun Jiao iq1_capture = iq1_capture.reshape([num_trans*iq_len,]) 475deb8d18SXianjun Jiao 485deb8d18SXianjun Jiao return timestamp, iq0_capture, iq1_capture 495deb8d18SXianjun Jiao 505deb8d18SXianjun JiaoUDP_IP = "192.168.10.1" #Local IP to listen 515deb8d18SXianjun JiaoUDP_PORT = 4000 #Local port to listen 525deb8d18SXianjun Jiao 535deb8d18SXianjun Jiaosock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP 545deb8d18SXianjun Jiaosock.bind((UDP_IP, UDP_PORT)) 55a4eb2001SXianjun Jiaosock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 464) # for low latency. 464 is the minimum udp length in our case (CSI only) 565deb8d18SXianjun Jiao 575deb8d18SXianjun Jiao# align with side_ch_control.v and all related user space, remote files 585deb8d18SXianjun JiaoMAX_NUM_DMA_SYMBOL = 8192 595deb8d18SXianjun Jiao 605deb8d18SXianjun Jiaoif len(sys.argv)<2: 615deb8d18SXianjun Jiao print("Assume iq_len = 8187! (Max UDP 65507 bytes; (65507/8)-1 = 8187)") 625deb8d18SXianjun Jiao iq_len = 8187 635deb8d18SXianjun Jiaoelse: 645deb8d18SXianjun Jiao iq_len = int(sys.argv[1]) 655deb8d18SXianjun Jiao print(iq_len) 665deb8d18SXianjun Jiao # print(type(num_eq)) 675deb8d18SXianjun Jiao 685deb8d18SXianjun Jiaoif iq_len>8187: 695deb8d18SXianjun Jiao iq_len = 8187 705deb8d18SXianjun Jiao print('Limit iq_len to 8187! (Max UDP 65507 bytes; (65507/8)-1 = 8187)') 715deb8d18SXianjun Jiao 725deb8d18SXianjun Jiaonum_dma_symbol_per_trans = 1 + iq_len 735deb8d18SXianjun Jiaonum_byte_per_trans = 8*num_dma_symbol_per_trans 745deb8d18SXianjun Jiao 755deb8d18SXianjun Jiaoif os.path.exists("iq_2ant.txt"): 765deb8d18SXianjun Jiao os.remove("iq_2ant.txt") 775deb8d18SXianjun Jiaoiq_fd=open('iq_2ant.txt','a') 785deb8d18SXianjun Jiao 799fde3bffSthavingaplt.ion() 809fde3bffSthavinga 815deb8d18SXianjun Jiaowhile True: 825deb8d18SXianjun Jiao try: 835deb8d18SXianjun Jiao data, addr = sock.recvfrom(MAX_NUM_DMA_SYMBOL*8) # buffer size 845deb8d18SXianjun Jiao # print(addr) 855deb8d18SXianjun Jiao test_residual = len(data)%num_byte_per_trans 865deb8d18SXianjun Jiao # print(len(data)/8, num_dma_symbol_per_trans, test_residual) 875deb8d18SXianjun Jiao if (test_residual != 0): 885deb8d18SXianjun Jiao print("Abnormal length") 895deb8d18SXianjun Jiao 90*e556af35SXianjun Jiao iq = np.frombuffer(data, dtype='uint16') 915deb8d18SXianjun Jiao np.savetxt(iq_fd, iq) 925deb8d18SXianjun Jiao 935deb8d18SXianjun Jiao timestamp, iq0_capture, iq1_capture = parse_iq(iq, iq_len) 945deb8d18SXianjun Jiao print(timestamp, max(iq0_capture.real), max(iq1_capture.real)) 955deb8d18SXianjun Jiao display_iq(iq0_capture, iq1_capture) 965deb8d18SXianjun Jiao 975deb8d18SXianjun Jiao except KeyboardInterrupt: 985deb8d18SXianjun Jiao print('User quit') 995deb8d18SXianjun Jiao break 1005deb8d18SXianjun Jiao 1015deb8d18SXianjun Jiaoprint('close()') 1029fde3bffSthavingaiq_fd.close() 1035deb8d18SXianjun Jiaosock.close() 104