%% Skript pro simulaci fyzicke vrstvy IEEE 802.11n

close all
clearvars
clear global
clc

tic
%% define some parameters ----------------------------------------
wifi_standard = '802dot11ac';

CH_BANDWIDTH = 'CBW20';

GuardInterval = 'normal'; % 'short', 'normal', 'doubled'
coding_type = 'BCC'; % 'BCC' or 'LDPC'
decision_type = 'LLR'; %'HD' - Hard decision values; 'LLR' - Log-likelihood ratio(LLR);


SpatialStreams = 1:4;
includeSTBC = false;



LENGTH_vec = 1004; % pocet oktetu uzivatelskych dat (0--65535)

% MCSvec = [0 1];
MCSvec = 1:9;

%% define simulation parameters -------------------------------------------
channelType = 'awgn'; % 'awgn' or 'fad'
eqType = 'ideal'; %ideal, linear, polynom

SNR = -5:0.5:25;

N_frames = 100; % the number of frames within inner loop (for each SNR value)

single = true; % no parallel computing (for now)

showPlots = 1;
showMapping = 0;

calc_round = 0;


for i_length = 1:length(LENGTH_vec)
    
    
    if includeSTBC == true
        if any(SpatialStreams < 5)
            SpatialStreams = SpatialStreams(SpatialStreams<5);
            
            warning(strcat('Setting may changed. Simulation only for streams:',[' ' num2str(SpatialStreams)]));
        else
            includeSTBC = false;
            warning('includeSTBC was turned off');
        end
    end

    
    LENGTH = LENGTH_vec(i_length); % LENGTH parameter defines the number of octets in DATA field in a frame, LENGTH = {0; 65535}
    OnlyOne = false;
    
    error_val = zeros(N_frames,length(SNR),length(MCSvec),length(SpatialStreams)); % initialize error values (rewrite using OOP) %%%%%%%%%
    
    
    
    for i_N_ss = 1:length(SpatialStreams)
        for i_mcs = 1:length(MCSvec) % smycka promennych parametru (viz batch file)
            
            LENGTH = LENGTH_vec(i_length);
%             load_wifi_params;
%             PSDU_test = ((wifi_params.MCS(i_mcs).CR^(-1))*(LENGTH*8 + wifi_params.mapping.service_length + wifi_params.coding.tail_length + wifi_params.coding.N_pad_bits ));%/MCS.N_ss;
%         
%             while or((rem(PSDU_test,SpatialStreams(i_N_ss))~=0),(rem((PSDU_test/SpatialStreams(i_N_ss)),wifi_params.MCS(i_mcs).N_cbps) ~=0))
%         
%                 LENGTH = LENGTH+1
%                 load_wifi_params;
%                 PSDU_test = ((wifi_params.MCS(i_mcs).CR^(-1))*(LENGTH*8 + wifi_params.mapping.service_length + wifi_params.coding.tail_length + wifi_params.coding.N_pad_bits));%/MCS.N_ss;
% 
%             end

            disp(['-----------------------------------------------------------------'])
            load_wifi_params;

            disp([wifi_standard,' > ',coding_type,', ',wifi_params.MCS(i_mcs).MCS,', M = ',num2str(wifi_params.MCS(i_mcs).M),', CR = ',sprintf('%2.2f',wifi_params.MCS(i_mcs).CR),', ',num2str(wifi_params.MCS(i_mcs).N_ss),' Spatial stream(s)']);
            disp(['-----------------------------------------------------------------'])
            
            if (OnlyOne == false)
            % preallocate result variables
            results = result_allocation(SNR,N_frames,wifi_params,SpatialStreams,MCSvec);
            else
            %New data rate
            results.data_rate_PSDU = wifi_params.data_rate_PSDU;
            results.data_rate = wifi_params.data_rate;   
            end
            
            OnlyOne = true;
            
            
            sim_file;
            


            results = result_all(results, i_N_ss, i_mcs);

            % generate results file filename
            output_filename = load_filename2(SNR,N_frames,MCSvec(i_mcs),wifi_params,wifi_standard, CH_BANDWIDTH, coding_type, LENGTH, GuardInterval, decision_type);
            filename_suffix = [];
            save(fullfile('./results',[output_filename filename_suffix '.mat']));

        end % mcs loop
    end %end Spatial Stream loop
    
