function routerData = rfFingerprintingNonHTReceiver(routerData, rxSDR, Config)
%rfFingerprintingNonHTReceiver Decodes received WLAN Packets
%   RDATA = rfFingerprintingNonHTReceiver(RDATA, RX, CONF) uses PlutoSDR
%   recevier, RX, to receive WLAN packets based on the configuration, CONF.
%   The received beacon frame information for routers is appended to RDATA
%   and returned.

%   Copyright 2019 The MathWorks, Inc.

% Set up system
% Instantiate and configure all objects and structures for packet
% synchronization and decoding

% System info
SampleRate = 20e6; % Hz
SymbolLength = 80*Config.RadioInfo.OversamplingFactor; % Samples in 20MHz OFDM Symbol (FFT+CP)
FramesToCollect =...
  floor(SampleRate*Config.SimInfo.CaptureDuration/SymbolLength);

% Set up Front-End Packet Synchronizer
WLANFrontEnd = rfFingerprintingNonHTFrontEnd('ChannelBandwidth', 'CBW20');

decimator = dsp.FIRDecimator('DecimationFactor',Config.RadioInfo.OversamplingFactor);

% Collect symbols and search for packets
% Collect data from the radio one symbol at a time, constructing the packet
% out of these symbols.  Once a valid packet is captured, try to decode it.

for frame = 1:FramesToCollect
  
  data = step(rxSDR);
  data = decimator(data);
  
  % WLANFrontEnd will internally buffer input symbols to build full
  % packets.  The flag valid will be true when a complete packet is
  % captured.
  [valid, cfgNonHT, rxNonHTData, chanEst, noiseVar, LLTF] = WLANFrontEnd(data);
  
  
  % Decode when we have captured a full packet
  if valid
    % Decode payload to bits
    bits = wlanNonHTDataRecover(...
      rxNonHTData,...
      chanEst,...
      noiseVar,...
      cfgNonHT,...
      'EqualizationMethod', 'ZF');
    
    % Decode bits
    [cfgMAC, ~, decodeStatus] = wlanMPDUDecode(bits, cfgNonHT);
    
    if (decodeStatus == wlanMACDecodeStatus.Success) && strcmp(cfgMAC.FrameType, 'Beacon')
      
      MACAddress = convertCharsToStrings(cfgMAC.Address2);
      
      % Add new MACAddress to routerData
      routerIndex = find(strcmp([routerData.Routers.MACAddress], MACAddress), 1);
      if isempty(routerIndex)
        if routerData.NumRouters < length(routerData.Routers)
          routerData.NumRouters = routerData.NumRouters + 1;
          routerIndex = routerData.NumRouters;
          routerData.Routers(routerIndex).MACAddress = MACAddress;
        else
          break
        end
      end
      
      if routerData.Routers(routerIndex).NumFrames < Config.FramesPerRouter
        routerData.Routers(routerIndex).NumFrames = routerData.Routers(routerIndex).NumFrames+1;
        routerData.Routers(routerIndex).Data(:,routerData.Routers(routerIndex).NumFrames) = LLTF;
        fprintf('SSID: %s\n', convertCharsToStrings(cfgMAC.ManagementConfig.SSID));
        fprintf('MACAddress2: %s\n', MACAddress);
        fprintf('Packets Decoded: %d/%d\n',...
          routerData.Routers(routerIndex).NumFrames, Config.FramesPerRouter);
        
        disp("max(abs(LLTF)) = " + num2str(max(abs(LLTF))))
        
        fprintf('---------------\n');
      end
    end
  end
end
end
