gusucode.com > vnt工具箱matlab源码程序 > vnt/vnt/+can/+ni/+xnet/Utility.m

    classdef (Hidden) Utility
% Utility Supporting functionality for toolbox operations.
%
%   This class implements internal functionality required for toolbox
%   operation. These methods are not intended for external use. 
%   Methods contained here are applicable to NI devices only.

% Authors: JDP
% Copyright 2013-2015 The MathWorks, Inc.

properties (Constant)
    % Session creation constants.
    USE_DEFAULT_DATABASE = ':memory:';
    USE_NO_CLUSTER = '';
    USE_NO_LIST = '';
    
    % Property ID session modes.
    nxMode_SignalInSinglePoint         = uint32(0);
    nxMode_SignalInWaveform            = uint32(1);
    nxMode_SignalInXY                  = uint32(2);
    nxMode_SignalOutSinglePoint        = uint32(3);
    nxMode_SignalOutWaveform           = uint32(4);
    nxMode_SignalOutXY                 = uint32(5);
    nxMode_FrameInStream               = uint32(6);
    nxMode_FrameInQueued               = uint32(7);
    nxMode_FrameInSinglePoint          = uint32(8);
    nxMode_FrameOutStream              = uint32(9);
    nxMode_FrameOutQueued              = uint32(10);
    nxMode_FrameOutSinglePoint         = uint32(11);
    nxMode_SignalConversionSinglePoint = uint32(12);
    
    % Property ID classes.
    nxClass_Database      = uint32(hex2dec('00000000'));
    nxClass_Cluster       = uint32(hex2dec('00010000'));
    nxClass_Frame         = uint32(hex2dec('00020000'));
    nxClass_Signal        = uint32(hex2dec('00030000'));
    nxClass_Subframe      = uint32(hex2dec('00040000'));
    nxClass_ECU           = uint32(hex2dec('00050000'));
    nxClass_LINSched      = uint32(hex2dec('00060000')); % LIN Schedule
    nxClass_LINSchedEntry = uint32(hex2dec('00070000')); % LIN Schedule Entry
    nxClass_PDU           = uint32(hex2dec('00080000'));
    nxClass_Session       = uint32(hex2dec('00100000'));
    nxClass_System        = uint32(hex2dec('00110000'));
    nxClass_Device        = uint32(hex2dec('00120000'));
    nxClass_Interface     = uint32(hex2dec('00130000'));
    nxClass_Alias         = uint32(hex2dec('00140000'));
    nxClass_Mask          = uint32(hex2dec('00FF0000'));

    % Property ID datatypes.
    nxPrptype_u32      = uint32(hex2dec('00000000'));
    nxPrptype_f64      = uint32(hex2dec('01000000'));
    nxPrptype_bool     = uint32(hex2dec('02000000')); % use u8 as datatype (semantic only)
    nxPrptype_string   = uint32(hex2dec('03000000'));
    nxPrptype_1Dstring = uint32(hex2dec('04000000')); % comma-separated list
    nxPrptype_ref      = uint32(hex2dec('05000000')); % u32 reference (handle)
    nxPrptype_1Dref    = uint32(hex2dec('06000000')); % array of u32 reference
    nxPrptype_time     = uint32(hex2dec('07000000')); % nxTimestamp_t
    nxPrptype_1Du32    = uint32(hex2dec('08000000')); % array of u32 values
    nxPrptype_u64      = uint32(hex2dec('09000000'));
    nxPrptype_1Du8     = uint32(hex2dec('0A000000')); % array of u8 values
    nxPrptype_Mask     = uint32(hex2dec('FF000000'));

    % Property ID for devices.
    nxPropDev_FormFac    = bitor(bitor(uint32(hex2dec('00000001')), can.ni.xnet.Utility.nxClass_Device), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropDev_IntfRefs   = bitor(bitor(uint32(hex2dec('00000002')), can.ni.xnet.Utility.nxClass_Device), can.ni.xnet.Utility.nxPrptype_1Dref);
    nxPropDev_Name       = bitor(bitor(uint32(hex2dec('00000003')), can.ni.xnet.Utility.nxClass_Device), can.ni.xnet.Utility.nxPrptype_string);
    nxPropDev_NumPorts   = bitor(bitor(uint32(hex2dec('00000004')), can.ni.xnet.Utility.nxClass_Device), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropDev_ProductNum = bitor(bitor(uint32(hex2dec('00000008')), can.ni.xnet.Utility.nxClass_Device), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropDev_SerNum     = bitor(bitor(uint32(hex2dec('00000005')), can.ni.xnet.Utility.nxClass_Device), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropDev_SlotNum    = bitor(bitor(uint32(hex2dec('00000006')), can.ni.xnet.Utility.nxClass_Device), can.ni.xnet.Utility.nxPrptype_u32);

    % Property ID for interfaces.
    nxPropIntf_DevRef     = bitor(bitor(uint32(hex2dec('00000001')), can.ni.xnet.Utility.nxClass_Interface), can.ni.xnet.Utility.nxPrptype_ref);
    nxPropIntf_Name       = bitor(bitor(uint32(hex2dec('00000002')), can.ni.xnet.Utility.nxClass_Interface), can.ni.xnet.Utility.nxPrptype_string);
    nxPropIntf_Num        = bitor(bitor(uint32(hex2dec('00000003')), can.ni.xnet.Utility.nxClass_Interface), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropIntf_PortNum    = bitor(bitor(uint32(hex2dec('00000004')), can.ni.xnet.Utility.nxClass_Interface), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropIntf_Protocol   = bitor(bitor(uint32(hex2dec('00000005')), can.ni.xnet.Utility.nxClass_Interface), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropIntf_CANTermCap = bitor(bitor(uint32(hex2dec('00000008')), can.ni.xnet.Utility.nxClass_Interface), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropIntf_CANTcvrCap = bitor(bitor(uint32(hex2dec('00000007')), can.ni.xnet.Utility.nxClass_Interface), can.ni.xnet.Utility.nxPrptype_u32);

    % Property ID for system.
    nxPropSys_DevRefs         = bitor(bitor(uint32(hex2dec('00000002')), can.ni.xnet.Utility.nxClass_System), can.ni.xnet.Utility.nxPrptype_1Dref);
    nxPropSys_IntfRefs        = bitor(bitor(uint32(hex2dec('00000003')), can.ni.xnet.Utility.nxClass_System), can.ni.xnet.Utility.nxPrptype_1Dref);
    nxPropSys_IntfRefsCAN     = bitor(bitor(uint32(hex2dec('00000004')), can.ni.xnet.Utility.nxClass_System), can.ni.xnet.Utility.nxPrptype_1Dref);
    nxPropSys_IntfRefsFlexRay = bitor(bitor(uint32(hex2dec('00000005')), can.ni.xnet.Utility.nxClass_System), can.ni.xnet.Utility.nxPrptype_1Dref);
    nxPropSys_IntfRefsLIN     = bitor(bitor(uint32(hex2dec('00000007')), can.ni.xnet.Utility.nxClass_System), can.ni.xnet.Utility.nxPrptype_1Dref);
    nxPropSys_VerBuild        = bitor(bitor(uint32(hex2dec('00000006')), can.ni.xnet.Utility.nxClass_System), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropSys_VerMajor        = bitor(bitor(uint32(hex2dec('00000008')), can.ni.xnet.Utility.nxClass_System), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropSys_VerMinor        = bitor(bitor(uint32(hex2dec('00000009')), can.ni.xnet.Utility.nxClass_System), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropSys_VerPhase        = bitor(bitor(uint32(hex2dec('0000000A')), can.ni.xnet.Utility.nxClass_System), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropSys_VerUpdate       = bitor(bitor(uint32(hex2dec('0000000B')), can.ni.xnet.Utility.nxClass_System), can.ni.xnet.Utility.nxPrptype_u32);

    % Property ID for session.
    nxPropSession_ApplicationProtocol = bitor(bitor(uint32(hex2dec('00000091')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_u32);
    
    nxPropSession_AutoStart    = bitor(bitor(uint32(hex2dec('00000001')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_bool);
    nxPropSession_ClusterName  = bitor(bitor(uint32(hex2dec('0000000A')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_string);
    nxPropSession_DatabaseName = bitor(bitor(uint32(hex2dec('00000002')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_string);
    nxPropSession_List         = bitor(bitor(uint32(hex2dec('00000003')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_1Dstring);
    nxPropSession_Mode         = bitor(bitor(uint32(hex2dec('00000004')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropSession_NumInList    = bitor(bitor(uint32(hex2dec('00000005')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropSession_NumPend      = bitor(bitor(uint32(hex2dec('00000006')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropSession_NumUnused    = bitor(bitor(uint32(hex2dec('0000000B')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropSession_PayldLenMax  = bitor(bitor(uint32(hex2dec('00000009')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropSession_Protocol     = bitor(bitor(uint32(hex2dec('00000008')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropSession_QueueSize    = bitor(bitor(uint32(hex2dec('0000000C')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropSession_ResampRate   = bitor(bitor(uint32(hex2dec('00000007')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_f64);

    nxPropSession_IntfCANExtTcvrConfig = bitor(bitor(uint32(hex2dec('00000023')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropSession_IntfCanFdBaudRate    = bitor(bitor(uint32(hex2dec('00000027')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropSession_IntfCanIoMode        = bitor(bitor(uint32(hex2dec('00000026')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropSession_IntfCANLstnOnly      = bitor(bitor(uint32(hex2dec('00000022')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_bool);
    nxPropSession_IntfCANPendTxOrder   = bitor(bitor(uint32(hex2dec('00000020')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropSession_IntfCANSingShot      = bitor(bitor(uint32(hex2dec('00000024')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_bool);
    nxPropSession_IntfCANTerm          = bitor(bitor(uint32(hex2dec('00000025')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropSession_IntfCANTcvrState     = bitor(bitor(uint32(hex2dec('00000028')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropSession_IntfCANTcvrType      = bitor(bitor(uint32(hex2dec('00000029')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropSession_IntfCanTxIoMode      = bitor(bitor(uint32(hex2dec('00000039')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_u32);

    nxPropSession_IntfBaudRate          = bitor(bitor(uint32(hex2dec('00000016')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropSession_IntfEchoTx            = bitor(bitor(uint32(hex2dec('00000010')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_bool);
    nxPropSession_IntfOutStrmList       = bitor(bitor(uint32(hex2dec('00000011')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_1Dref);
    nxPropSession_IntfOutStrmListById   = bitor(bitor(uint32(hex2dec('00000021')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_1Du32);
    nxPropSession_IntfOutStrmTimng      = bitor(bitor(uint32(hex2dec('00000012')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_u32);
    nxPropSession_IntfStartTrigToInStrm = bitor(bitor(uint32(hex2dec('00000014')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_bool);
    nxPropSession_IntfBusErrToInStrm    = bitor(bitor(uint32(hex2dec('00000015')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_bool);

    % Triggering definitions.
    nxPropSession_IntfSrcTermStartTrigger = bitor(bitor(uint32(hex2dec('00000090')), can.ni.xnet.Utility.nxClass_Session), can.ni.xnet.Utility.nxPrptype_string);

    nxTerm_PXI_Trig0         = 'PXI_Trig0'; % PXI_Trig0 same as RTSI0
    nxTerm_PXI_Trig1         = 'PXI_Trig1';
    nxTerm_PXI_Trig2         = 'PXI_Trig2';
    nxTerm_PXI_Trig3         = 'PXI_Trig3';
    nxTerm_PXI_Trig4         = 'PXI_Trig4';
    nxTerm_PXI_Trig5         = 'PXI_Trig5';
    nxTerm_PXI_Trig6         = 'PXI_Trig6';
    nxTerm_PXI_Trig7         = 'PXI_Trig7';
    nxTerm_FrontPanel0       = 'FrontPanel0';
    nxTerm_FrontPanel1       = 'FrontPanel1';
    nxTerm_PXI_Star          = 'PXI_Star';
    nxTerm_PXI_Clk10         = 'PXI_Clk10';
    nxTerm_10MHzTimebase     = '10MHzTimebase';
    nxTerm_1MHzTimebase      = '1MHzTimebase';
    nxTerm_MasterTimebase    = 'MasterTimebase';
    nxTerm_CommTrigger       = 'CommTrigger';
    nxTerm_StartTrigger      = 'StartTrigger';
    nxTerm_FlexRayStartCycle = 'FlexRayStartCycle';
    nxTerm_FlexRayMacrotick  = 'FlexRayMacrotick';
    nxTerm_LogTrigger        = 'LogTrigger';
    
    SourceTerminalOptions = { ...
        can.ni.xnet.Utility.nxTerm_PXI_Trig0, can.ni.xnet.Utility.nxTerm_PXI_Trig1, ...
        can.ni.xnet.Utility.nxTerm_PXI_Trig2, can.ni.xnet.Utility.nxTerm_PXI_Trig3, ...
        can.ni.xnet.Utility.nxTerm_PXI_Trig4, can.ni.xnet.Utility.nxTerm_PXI_Trig5, ...
        can.ni.xnet.Utility.nxTerm_PXI_Trig6, can.ni.xnet.Utility.nxTerm_PXI_Trig7, ...
        can.ni.xnet.Utility.nxTerm_FrontPanel0, can.ni.xnet.Utility.nxTerm_FrontPanel1, ...
        can.ni.xnet.Utility.nxTerm_PXI_Star, can.ni.xnet.Utility.nxTerm_PXI_Clk10, ...
        can.ni.xnet.Utility.nxTerm_StartTrigger, can.ni.xnet.Utility.nxTerm_CommTrigger, ...
        can.ni.xnet.Utility.nxTerm_FlexRayStartCycle, can.ni.xnet.Utility.nxTerm_FlexRayMacrotick, ...
        can.ni.xnet.Utility.nxTerm_1MHzTimebase, can.ni.xnet.Utility.nxTerm_10MHzTimebase};
    
    DestinationTerminalOptions = { ...
        can.ni.xnet.Utility.nxTerm_PXI_Trig0, can.ni.xnet.Utility.nxTerm_PXI_Trig1, ...
        can.ni.xnet.Utility.nxTerm_PXI_Trig2, can.ni.xnet.Utility.nxTerm_PXI_Trig3, ...
        can.ni.xnet.Utility.nxTerm_PXI_Trig4, can.ni.xnet.Utility.nxTerm_PXI_Trig5, ...
        can.ni.xnet.Utility.nxTerm_PXI_Trig6, can.ni.xnet.Utility.nxTerm_PXI_Trig7, ...
        can.ni.xnet.Utility.nxTerm_FrontPanel0, can.ni.xnet.Utility.nxTerm_FrontPanel1, ...
        can.ni.xnet.Utility.nxTerm_StartTrigger, can.ni.xnet.Utility.nxTerm_MasterTimebase, ...
        can.ni.xnet.Utility.nxTerm_LogTrigger};
    
    % Readable states for nxReadState.
    nxState_TimeCurrent       = bitor(bitor(uint32(hex2dec('00000001')), can.ni.xnet.Utility.nxClass_Interface), can.ni.xnet.Utility.nxPrptype_time);
    nxState_TimeCommunicating = bitor(bitor(uint32(hex2dec('00000002')), can.ni.xnet.Utility.nxClass_Interface), can.ni.xnet.Utility.nxPrptype_time);
    nxState_TimeStart         = bitor(bitor(uint32(hex2dec('00000003')), can.ni.xnet.Utility.nxClass_Interface), can.ni.xnet.Utility.nxPrptype_time);
    nxState_SessionInfo       = bitor(bitor(uint32(hex2dec('00000004')), can.ni.xnet.Utility.nxClass_Interface), can.ni.xnet.Utility.nxPrptype_u32);
    nxState_CANComm           = bitor(bitor(uint32(hex2dec('00000010')), can.ni.xnet.Utility.nxClass_Interface), can.ni.xnet.Utility.nxPrptype_u32);
    
    % Transceiver states for nxPropSession_IntfCANTcvrState.
    nxCANTcvrState_Normal      = 0;
    nxCANTcvrState_Sleep       = 1;
    nxCANTcvrState_SWWakeup    = 2;
    nxCANTcvrState_SWHighSpeed = 3;
    
    % Termination states for nxPropSession_IntfCANTerm.
    nxCANTerm_Off = 0;
    nxCANTerm_On  = 1;
    
    % Termination capability for nxPropIntf_CANTermCap.
    nxCANTermCap_No  = 0;
    nxCANTermCap_Yes = 1;
    
    % Numeric to string maps.
    nxPropIntf_Protocol_Values = containers.Map( ...
        { hex2dec('FFFFFFFE'), 0, 1, 2 }, ...
        { 'Unknown', 'CAN', 'FlexRay', 'LIN' } );

    nxPropIntf_CANTermCap_Values = containers.Map( ...
        { 0, 1 }, ...
        { 'No', 'Yes' } );

    nxPropIntf_CANTcvrCap_Values = containers.Map( ...
        { 0, 1, 2 }, ...
        { 'High-Speed (HS)', 'Low-Speed (LS)', 'XS (HS, LS, SW, or External)' } );

    nxPropDev_FormFac_Values = containers.Map( ...
        { 0, 1, 2 }, ...
        { 'PXI', 'PCI', 'C Series' } );

    nxPropSession_IntfCANTcvrType_Values = containers.Map( ...
        { 0, 1, 2, 3, 4 }, ...
        { 'High-Speed (HS)', 'Low-Speed (LS)', 'Single Wire (SW)', 'External (Ext)', 'Disconnected (Disc)' } );
    
    nxCANComm_Get_CommState_Values = containers.Map( ...
        { 0, 1, 2, 3 }, ...
        { 'ErrorActive', 'ErrorPassive', 'BusOff', 'Init' } );
    
    nxCANComm_Get_LastErr_Values = containers.Map( ...
        { 0, 1, 2, 3, 4, 5, 6 }, ...
        { 'None', 'Stuff', 'Form', 'Ack', 'Bit 1', 'Bit 0', 'CRC' } );
    
    % VNT Definitions.
    ActiveConnectionErrorCode = '0xBFF6300E';
    DefaultBusSpeed = 500000;
end

methods (Static)
    
    function found = isDriverAvailable()
        % isDriverAvailable Verifies the presence of a driver.
        %
        %   This method is used internally to check if a driver interface
        %   is installed on the system. It returns true if the driver was
        %   identified, otherwise returns false.
        
        try
            % Silence load library warnings to prevent potential BaT stalls.
            import com.mathworks.toolbox.testmeas.util.mwSystem.*;
            com.mathworks.toolbox.testmeas.util.mwSystem.silenceLoadLibrary();
            
            % There is no driver open function in this library, so to
            % verify if the library is available, we can simply call one of
            % the other functions. If the calls succeeds, we know the
            % library has to be present.
            SessionRef = can.ni.xnet.NIXNET.nxSystemOpen();
            can.ni.xnet.NIXNET.nxSystemClose(SessionRef);
            
            % Return true if no error is encountered.
            found = true;
            
        catch err %#ok<NASGU>
            % Otherwise return false.
            found = false;
        end
    end
    
    function out = getDriverVersion()
    % getDriverVersion Returns vendor driver version.
    %
    %   This method obtains driver version information and returns
    %   the version as a string built from the various version number
    %   components.
        
        % Open the system reference.
        SessionRef = can.ni.xnet.NIXNET.nxSystemOpen();
        
        % Get the version components.
        verMajor = can.ni.xnet.NIXNET.nxGetProperty( ...
            SessionRef, can.ni.xnet.Utility.nxPropSys_VerMajor, 'u32');
        verMinor = can.ni.xnet.NIXNET.nxGetProperty( ...
            SessionRef, can.ni.xnet.Utility.nxPropSys_VerMinor, 'u32');
        verUpdate = can.ni.xnet.NIXNET.nxGetProperty( ...
            SessionRef, can.ni.xnet.Utility.nxPropSys_VerUpdate, 'u32');
        
        % Close the system reference.
        can.ni.xnet.NIXNET.nxSystemClose(SessionRef);
        
        % Return the version as a combined string.
        out = [num2str(verMajor) '.' num2str(verMinor) '.' num2str(verUpdate)];
    end
    
    function out = getNumberOfChannels()
    % getNumberOfChannels Get the number of channels available.
    %
    %   This method returns the count of device channels available
    %   on the system.
        
        % Open the system reference.
        SessionRef = can.ni.xnet.NIXNET.nxSystemOpen();
        
        % Get the size of the CAN interface references property.
        propSize = can.ni.xnet.NIXNET.nxGetPropertySize( ...
            SessionRef, ...
            can.ni.xnet.Utility.nxPropSys_IntfRefsCAN);
        
        % Calculate the number of interfaces available by taking the size
        % of the interface references property and dividing by the variable
        % size in bytes, defined as 4 bytes by NI.
        out = propSize / 4;
        
        % Close the system reference.
        can.ni.xnet.NIXNET.nxSystemClose(SessionRef);
    end
    
    function out = getChannelInfoByInterface(interface)
    % getChannelInfoByInterface Get specific channel information.
    %
    %   This method returns a channel information structure for the device
    %   channel represented by the input. The expected input is a string
    %   that is the interface tag assigned to the channel.
        
        % Get information on all of the channels available.
        channelInfo = can.ni.xnet.Utility.getAllChannelInfo();
        
        % Find the specific channel information structure that corresponds
        % to the interface name provided and return it. Note that we loop
        % because the string comparison functions that make use of logicla
        % indexing only can compare on a fixed string size and not an exact
        % match. We need an exact match to cover the case of 'CAN1' and
        % 'CAN11' existing simultaneously.
        for ii = 1:numel(channelInfo)
            % Return the channel information structure at the matching
            % index for the requested interface.
            if strcmpi(interface, channelInfo(ii).Interface.Name)
                out = channelInfo(ii);
                return;
            end
        end
        
        % Return empty on no match.
        out = [];
    end
    
    function out = getAllChannelInfo()
    % getAllChannelInfo Get channel information for all channels.
    %
    %   This method returns an array of channel information structures with
    %   an entry for each device channel available on the system.
    
        % If there are no channels, return empty.
        if can.ni.xnet.Utility.getNumberOfChannels() == 0
            out = [];
            return;
        end
        
        % Open the system reference.
        SessionRef = can.ni.xnet.NIXNET.nxSystemOpen();
        
        % Get the channel references to be able to query for information.
        interfaceRefs = can.ni.xnet.NIXNET.nxGetProperty(...
            SessionRef, ...
            can.ni.xnet.Utility.nxPropSys_IntfRefsCAN, ...
            'array');
        
        % Initialize output.
        out = struct([]);
        
        % Loop through each channel and gather information.
        for ii = 1:numel(interfaceRefs)
            % Collect all the interface information about this channel.
            out(end + 1).Interface.DeviceRef = ...
                can.ni.xnet.NIXNET.nxGetProperty(interfaceRefs(ii), can.ni.xnet.Utility.nxPropIntf_DevRef, 'u32'); %#ok<AGROW>

            out(end).Interface.Name = ...
                can.ni.xnet.NIXNET.nxGetProperty(interfaceRefs(ii), can.ni.xnet.Utility.nxPropIntf_Name, 'cstr');
            
            out(end).Interface.Number = ...
                can.ni.xnet.NIXNET.nxGetProperty(interfaceRefs(ii), can.ni.xnet.Utility.nxPropIntf_Num, 'u32');
            
            out(end).Interface.PortNumber = ...
                can.ni.xnet.NIXNET.nxGetProperty(interfaceRefs(ii), can.ni.xnet.Utility.nxPropIntf_PortNum, 'u32');
            
            value = can.ni.xnet.NIXNET.nxGetProperty(interfaceRefs(ii), can.ni.xnet.Utility.nxPropIntf_Protocol, 'u32');
            out(end).Interface.Protocol = can.ni.xnet.Utility.nxPropIntf_Protocol_Values(value);
            
            value = can.ni.xnet.NIXNET.nxGetProperty(interfaceRefs(ii), can.ni.xnet.Utility.nxPropIntf_CANTermCap, 'u32');
            out(end).Interface.TerminationCapability = can.ni.xnet.Utility.nxPropIntf_CANTermCap_Values(value);
            
            value = can.ni.xnet.NIXNET.nxGetProperty(interfaceRefs(ii), can.ni.xnet.Utility.nxPropIntf_CANTcvrCap, 'u32');
            out(end).Interface.TransceiverCapability = can.ni.xnet.Utility.nxPropIntf_CANTcvrCap_Values(value);
            
            % Collect all the device information about this channel.
            value = can.ni.xnet.NIXNET.nxGetProperty(out(end).Interface.DeviceRef, can.ni.xnet.Utility.nxPropDev_FormFac, 'u32');
            out(end).Device.FormFactor = can.ni.xnet.Utility.nxPropDev_FormFac_Values(value);
            
            out(end).Device.Interfaces = ...
                can.ni.xnet.NIXNET.nxGetProperty(out(end).Interface.DeviceRef, can.ni.xnet.Utility.nxPropDev_IntfRefs, 'array');
            
            out(end).Device.NumberOfPorts = ...
                can.ni.xnet.NIXNET.nxGetProperty(out(end).Interface.DeviceRef, can.ni.xnet.Utility.nxPropDev_NumPorts, 'u32');
            
            value = can.ni.xnet.NIXNET.nxGetProperty(out(end).Interface.DeviceRef, can.ni.xnet.Utility.nxPropDev_Name, 'cstr');
            % Remove any instance of NI being in the device name, if present.
            if strcmpi('NI ', value(1:3))
                value = value(4:end);
            end
            out(end).Device.ProductName = value;            
            
            out(end).Device.ProductNumber = ...
                can.ni.xnet.NIXNET.nxGetProperty(out(end).Interface.DeviceRef, can.ni.xnet.Utility.nxPropDev_ProductNum, 'u32');
            
            out(end).Device.SerialNumber = can.ni.xnet.NIXNET.nxGetProperty(out(end).Interface.DeviceRef, can.ni.xnet.Utility.nxPropDev_SerNum, 'u32');

            % Calling for this property on devices without slots generates
            % a driver error, so try/catch that error and set an
            % appropriate value if the call fails.
            try
                out(end).Device.SlotNumber = ...
                    can.ni.xnet.NIXNET.nxGetProperty(out(end).Interface.DeviceRef, can.ni.xnet.Utility.nxPropDev_SlotNum, 'u32');
            catch err %#ok<NASGU>
                out(end).Device.SlotNumber = 'N/A';
            end
        end
        
        % Close the system reference.
        can.ni.xnet.NIXNET.nxSystemClose(SessionRef);
    end
    
end
    
end