mobisys2018_nexmon_channel_.../matlab/readcsi.m

217 lines
9.5 KiB
Matlab

%READCSI Extract and interpret CSI values.
% READCSI(BASE_FILENAME, SHOULD_SAVE, SHOULD_PLOT) opens the
% BASE_FILENAME.pcap to extract channel state information (CSI) dumped
% using nexmon's CSI Extractor firmware patch. If SHOULD_SAVE is 1,
% extracted values will be written to BASE_FILENAME.mat. If SHOULD_PLOT
% is 1, then CSI values will directly be plotted.
%
% Payload format:
% 14 byte: Ethernet header
% 20 byte: IPv4 header
% 8 byte: UDP header
% 4 byte: Magic String "CSIS"(0x43 0x53 0x49 0x53)
% 6 byte: HW address
% 4 byte: reserved
% 1020 byte: 255 CSI value pairs
%
% CSI value pair format:
% 2 byte: two's complement real
% 2 byte: two's complement imag
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% ########### ########### ########## ########## %
% ############ ############ ############ ############ %
% ## ## ## ## ## ## ## %
% ## ## ## ## ## ## ## %
% ########### #### ###### ## ## ## ## ###### %
% ########### #### # ## ## ## ## # # %
% ## ## ###### ## ## ## ## # # %
% ## ## # ## ## ## ## # # %
% ############ ##### ###### ## ## ## ##### ###### %
% ########### ########### ## ## ## ########## %
% %
% S E C U R E M O B I L E N E T W O R K I N G %
% %
% License: %
% %
% Copyright (c) 2018 Jakob Link, Matthias Schulz %
% %
% Permission is hereby granted, free of charge, to any person obtaining a %
% copy of this software and associated documentation files (the %
% "Software"), to deal in the Software without restriction, including %
% without limitation the rights to use, copy, modify, merge, publish, %
% distribute, sublicense, and/or sell copies of the Software, and to %
% permit persons to whom the Software is furnished to do so, subject to %
% the following conditions: %
% %
% 1. The above copyright notice and this permission notice shall be %
% include in all copies or substantial portions of the Software. %
% %
% 2. Any use of the Software which results in an academic publication or %
% other publication which includes a bibliography must include %
% citations to the nexmon project a) and the paper cited under b) or %
% the thesis cited under c): %
% %
% a) "Matthias Schulz, Daniel Wegemer and Matthias Hollick. Nexmon: %
% The C-based Firmware Patching Framework. https://nexmon.org" %
% %
% b) "Matthias Schulz, Jakob Link, Francesco Gringoli, and Matthias %
% Hollick. Shadow Wi-Fi: Teaching Smartphones to Transmit Raw %
% Signals and to Extract Channel State Information to Implement %
% Practical Covert Channels over Wi-Fi. Accepted to appear in %
% Proceedings of the 16th ACM International Conference on Mobile %
% Systems, Applications, and Services (MobiSys 2018), June 2018." %
% %
% c) "Matthias Schulz. Teaching Your Wireless Card New Tricks: %
% Smartphone Performance and Security Enhancements through Wi-Fi %
% Firmware Modifications. Dr.-Ing. thesis, Technische Universität %
% Darmstadt, Germany, February 2018." %
% %
% 3. The Software is not used by, in cooperation with, or on behalf of %
% any armed forces, intelligence agencies, reconnaissance agencies, %
% defense agencies, offense agencies or any supplier, contractor, or %
% research associated. %
% %
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS %
% OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF %
% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. %
% IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY %
% CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, %
% TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE %
% SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function csi_buff = readcsi(base_filename, should_save, should_plot)
%% parameters
% configure WLAN object and get parameters
cfgVHT = wlanVHTConfig; % legacy mode
%cfgVHT.Modulation = 'OFDM'; % OFDM
cfgVHT.ChannelBandwidth = 'CBW80'; % 20MHz
cfgVHT.MCS = 0; % BPSK 6Mbps
cfgVHT.NumTransmitAntennas = 1; % one antenna
FFTLength = helperFFTLength(cfgVHT); % get fft length
% get data, pilot, and null carrier indices
[dataIdx,pilotIdx] = helperSubcarrierIndices(cfgVHT,'VHT');
dpIdx = [dataIdx; pilotIdx];
nullIdx = 1:FFTLength;
nullIdx(dpIdx) = [];
%% helper
% anonymous function: sign extend and convert binary 14-bit-twocompl to int16
twos2dec = @(x) typecast(uint16(bin2dec(x)),'int16');
%% read file
p = readpcap();
p.open([base_filename '.pcap']);
%n = min(length(p.all()),100);
n = p.length();
p.from_start();
ts = zeros(n,1);
% matrix to store calculated csi for each packet
csi_buff = complex(zeros(n,FFTLength),0);
k = 1; % target matrix counter
% iterate over each packet
while (k <= n)
f = p.next();
if isempty(f)
disp('no more frames');
break;
end
if f.header.orig_len ~= 1076
continue;
end
ts(k) = double(f.header.ts_sec) + double(f.header.ts_usec) * 1e-6;
payload = f.payload;
% convert to binary
binary = dec2bin(payload,32);
%disp(dec2hex(payload(14),8))
% remove none-csi
binary = binary(15:end,:);
% extract imaginary and real parts
real_b = binary(:,1:16);
imag_b = binary(:,17:end);
% group to cells
real_b_cells = num2cell(real_b,2);
imag_b_cells = num2cell(imag_b,2);
% apply twos2dec for each cell
real_d = cellfun(twos2dec,real_b_cells);
imag_d = cellfun(twos2dec,imag_b_cells);
% build complex numbers
cmplx = complex(double(real_d), double(imag_d));
% throw away constant value at beginning
% and extract used carriers
if FFTLength <= 254
% for 20 and 40 MHz
cmplx_bw = fftshift(cmplx(2:FFTLength+1));
else
% exact format for 80 MHz currently unknown
% only 255 values in CSI UDP, but FFTLength is 256
cmplx_bw = fftshift([cmplx(1:FFTLength-1); 10000]);
end
% zero set null carriers
cmplx_bw(nullIdx) = 0.0;
% store csi
csi_buff(k,:) = cmplx_bw.';
k = k + 1;
end
%% save results
if (should_save)
save([base_filename '.mat'], 'csi_buff', '-v7.3');
end
%% plot
if (should_plot)
% y-Axis ticks and ticklabels for phase
ticky = [-180:45:180];
tickyL = {'-180','','-90','','0°', '', '90°', '', '180°'};
% x-Axis
x = -FFTLength/2:FFTLength/2-1;
for n = 1:size(csi_buff,1)
plot_chan = csi_buff(n,:);
figure(1);
% plot magnitude
subplot(2,1,1)
bha = bar(x,abs(plot_chan),'BarWidth',1);
set(bha,'FaceColor',[0 0 1])
set(bha,'EdgeColor',[0 0 0])
title('CSI Magnitude')
xlabel('Subcarrier Index')
ylabel('Magnitude')
grid on
myAxis = axis();
axis([min(x), max(x), myAxis(3), myAxis(4)])
% plot phase
subplot(2,1,2)
bha = bar(x,rad2deg(angle(plot_chan)),'BarWidth',1);
set(bha,'FaceColor',[1 0 0])
set(bha,'EdgeColor',[0 0 0])
title('CSI Phase')
xlabel('Subcarrier Index')
ylabel('Phase in °')
grid on
set(gca,'YTick',ticky)
set(gca,'YTickLabel',tickyL)
myAxis = axis();
axis([min(x), max(x), myAxis(3), myAxis(4)])
% wait for user input
waitforbuttonpress();
end
end
end