seemoo-lab / nexmon_csi

Channel State Information Extraction on Various Broadcom Wi-Fi Chips
313 stars 122 forks source link

CSI streams for each Antenna #99

Open salmanpolito opened 4 years ago

salmanpolito commented 4 years ago

Hi @matthiasseemoo @jlinktu I am using the Nexmon_CSI on RT-AC86U. I am working on a passive sensing project. I want to get the CSI from all the available streams, so that I can sanitize it. Is it possible to get the CSI streams for all the four antenna simultaneously? I checked almost all the issues, but it seems that we have to manually change the Core "C" and "N" value and then we can get the CSI stream for that particular Antenna. Looking forward to hearing from you. Thanks in advance.

salmanpolito commented 4 years ago

Sorry, I think my query was very simple: I finally figured out how to do it. --> As mentioned in previous issues, RT-AC86U (or any other nexmon supported devices ) contains core for each antenna. there are four cores in RT-AC86U and hence supporting four antenna, 3 external and one internal. rsxx is the spatial streams received on each antenna. --> Unlike Atheros_CSI tool that extracts CSI in parallel at all antenna for each packet, Nexmon CSI is extracting it sequentially. for instance, by selecting core=3 and rsxx=0 (i.e. one stream), it will receive first packet on antenna 1, second on antenna 2 and 3rd on antenna 3 and will loop again for the subsequent packets. --> I noticed that the CSI was received very slow at my receiver AP, (I have used two RT-AC86U APs, one as transmitter and second as a receiver). The normal speed was around 40-50 Hz, and I required at least 1k packets. I, therefore, used iperf on a laptop connected to transmitter AP and transferred 100Gb file to the server. The packet rate increased significantly. --> I have done some minor changes in the MATLAB file, which I believe will help the new users to get the CSI stream from all antenna. I have done it for three antennas and one stream only. (please ignore the device orientation part) --> I am still looking forward to your insightful comments. clc clear all close all %% configuration CHIP = '4366c0'; % wifi chip (possible values 4339, 4358, 43455c0, 4366c0) BW = 80; % bandwidth FILE = './asus/static2'; % capture file NPKTS_MAX = 18000; % max number of UDPs to process

%% read file HOFFSET = 16; % header offset NFFT = BW3.2; % fft size p = readpcap(); p.open(FILE); n = min(length(p.all()),NPKTS_MAX); p.from_start(); csi_buff = complex(zeros(n,NFFT),0); k = 1; core=zeros(1,n); rxss=core; while (k <= n) f = p.next(); if isempty(f) disp('no more frames'); break; end if f.header.orig_len-(HOFFSET-1)4 ~= NFFT4 disp('skipped frame with incorrect size'); continue; end payload = f.payload; if length(payload)<NFFT break; end payloadbytes = typecast(payload ,'uint8'); core(k) = bitand(payloadbytes(56),3); rxss(k) = bitand(bitshift(payloadbytes(56),-3),3); H = payload(HOFFSET:HOFFSET+NFFT-1)'; if (strcmp(CHIP,'4339') || strcmp(CHIP,'43455c0')) Hout = typecast(H, 'int16'); elseif (strcmp(CHIP,'4358')) Hout = unpack_float(int32(0), int32(NFFT), H); elseif (strcmp(CHIP,'4366c0')) Hout = unpack_float(int32(1), int32(NFFT), H); else disp('invalid CHIP'); break; end Hout = reshape(Hout,2,[]).'; cmplx = double(Hout(1:NFFT,1))+1jdouble(Hout(1:NFFT,2)); csi_buff(k,:) = cmplx.'; time_stamp(k)=f.header.ts_sec; k = k + 1; end

% pilot Removal %https://www.oreilly.com/library/view/80211ac-a-survival/9781449357702/ch02.html % csi_buff(:,230:234)=[]; csi_buff(:,124:134)=[]; csi_buff(:,245)=[]; csi_buff(:,235)=[]; csi_buff(:,207)=[]; csi_buff(:,171)=[]; csi_buff(:,143)=[]; csi_buff(:,120:123)=[]; csi_buff(:,104)=[]; csi_buff(:,76)=[]; csi_buff(:,40)=[]; csi_buff(:,12)=[]; csi_buff(:,1:5)=[]; max_csi=max(core); if(max_csi==0) antenna_1=csi_buff(core==0,:); csi_data=[antenna_1]; elseif(max_csi==1) antenna_1=csi_buff(core==0,:); antenna_2=csi_buff(core==1,:); csi_data=[antenna_1,antenna_2]; elseif(max_csi==2) antenna_1=csi_buff(core==0,:); antenna_2=csi_buff(core==1,:); antenna_3=csi_buff(core==2,:); % time_stamp=time_stamp(core==2); % time_stamp=typecast(time_stamp,'double'); time_stamp=sort(time_stamp); if (length(antenna_1)~=length(antenna_2)~=length(antenna_3)) xx=min([length(antenna_1),length(antenna_2),length(antenna_3)]); antenna_1(xx:end,:)=[]; antenna_2(xx:end,:)=[]; antenna_3(xx:end,:)=[]; % time_stamp(xx:end)=[]; end csi_data=[antenna_1,antenna_2,antenna_3]/128; % fc = 80; % fs = 2312.5e3; % [b,a] = butter(6,fc/(fs/2)); % csi_data = filter(b,a,csi_data); else antenna_1=csi_buff(core==0,:); antenna_2=csi_buff(core==1,:); antenna_3=csi_buff(core==2,:); antenna_4=csi_buff(core==3,:); csi_data=[antenna_1,antenna_2,antenna_3,antenna_4]; end x=length(csi_data)1e-3; time_stamp=linspace(double(min(time_stamp)),double(max(time_stamp))+x*1e6,length(csi_data))'; ind1= find(time_stamp==0); time_stamp(ind1)=[];

