%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%% Tecnologias de Acceso a Red %%%%%%%%%%%
%%%%%%%%          Practica ADSL            %%%%%%%%
%%%%%%%%%   Francisco J. Rodriguez Ruiz   %%%%%%%%%
%%%%%%%%%          Luca Martino           %%%%%%%%%
%%%%%%%%%%%      Curso 2012-2013        %%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%% ------------------------------ NOTA ------------------------------ %%%
% Este codigo se proporciona como base para la practica de Tecnologias   %
% de Acceso a Red. Puede emplearse sin modificacion alguna, aunque no es %
% obligatorio utilizarlo, sino que cada gupo puede hacer uso de la parte %
% que le convenga, o bien usar su propio codigo. Se suministra           %
% unicamente a modo de ayuda.                                            %
% En cualquier caso, es importante que los alumnos entiendan que         %
% funcionalidad tiene cada parte del codigo.                             %
%%% ------------------------------------------------------------------ %%%


clc
clear all
close all


%% 1) Parametros de configuracion:

N = 256;   % Numero total de subcanales
nu = 32;   % Longitud del prefijo ciclico

Kf = 224;  % Longitud de la trama rapida sin contar el FEC (en bytes)
Rf = 16;   % Longitud del campo FEC (en bytes)

% Definicion del canal:
H_del = [0 3 6 20];          % Retardos
H_att_dB = [0 -2 -8 -3];     % Atenuacion (en dB)
H_att = 10.^(H_att_dB/10);   % Atenuacion (en lineal)
H_pha = [1 1 -1 1];          % Fase (define el signo de cada coeficiente)
H = zeros(H_del(end)+1,1);       % Vector de ceros de la longitud adecuada
H(1+H_del)=H_att.*H_pha;         % Rellena con los valores de los coefic.

% Bit loading:
bn = zeros(N,1);
bn(33:N) = 2;


%% 2) Transmisor

Nsim = 100;          % Numero de simulaciones (elegir entre 50 y 100)
vec_SNR = 15:2:30;   % Vector de SNR's que se van a simular (en dB)
BER = zeros(1,length(vec_SNR));  % Vector para guardar la BER para cada SNR

