%% 802.11 OFDM Beacon Receiver with Captured Data
%
% This example shows a receiver design that is able to recover 802.11(TM)
% OFDM beacon packets in non-HT format transmitted over the air from
% commercial 802.11 hardware. Beacon packets are typically transmitted in
% non-HT format, even for HT [ <#9 1> ], VHT [ <#9 1> ], and/or HE [ <#9 2>
% ] capable hardware. Packet information such as SSID is printed to the
% command-line during recovery.

% Copyright 2015-2019 The MathWorks, Inc.

%% Introduction
% This example illustrates the use of WLAN Toolbox(TM) to recover
% real-world signals. It demonstrates a receiver design including
% synchronization, transmission configuration recovery, and payload
% decoding for non-HT packets. The example recovers beacon
% packets from a file containing a captured baseband waveform.

%% Beacon Packet Recovery
% The following steps happen sequentially to recover one non-HT packet:
% 
% * Packet Detection: First a packet must be detected before any processing
% begins. This is accomplished by auto-correlating input symbols. Since the
% front of each 802.11 OFDM packet contains a repetitive structure called
% the L-STF, peaks will occur in the correlation when this packet is
% present. The L-STF field is then extracted and used for coarse frequency
% estimation.
% 
% * Symbol Timing: Once a packet has been detected, future symbols will be
% collected and cross-correlated to locate the L-LTF. The resulting
% correlation peaks provide an accurate timing estimate. Once the full
% L-LTF is located, it is extracted and used for channel estimation and
% fine frequency estimation.
%
% * L-SIG Decoding: The first OFDM symbol after the L-LTF is the L-SIG
% field. This field must be recovered and decoded to determine the
% modulation, code rate, and length of the following payload. The
% information is used to capture the correct amount of data after the L-SIG
% for the complete payload and to decode that information.
% 
% * Payload Decoding: All OFDM symbols after the L-SIG are buffered to a
% length determined by the L-SIG field. After all the symbols have been
% captured they are demodulated and decoded into their source bits. The
% source bits are then evaluated. This evaluation includes frame check
% sequence (FCS) validation and extraction of the header and body. If the
% packet is of subtype beacon, summary information such as SSID will be
% printed for the recovered packet.
% 
% Once a full packet is received or any failures occur during the
% processing chain, the receiver will return to packet detection to search
% for more packets. This process is repeated for the duration of the
% signal.

%% Streaming Process on Captured Data
% In this example an off-the-air capture is processed to recover beacon
% frames. A Wi-Fi(R) signal was captured using an RF interface with one
% receive antenna at a sampling rate of 20 Msps. The captured waveform is
% stored in a binary baseband file. The file was created using
% <docid:comm_ref#bvby020-1 comm.BasebandFileWriter>.
%
% The captured waveform is processed in a streaming fashion. A block of
% samples is pulled in for processing in each iteration. As many valid
% packets are retrieved as possible. <docid:comm_ref#bvbbo5v-1
% comm.BasebandFileReader> is used to read blocks of samples from the
% binary baseband file.

% Create an object to stream the data from the file
basebandReader = comm.BasebandFileReader( ...
    'Filename',       'nonHTBeaconRxData.bb', ...
    'SamplesPerFrame', 80); % Number of samples in 1 OFDM symbol at 20 MHz

%%
% The center frequency, sample rate and number of channels in the captured
% waveform are provided by the comm.BasebandFileReader object.

disp(['Center frequency: ' num2str(basebandReader.CenterFrequency/1e6) ' MHz'])
disp(['Sample rate: ' num2str(basebandReader.SampleRate/1e6) ' Msps'])
disp(['Number of receive antennas: ' num2str(basebandReader.NumChannels) newline])

%%
% A <matlab:edit('nonHTFrontEnd.m') nonHTFrontEnd> object performs
% front-end processing and L-SIG decoding. The object is configured with a
% channel bandwidth of 20 MHz to process non-HT packets. Only one receive
% antenna is supported.
rxFrontEnd = nonHTFrontEnd('ChannelBandwidth', 'CBW20');  