end % LENGTH loop

%% simulation results presentation

%save_result
    
    file_name = strcat(channelType,'+',wifi_params.general.eqType,'+',num2str(includeSTBC),'.mat');
    save(file_name);
    
    
    results.SNR = SNR;
   
    
   
    for i_N_ss = 1:length(SpatialStreams)
            
                     
            for i_mcs = 1:length(MCSvec)
                figure (1);
                subplot(length(SpatialStreams),1,i_N_ss);
                
                color_line = [0:6 0:6];
                color_line = de2bi(color_line(i_mcs),3);
                marker_line = ['*' '*' '*' '*' '*' '*' '*' 'o' 'o' 'o' 'o' 'o' 'o' 'o'];
                
                lgnd = strcat({'BER PSDU for '},wifi_params.MCS(i_mcs).MCS); 
                semilogy(SNR,results.ber_PSDU(1,:,i_N_ss,i_mcs),'Color',color_line,'LineStyle','-','Marker',marker_line(i_mcs),'DisplayName',lgnd)
                hold on
                
                
                %color_line = randi(7);
                %color_line = de2bi(color_line,3);
                figure (2);
                subplot(length(SpatialStreams),1,i_N_ss); 
                
                lgnd = strcat({'FER PSDU for '},wifi_params.MCS(i_mcs).MCS);
                semilogy(SNR,results.fer_frames_PSDU(1,:,i_N_ss,i_mcs),'Color',color_line,'LineStyle','-','Marker',marker_line(i_mcs),'DisplayName',lgnd)
                hold on
                
                figure (3);
                subplot(length(SpatialStreams),1,i_N_ss);
                
                lgnd = strcat({'Throughput PSDU for '},wifi_params.MCS(i_mcs).MCS);
                plot(SNR,(results.throughput_PSDU(1,:,i_N_ss,i_mcs)./10^6),'Color',color_line,'LineStyle','-','Marker',marker_line(i_mcs),'DisplayName',lgnd)
                hold on
                
            end   
            figure (1);
            if strcmp(channelType,'fad')
            EbN0Lin = 10.^(SNR/10);
            theoryBer = 0.5.*(1-sqrt(EbN0Lin./(EbN0Lin+1)));
            lgnd = strcat({'Theoretical BER for Rayling channel'});
            
            else 
               
            theoryBer = 0.5*erfc(sqrt(1*10.^(SNR/10)));
            lgnd = strcat({'Theoretical BER for AWGN channel'});
            end
            
            semilogy(SNR,theoryBer,'Color','blue','LineStyle',':','DisplayName',lgnd);
            
            axis([SNR(1) SNR(end) 10^(-8) 1])
            grid on
            xlabel('SNR [dB]')
            ylabel('BER [-]')
            lgnd = legend('show');
            title(['BER vs SNR for ',num2str(SpatialStreams(i_N_ss)),' spatial stream(s)'])
          
            figure (2);
            axis([SNR(1) SNR(end) 10^(-3) 1])
            grid on
            xlabel('SNR [dB]')
            ylabel('FER [-]')
            lgnd = legend('show');
            title(['FER vs SNR for ',num2str(SpatialStreams(i_N_ss)),' spatial stream(s)'])
            
            figure (3);
            axis([SNR(1) SNR(end) 10^(0) 10^(2)])
            grid on
            xlabel('SNR [dB]')
            ylabel('Throughput [Mbit/s]')
            lgnd = legend('show');
            title(['Throughput vs SNR for ',num2str(SpatialStreams(i_N_ss)),' spatial stream(s)'])
            
    end
            hold off
           

t = toc;