% Para cada SNR:
for it_SNR=1:length(vec_SNR)
    
    SNR = 10^(vec_SNR(it_SNR)/10);  % SNR en escala lineal
    s2n = 1/SNR;                    % Varianza del ruido para la SNR actual
    
    % Realiza Nsim simulaciones:
    for it_sim = 1:Nsim
        
        %---CAPA DE ENLACE:
        
        % Fuente aleatoria:
        tx_frame = randint(1,8*Kf);  % Trama (de enlace) a transmitir
            % size(tx_frame) = [1, 1792]

        % Anade FEC (codif. Reed-Solomon):
        tx_frameFEC = FECcod(tx_frame,Rf);  % Trama codificada (240*8 bits)
                                            % *CREAR LA FUNCION FECcod(bits,Rf) %
            % size(tx_frameFEC) = [1, 1920]
        
        % Anade ceros para que el numero de bits sea multiplo de sum(bn):
        nZeros = sum(bn)-mod(length(tx_frameFEC),sum(bn));  % Numero de ceros
                                                            % que se deben anadir
        tx_frameFEC = [tx_frameFEC zeros(1,nZeros)];  % Ahora tx_frameFEC puede
                                                      % formar un numero entero
                                                      % de 'tramas fisicas'
            % size(tx_frameFEC) = [1, 1920+nZeros]

        % Aleatorizador:
        tx_rnd = aleatoriz(tx_frameFEC);    % Trama aleatorizada
                                            % *CREAR LA FUNCION aleatoriz(bits) %
            % size(tx_rnd) = [1, 1920+nZeros]
                                            
                                            
        %---CAPA FISICA:
        
        % Para cada simbolo DMT (e.d., para cada 'trama fisica'):
        nSimb = length(tx_rnd)/sum(bn);   % Numero de simbolos DMT
        tx_sec = zeros((2*N+nu)*nSimb,1);  % Inicializa el vector de simb.
                                           % que se enviaran al canal (en
                                           % total, 2N+nu valores por cada
                                           % simbolo DMT)
            % size(tx_sec) = [(2N+nu)*nSimb,  1]
            
        % Para cada simbolo DMT:
        for it_simb=1:nSimb
            
            % Selecciona los bits adecuados de tx_rnd:
            tx_simb = tx_rnd(1+sum(bn)*(it_simb-1):it_simb*sum(bn));
               % size(tx_simb) = [1, sum(bn)]
            
            % Conversor S/P:
            tx_simb = se2pa(tx_simb,bn);
                                            % *CREAR LA FUNCION se2pa(bits,bn) %
               % size(tx_simb) = [N, max(bn)]

            % Codificador QAM:
            tx_simb = qamEnc(tx_simb,bn);
                                            % *CREAR LA FUNCION qamEnc(bits,bn) %
               % size(tx_simb) = [N, 1]

            % Espejo de datos e IFFT:
            tx_simb = mirr_IFFT(tx_simb);
                                            % *CREAR LA FUNCION mirr_IFFT(bits) %
               % size(tx_simb) = [2N, 1]

            % Anade prefijo ciclico:
            tx_simbCP = addCP(tx_simb,nu);
                                            % *CREAR LA FUNCION addCP(bits,nu) %
               % size(tx_simbCP) = [2N+nu, 1]

            % Forma la secuencia de entrada al canal:
            tx_sec(1+(it_simb-1)*(2*N+nu):it_simb*(2*N+nu)) = tx_simbCP;
               % size(tx_sec) = [(2N+nu)*nSimb,  1]
        end


        %% 3) Canal discreto equivalente

        rx_sec = channel(tx_sec,H,s2n);
                                            % *CREAR LA FUNCION channel(bits,H,s2n) %
            % size(rx_sec) = [(2N+nu)*nSimb,  1]


        %% 4) Receptor

        rx_rnd = zeros(1,length(tx_rnd));  % Inicializa el vector de bits
                                           % recibidos en la capa de enlace
            % size(rx_rnd) = [1, 1920+nZeros]

        %---CAPA FISICA:
        
        % Para cada simbolo DMT:
        for it_simb=1:nSimb

            % Toma los valores apropiados de la secuencia recibida:
            rx_simbCP = rx_sec(1+(it_simb-1)*(2*N+nu):it_simb*(2*N+nu));
               % size(rx_simbCP) = [2N+nu, 1]

            % Elimina el prefijo ciclico:
            rx_simb = remCP(rx_simbCP,nu);
                                            % *CREAR LA FUNCION remCP(bits,nu) %
               % size(rx_simb) = [2N, 1]

            % Deshacer el espejo de datos y realizar la FFT:
            rx_simb = mirrRem_FFT(rx_simb);
                                            % *CREAR LA FUNCION mirrRem_FFT(bits) %
               % size(rx_simb) = [N, 1]

            % Ecualizacion en el dominio de la frecuencia (FEQ):
            rx_simb = feq(rx_simb,H);
                                            % *CREAR LA FUNCION feq(bits,H) %
               % size(rx_simb) = [N, 1]

            % Decodificador QAM:
            rx_bits = qamDec(rx_simb,bn);
                                            % *CREAR LA FUNCION qamDec(bits,bn) %
               % size(rx_bits) = [N, max(bn)]

            % Conversor P/S:
            rx_bits = pa2se(rx_bits,bn);
                                            % *CREAR LA FUNCION pa2se(bits,bn) %
               % size(rx_bits) = [1, sum(bn)]
            
            % Almacena los bits en la secuencia de la capa enlace recibida:
            rx_rnd(1+sum(bn)*(it_simb-1):it_simb*sum(bn)) = rx_bits;
               % size(rx_rnd) = [1, 1920+nZeros]
        end
        
        
        %---CAPA DE ENLACE:
        
        % Desaleatorizador:
        rx_frameFEC = aleatorizRem(rx_rnd);
                                            % *CREAR LA FUNCION aleatorizRem(bits) %
            % size(rx_frameFEC) = [1, 1920+nZeros]
                                            
        % Elimina los ceros que fueron anadidos artificialmente:
        rx_frameFEC = rx_frameFEC(1:end-nZeros);
            % size(rx_frameFEC) = [1, 1920]

        % Decodificacion Reed/Solomon:
        rx_frame = FECdecod(rx_frameFEC,Rf);
                                            % *CREAR LA FUNCION FECdecod(bits,Rf) %
            % size(rx_frame) = [1, 1792]
        
        % Medir la BER para la SNR actual:
        BER(it_SNR) = BER(it_SNR)+sum(rx_frame~=tx_frame)/(length(tx_frame)*Nsim);
                         % Se divide entre el numero total de bits, que es length(tx_frame)
                         % ... pero tambien entre Nsim, porque se esta promediando
                         %  para Nsim simulaciones
        
    end
end

%% 4) Dibuja las figuras correspondientes:

% ...

