%hScanLTEWaveformParameterController Set values to the widgets
%   hScanLTEWaveformParameterController Updates fields of GUI widgets as
%   follows:
%
%   Signal source          - Updates the drop-down with: File, RTL-SDR,
%                            ADALM-PLUTO, USRP B200/B210, USRP N200/N210,
%                            USRP X300/X310, ZedBoard-FMC2/3/4, ZC706-FMC2/3/4
%   Signal file name       - Updates edit box with baseband file (*.bb)
%   LTE frequency band     - Updates the drop-down with 44 LTE frequency
%                            bands and 'User defined frequency' options
%   User frequency (MHz)   - Updates edit box with user defined frequency
%   Frequency offset (ppm) - Updates edit box with user defined frequency
%                            offset
%   Information block type - Updates the drop-down with MIB and MIB & SIB1
%                            options

%   Copyright 2019-2020 The MathWorks, Inc.

classdef hScanLTEWaveformParameterController < matlab.System
    properties (SetObservable, Nontunable)
        %Set the default signal source parameter
        SignalSource = 'File'
    end
    properties (SetObservable, AbortSet, Nontunable)
        %Set all the default parameters in search settings panel
        SignalFilename = 'LTECaptures.bb'
        LTECenterFrequency = 'User defined frequency';%'1 / 2110-2171 MHz'
        LTECenterFrequencyRTLSDR = 'User defined frequency';%'5 / 869-894 MHz'
        UserDefinedFrequency = '[800,900]'
        FrequencyOffset = 0
        CellRecType = 'MIB'
        CellRecTypeRTLSDR = 'MIB'
        PlotRSMeasurements = false
        ReferenceMeasurementtype = 'RSRQ'
        RadioAddress
        RadioPlatform
        Browse
        FileCenterFrequency
    end
    properties (Dependent, SetAccess=private)
        SignalSourceType
    end
    properties(Hidden, Transient)
        LTECenterFrequencySet = matlab.system.internal.DynamicStringSet({'User defined frequency','1 / 2110-2171 MHz','2 / 1930-1990 MHz'....
            ,'3 / 1805-1880 MHz','4 / 2110-2155 MHz','5 / 869-894 MHz'...
            ,'6 / 875-885 MHz','7 / 2620-2690 MHz','8 / 925-960 MHz'...
            ,'9 / 1844.9-1879.9 MHz','10 / 2110-2170 MHz','11 / 1475.9-1495.9 MHz'...
            ,'12 / 729-746 MHz','13 / 746-756 MHz','14 / 758-768 MHz'...
            ,'15 / 2600-2620 MHz','16 / 2585-2600 MHz','17 / 734-746 MHz'...
            ,'18 / 860-875 MHz','19 / 875-890 MHz','20 / 791-821 MHz'...
            ,'21 / 1495.9-1510.9 MHz','22 / 3510-3590 MHz'...
            ,'23 / 2180-2200 MHz','24 / 1525-1559 MHz','25 / 1930-1995 MHz'...
            ,'26 / 859-894 MHz','27 / 852-869 MHz','28 / 758-803 MHz'...
            ,'29 / 717-728 MHz','30 / 2350-2360 MHz','31 / 462.5-467.5 MHz'...
            ,'32 / 1452-1496 MHz','33 / 1900-1920 MHz','34 / 2010-2025 MHz'...
            ,'35 / 1850-1910 MHz','36 / 1930-1990 MHz','37 / 1910-1930 MHz'...
            ,'38 / 2570-2620 MHz','39 / 1880-1920 MHz','40 / 2300-2400 MHz'...
            ,'41 / 2496-2690 MHz','42 / 3400-3600 MHz','43 / 3600-3800 MHz'...
            ,'44 / 703-803 MHz'});
        LTECenterFrequencyRTLSDRSet = matlab.system.internal.DynamicStringSet({'User defined frequency','5 / 869-894 MHz','6 / 875-885 MHz'...
            ,'8 / 925-960 MHz','11 / 1475.9-1495.9 MHz','12 / 729-746 MHz'...
            ,'13 / 746-756 MHz','14 / 758-768 MHz','17 / 734-746 MHz'...
            ,'18 / 860-875 MHz','19 / 875-890 MHz','20 / 791-821 MHz'...
            ,'21 / 1495.9-1510.9 MHz','24 / 1525-1559 MHz','26 / 859-894 MHz'});
        ReferenceMeasurementtypeSet =  matlab.system.internal.DynamicStringSet({'RSRQ','RSRP','RSSI'});
        CellRecTypeSet = matlab.system.internal.DynamicStringSet({'MIB','MIB & SIB1'});
        CellRecTypeRTLSDRSet = matlab.system.internal.DynamicStringSet({'MIB'});
        SignalSourceSet = matlab.system.internal.DynamicStringSet({'File','RTL-SDR',...
            'ADALM-PLUTO','USRP-B200/B210','USRP-N200/N210','USRP-X300/X310','ZedBoard-FMC2/3/4','ZC706-FMC2/3/4'});
    end
    methods
        function obj = hScanLTEWaveformParameterController(varargin)
            setProperties(obj, nargin, varargin{:});
        end
        function set.SignalSource(obj, aSource)
            % Set selected signal source
            greyViewer(obj.Viewer,'off');
            if strcmp(aSource, 'File') % File
                obj.SignalSource = aSource;
            else % Hardware
                h = waitbar(0.5,'Checking for Hardware Support Package....','WindowStyle','modal','Name','HSP Check');
                h.CloseRequestFcn = '';
                %Check for hardware support package
                HSPInstalled = hScanLTEWaveformHSPCheck(aSource);
                if HSPInstalled
                    waitbar(1,h);
                    h.CloseRequestFcn = 'closereq';
                    close(h);
                    if any(strcmp(aSource,{'ZC706-FMC2/3/4','ZedBoard-FMC2/3/4'}))
                        % Interface for providing IP address
                        answer = inputdlg('IP Address:',...
                            'Provide Zynq Radio IP Address', [1 60],{'192.168.3.2'});
                        % Validate IP address
                        ipFlag = false;
                        try
                            ipAdd = answer{1};
                            zynqradioshared.internal.checkIPAddressFormat(ipAdd);
                        catch
                            ipFlag = true;
                        end
                        if ipFlag
                            obj.SignalSource = '';
                            errordlg('Please provide a valid IP address formed of 4 numbers separated by three dots','Invalid IP Address','Modal');
                            return;
                        end
                    else
                        ipAdd = [];
                    end
                    k = waitbar(0.5,'Checking for radio connections....','WindowStyle','modal','Name','Radio Connection Check');
                    k.CloseRequestFcn = '';
                     %Check for Radio connectivity
                    [radioFound, radioInfo] = hScanLTEWaveformRadioConnectivityCheck(aSource,ipAdd);
                    if radioFound
                        waitbar(1,k);
                        k.CloseRequestFcn = 'closereq';
                        close(k);
                        obj.SignalSource = aSource;
                        updateRadioInfo(obj,radioInfo);
                    else
                        k.CloseRequestFcn = 'closereq';
                        close(k);
                        obj.SignalSource = '';
                        if any(strcmp(aSource,{'ZC706-FMC2/3/4','ZedBoard-FMC2/3/4'}))                            
                            message = ['Unable to find ', num2str(aSource),...
                                ' radio, please verify the hardware setup from',...
                                ' Guided Host-Radio Setup documentation under',...
                                ' Communications Toolbox Support Package for Xilinx Zynq-Based Radio.'];
                        else
                            message = ['Unable to find ', num2str(aSource),'. Check your radio connection and try again.'];
                        end
                        errordlg(message,'Radio Connection-Error','Modal');
                        return;
                    end
                else
                    h.CloseRequestFcn = 'closereq';
                    close(h);
                    obj.SignalSource = '';
                    % Update Error dialog box if required support package is not available
                    message = ['MATLAB support package for ',num2str(aSource),' is not installed.'];
                    errordlg(message,'Support Package-Error','Modal');
                    return;
                end
            end
        end
        function aType = get.SignalSourceType(obj)
            % Get selected signal source
            switch obj.SignalSource
                case 'File'
                    aType = hScanLTEWaveformSourceType.Captured;
                case 'RTL-SDR'
                    aType = hScanLTEWaveformSourceType.RTLSDRRadio;
                case 'ADALM-PLUTO'
                    aType = hScanLTEWaveformSourceType.PlutoSDRRadio;
                case 'USRP-B200/B210'
                    aType = hScanLTEWaveformSourceType.USRPBRadio;
                case 'USRP-N200/N210'
                    aType = hScanLTEWaveformSourceType.USRPNRadio;
                case 'USRP-X300/X310'
                    aType = hScanLTEWaveformSourceType.USRPXRadio;
                case 'ZC706-FMC2/3/4'
                    aType = hScanLTEWaveformSourceType.ZC706Radio;
                case 'ZedBoard-FMC2/3/4'
                    aType = hScanLTEWaveformSourceType.ZedRadio;
            end
        end
        function set.SignalFilename(obj, aFilename)
            % Set signal file name value
            greyViewer(obj.Viewer,'off');
            [~,~,ext] = fileparts(aFilename);
            % Check whether .bb file is provided or not
            if ((~(strcmp(ext,'.bb')))||(isempty(ext)))
                ME.message = 'Invalid baseband file.';
                errordlg(ME.message,'Baseband File-Error','Modal');
                obj.SignalFilename = '';
            else
                obj.SignalFilename = aFilename;
            end
        end
        function set.LTECenterFrequency(obj,aLTEFrequency)
            % Set selected LTE frequency band value
            greyViewer(obj.Viewer,'off');
            obj.LTECenterFrequency = aLTEFrequency;
        end
        function set.LTECenterFrequencyRTLSDR(obj,aLTECenterFrequencyRTLSDR)            
            % Set selected LTE frequency band value specific to RTL SDR
            greyViewer(obj.Viewer,'off');
            obj.LTECenterFrequencyRTLSDR = aLTECenterFrequencyRTLSDR;
        end
        function set.UserDefinedFrequency(obj,aUserDefinedfrequency)
            % Set user defined frequency value
            greyViewer(obj.Viewer,'off');
            try
                obj.UserDefinedFrequency = '';
                dummy_freq = transpose(eval(aUserDefinedfrequency));
                band = dummy_freq(:)';
                if ((isempty(band))||(ischar(band)))
                    message = 'Provide valid user frequency.';
                elseif (size(dummy_freq,2) > 2)
                    message = 'You can provide up to 2 different frequency ranges.';
                elseif any(band<0)
                    message = 'Frequency cannot be negative.';
                elseif ((strcmp(obj.SigSrcType, 'RTLSDRRadio'))&&(band(end)>1559))
                    message = 'Provide LTE frequencies less than 1560 MHz for RTL-SDR.';
                elseif ((band(1)<700)||(band(end)>3800))
                    message = 'LTE frequencies are expected to be in the range from 700 MHz to 3800 MHz.';
                elseif any(rem(band(:),0.1))
                    message = 'User frequency should be multiple of 100 kHz.';
                elseif (size(dummy_freq,2) == 1)
                    if(band(end)<band(1))
                        message = 'Provide range starting from low to high frequency.';
                    else
                        obj.UserDefinedFrequency = aUserDefinedfrequency;
                    end
                elseif (size(dummy_freq,2) == 2)
                    bandCheck = (band(1)<=band(2)) && (band(2)<=band(3)) && (band(3)<=band(end));
                    if ~bandCheck
                        message = 'Provide range starting from low to high frequency.';
                    else
                        obj.UserDefinedFrequency = aUserDefinedfrequency;
                    end                    
                else
                    obj.UserDefinedFrequency = aUserDefinedfrequency;
                end
                if isempty(obj.UserDefinedFrequency)
                    errordlg(message,'User Defined Frequency-Error','Modal');
                end
            catch ME
                obj.UserDefinedFrequency = '';
                errordlg(ME.message,'User Defined Frequency-Error','Modal');
                return;
            end
        end
        function set.FrequencyOffset(obj,aFrequencyOffset)
            % Set Frequency offset parameter value
            greyViewer(obj.Viewer,'off');
            try
                obj.FrequencyOffset = '';
                dummy_offset = transpose(evalin('base',aFrequencyOffset));
                if ~(numel(dummy_offset) == 1)
                    message = 'Frequency offset value must be a scalar.';
                elseif ((isempty(dummy_offset))||(ischar(dummy_offset)))
                    message = 'Provide valid frequency offset value.';
                elseif ((dummy_offset<-1e4)||(dummy_offset>1e4))
                    message = 'Frequency offset value should be with in the range [-1e4 1e4].';
                else
                    obj.FrequencyOffset = dummy_offset;
                end
                if(isempty(obj.FrequencyOffset))
                    errordlg(message,'Frequency Offset-Error','Modal');
                end
            catch ME
                obj.FrequencyOffset = '';
                errordlg(ME.message,'Frequency Offset-Error','Modal');
                return;                
            end
        end
        function set.CellRecType(obj,aCellRecType)
            % Set Information block type value
            greyViewer(obj.Viewer,'off');
            obj.CellRecType = aCellRecType;
        end
        function set.CellRecTypeRTLSDR(obj,aCellRecTypeRTLSDR)
            % Set Information block type value for RTL SDR only MIB
            greyViewer(obj.Viewer,'off');
            obj.CellRecTypeRTLSDR = aCellRecTypeRTLSDR;
        end
    end
    methods (Access = private)
        function updateRadioInfo(obj,radioInfo)
            %Update radio related parameters
            if strcmp(obj.SignalSource,'RTL-SDR')
                obj.RadioAddress = radioInfo.RadioAddress;
                obj.RadioPlatform = 'RTL-SDR';
            elseif strcmp(obj.SignalSource,'ADALM-PLUTO')
                obj.RadioAddress = radioInfo.RadioID;
                obj.RadioPlatform = 'ADALM-PLUTO';
            elseif strcmp(obj.SignalSource,'USRP-B200/B210')
                for ii = 1:numel(radioInfo)
                    if any(strcmp(radioInfo(ii).Platform,{'B210','B200'}))
                        obj.RadioAddress = radioInfo(ii).SerialNum;
                        obj.RadioPlatform = radioInfo(ii).Platform;
                        break;
                    end
                end
            elseif strcmp(obj.SignalSource,'USRP-N200/N210')
                for ii = 1:numel(radioInfo)
                    if any(strcmp(radioInfo(ii).Platform,{'N200/N210/USRP2'}))
                        obj.RadioAddress = radioInfo(ii).IPAddress;
                        obj.RadioPlatform = radioInfo(ii).Platform;
                        break;
                    end
                end
            elseif strcmp(obj.SignalSource,'USRP-X300/X310')
                for ii = 1:numel(radioInfo)
                    if any(strcmp(radioInfo(ii).Platform,{'X310','X300'}))
                        obj.RadioAddress = radioInfo(ii).IPAddress;
                        obj.RadioPlatform = radioInfo(ii).Platform;
                        break;
                    end
                end
            elseif any(strcmp(obj.SignalSource,{'ZC706-FMC2/3/4','ZedBoard-FMC2/3/4'}))
                obj.RadioAddress = radioInfo.IPAddress;
                obj.RadioPlatform = radioInfo.DeviceName;
            end
        end
    end
    methods (Access=protected)
        function flag = isInactivePropertyImpl(obj, prop)
            % check whether the widgets in search settings panel should be
            % in active or not
            switch prop
                case 'CenterFrequencyUnit'
                    if strcmp(obj.SignalSource, 'File')
                        flag = true;
                    else
                        flag = false;
                    end
                case 'SignalFilename'
                    if strcmp(obj.SignalSource, 'File')
                        flag = false;
                    else
                        flag = true;
                    end
                case 'Browse'
                    if strcmp(obj.SignalSource, 'File')
                        flag = false;
                    else
                        flag = true;
                    end
                case 'UserDefinedFrequency'
                    if (strcmp(obj.SignalSource, 'RTL-SDR')&&(strcmp(obj.LTECenterFrequencyRTLSDR,'User defined frequency')))
                        flag = false;
                    elseif (any(strcmp(obj.SignalSource, {'ADALM-PLUTO','USRP-B200/B210',...
                            'USRP-N200/N210','USRP-X300/X310','ZC706-FMC2/3/4','ZedBoard-FMC2/3/4'}))...
                            &&(strcmp(obj.LTECenterFrequency,'User defined frequency')))
                        flag = false;
                    else
                        flag = true;
                    end
                case 'SignalSourceType'
                    flag = true;
                case 'LTECenterFrequency'
                    if (strcmp(obj.SignalSource, 'File'))||(strcmp(obj.SignalSource, 'RTL-SDR'))
                        flag = true;
                    else
                        flag = false;
                    end
                case 'LTECenterFrequencyRTLSDR'
                    if strcmp(obj.SignalSource, 'RTL-SDR')
                        flag = false;
                    else
                        flag = true;
                    end
                case 'FileCenterFrequency'
                    if strcmp(obj.SignalSource, 'File')
                        flag = false;
                    else
                        flag = true;
                    end
                case 'FrequencyOffset'
                    if any(strcmp(obj.SignalSource, {'RTL-SDR','USRP-B200/B210','USRP-N200/N210','USRP-X300/X310'}))
                        flag = false;
                    else
                        flag = true;
                    end
                case 'CellRecType'
                    if strcmp(obj.SignalSource, 'RTL-SDR')
                        flag = true;
                    else
                        flag = false;
                    end
                case 'CellRecTypeRTLSDR'
                    if strcmp(obj.SignalSource, 'RTL-SDR')
                        flag = false;
                    else
                        flag = true;
                    end
                otherwise
                    flag = false;
            end
        end
    end
end