%%
% A while loop is used to process blocks of samples and recover beacon
% packets until no more data is available in the baseband file. In each
% iteration of the loop a block of samples is read from the baseband file
% and is processed by |rxFrontEnd|. |rxFrontEnd| performs front-end
% processing and buffers samples until a packet has been detected and the
% payload received. When |payloadFull| is true, the full payload has been
% buffered and |rxFrontEnd| returns variables to allow the data within the
% packet to be recovered:
%
% * |cfgNonHT| contains the recovered packet parameters from L-SIG.
% * |rxNonHTData| is the time-domain non-HT data field signal.
% * |chanEst| contains the channel estimates obtained from the L-LTF.
% * |noiseVar| is the fixed noise variance value.
%
% The packet payload bits are recovered from the non-HT data field samples
% using <docid:wlan_ref#bu0lycd-1 wlanNonHTDataRecover>. The bits are then
% validated and decoded by <docid:wlan_ref#mw_function_wlanMPDUDecode
% wlanMPDUDecode> to recover the MAC frame parameters.
% <docid:wlan_ref#mw_function_wlanMPDUDecode wlanMPDUDecode> returns the
% following outputs that determine whether the received packet passed FCS
% check and whether the received packet is a beacon frame.
% 
% * |mpduCfg| is an object of type
% <docid:wlan_ref#mw_a004c76e-748e-42b5-84b2-360a063ea1f9
% wlanMACFrameConfig> containing the recovered MAC frame parameters from
% the beacon frame.
% * |status| is an enumeration of type
% <docid:wlan_ref#mw_025b5c9d-f00c-42d7-9dd5-c32f632ed43b
% wlanMACDecodeStatus> which is returned as 'Success' when MPDU passes
% FCS check and returned as 'FCSFailed' when the MPDU fails FCS check.
%
% If a valid beacon is detected, the decoded SSID is displayed.

% Symbol-by-symbol streaming process
numValidPackets = 0;
while ~isDone(basebandReader)
    % Pull in one OFDM symbol, i.e. 80 samples
    data = basebandReader();
    
    % Perform front-end processing and payload buffering
    [payloadFull, cfgNonHT, rxNonHTData, chanEst, noiseVar] = ...
        rxFrontEnd(data);
    
    if payloadFull        
        % Recover payload bits with zero-forcing equalization
        recBits = wlanNonHTDataRecover(rxNonHTData, chanEst, ...
            noiseVar, cfgNonHT, 'EqualizationMethod', 'ZF');
        
        % Decode and evaluate recovered bits
        [mpduCfg, ~, status] = wlanMPDUDecode(recBits, cfgNonHT);
        if strcmp(status, 'Success') && strcmp(mpduCfg.FrameType, 'Beacon')
            frameBody = mpduCfg.ManagementConfig; % Display SSID
            disp(['SSID: ', frameBody.SSID])
            numValidPackets = numValidPackets + 1;
        end
    end
end

disp([num2str(numValidPackets), ' Valid Beacon Packets Found'])

release(basebandReader);
release(rxFrontEnd);

%% Further Exploration
% See <docid:wlan_ug#example-sdruwlanofdm80211BeaconRx 802.11 OFDM
% Beacon Receiver with USRP Hardware> for an example of processing live
% signals with USRP.

%% Appendix
% This example uses the following helper functions and objects:
%
% * <matlab:edit('nonHTFrontEnd.m') nonHTFrontEnd.m>

%% Selected Bibliography
% # IEEE(R) Std 802.11(TM)-2016 IEEE Standard for Information technology -
% Telecommunications and information exchange between systems - Local and
% metropolitan area networks - Specific requirements - Part 11: Wireless
% LAN Medium Access Control (MAC) and Physical Layer (PHY) Specifications.
% # IEEE P802.11ax(TM)/D4.1 Draft Standard for Information technology -
% Telecommunications and information exchange between systems Local and
% metropolitan area networks - Specific requirements Part 11: Wireless LAN
% Medium Access Control (MAC) and Physical Layer (PHY) Specifications -
% Amendment 6: Enhancements for High Efficiency WLAN.