% deivice orientation c=299792458; tx_loc=[0;0]; rx_loc=[1.5;0]; sample_rate=1000; xb=[0,1.5]; yb=[0,10]; carrier_frequency=5.785e9; save('D:\Widar2\exp\T05.mat','csi_data','time_stamp'); save('D:\Widar2\exp\device_config.mat','c','carrier_frequency','rx_loc','sample_rate','tx_loc','xb','yb');

fatihoezdemir commented 4 years ago

Hello @salmanpolito , I am also trying to sanitize the CSI, but it seems that there are many things to do to sanitize it. Can you help me with it ? can you write a mail to me fatihoezdemir@tum.de ? Thank you

salmanpolito commented 4 years ago

Hello @salmanpolito , I am also trying to sanitize the CSI, but it seems that there are many things to do to sanitize it. Can you help me with it ? can you write a mail to me fatihoezdemir@tum.de ? Thank you

Hi, How about using the Widar2.0 way. They are removing the time offset and frequency offset using the spacial domain. BTW, I have checked the output from ASUS RT-AC86U using the above code (which I have made pilot and dc subcarrier free), and it is quite ok.

wen-young commented 4 years ago

loc'

hello salmanpolito, i see that you are working on WIDAR2.0 project, i'm too. But i have met a problem, the estimated rTOF is always negative, it lead in the range is always a constant , i really have no idea ,have you met this problem?

salmanpolito commented 4 years ago

loc'

hello salmanpolito, i see that you are working on WIDAR2.0 project, i'm too. But i have met a problem, the estimated rTOF is always negative, it lead in the range is always a constant , i really have no idea ,have you met this problem?

Hi @wen-young Thanks for your reply. I also have the same issue and trying to resolve it. Can you send me a personal email? "melleniumster@gmail.com". Lets work together on it !

zel602 commented 4 years ago

loc'

hello salmanpolito, i see that you are working on WIDAR2.0 project, i'm too. But i have met a problem, the estimated rTOF is always negative, it lead in the range is always a constant , i really have no idea ,have you met this problem?

I think maybe the phase difference caused by tof is more than π,rx and tx is out of sync

zel602 commented 4 years ago

loc'

hello salmanpolito, i see that you are working on WIDAR2.0 project, i'm too. But i have met a problem, the estimated rTOF is always negative, it lead in the range is always a constant , i really have no idea ,have you met this problem?

Hi @wen-young Thanks for your reply. I also have the same issue and trying to resolve it. Can you send me a personal email? "melleniumster@gmail.com". Lets work together on it !

Thanks for sharing your program,I want to ask a question,the core and rsxx to acquire CSI has been setted in advance,can we just get the CSI stream for the particular Antenna sequentially?Looking forward to having more communication with you

salmanpolito commented 4 years ago

sequentially You can select the core and rsxx in "makecsiparam". just chose a hexadecimal code for choosing a particular antenna. for instance, you want to choose the first antenna, set the value of core as 1 (0001), if the first and second antenna then set it as 3 (0011), and so on.

zel602 commented 4 years ago

sequentially You can select the core and rsxx in "makecsiparam". just chose a hexadecimal code for choosing a particular antenna. for instance, you want to choose the first antenna, set the value of core as 1 (0001), if the first and second antenna then set it as 3 (0011), and so on.

Thank you for your answer!May I ask you another question,for the Asus RT-AC86U,how does the core number in "makecsiparam" and physical core in the device correspond?

salmanpolito commented 4 years ago

sequentially You can select the core and rsxx in "makecsiparam". just chose a hexadecimal code for choosing a particular antenna. for instance, you want to choose the first antenna, set the value of core as 1 (0001), if the first and second antenna then set it as 3 (0011), and so on.

Thank you for your answer!May I ask you another question,for the Asus RT-AC86U,how does the core number in "makecsiparam" and physical core in the device correspond?

I think there is a detailed issue for this. RT-AC86U has four antennas. Three are external antennas and one antenna is hidden in the cover. For each antenna, there is a separate core to control its transmission and reception. When you chose a specific core, it means that you are using the corresponding antenna related to that core.

Dr-Yongqiang commented 4 years ago

路由器 I think zel may want to ask the core values of the four antennas of the router. For example, in the figure, antenna 1 corresponds to the core = 0x0001? This is just an example, and I also want to know the correct answer.Thanks! @DanielAW @derfalx @schmittner @qtux @Kjili