gusucode.com > vnt工具箱matlab源码程序 > vnt/vnt/+j1939/TPReceiver.m
classdef TPReceiver < handle % TPReceiver Class that implements an active J1939 transport protocol connection. % % This class is used to implement the J1939 transport protocol. A single % object of this class represents a single transport protocol transfer % sequence happening on the network. It stores information about that % transfer and collects the data messages until the sequence is complete. % Once complete, the class builds a final parameter group objects for the % reconstituted data. % Authors: Jaremy Pyle % Copyright 2015 The MathWorks, Inc. properties (SetAccess = 'private') % State - The current state of the transport protocol data transfer. State % PGN - The parameter group number to apply to the reconstructed % parameter group. PGN % Priority - The priority to apply to the reconstructed parameter group. Priority % SourceAddress - The source address to apply to the reconstructed % parameter group. SourceAddress % DestinationAddress - The destintation address to apply to the % reconstructed parameter group. DestinationAddress % PDUFormatType - The J1939 protocol data unit format of this % parameter group. PDUFormatType % Size - The size in bytes of the full data transfer. Size % Packets - The number of data transfer packets to expect. Packets % DataTransferBuffer - A array of data transfer packets collected as % the information comes in from the network. DataTransferBuffer % PacketReceiveStatus - An array of boolean values used to keep track % of which data transfer packets were received. PacketReceiveStatus % NextSequenceNumber - The next expected sequence number to be received % for a transport protocol sequence. NextSequenceNumber % CompletePG - The final j1939.ParameterGroup object representing the % complete data transfer. CompletePG % Database - A can.Database object containing the definition of the % final parameter group. Database % BroadcastT1Time - Measures elapsed time from DT to DT in a broadcast % sequence. BroadcastT1Time end methods function obj = TPReceiver(database, newCM) % TPReceiver Class constructor. % Store the provided database. obj.Database = database; % Get the individual parameter elements from the identifier. [priority, sourceAddress, destinationAddress, ~] = ... mexJ1939Utility('getSubsetForConstruction', newCM.ID); % Set the PG details. obj.PGN = typecast([newCM.Data(6:8) uint8(0)], 'uint32'); obj.Priority = priority; obj.SourceAddress = sourceAddress; obj.DestinationAddress = destinationAddress; obj.PDUFormatType = newCM.Data(7); % Get the size of the multiframe transfer. obj.Size = typecast(newCM.Data(2:3), 'uint16'); % Get the number of expected packats for the multiframe transfer. obj.Packets = newCM.Data(4); % Clear the data buffer to be ready for new packets. obj.DataTransferBuffer = struct('ID', [], 'Data', [], ... 'Timestamp', [], 'Extended', [], 'Remote', [], ... 'Error', [], 'PGN', []); obj.PacketReceiveStatus = false([1, obj.Packets]); obj.CompletePG = []; % Set the state to actively building a multiframe result. obj.State = j1939.TPRxState.Acquiring; % Set the initial expected sequence number. obj.NextSequenceNumber = 1; % Set broadcast properties. if obj.isBroadcast() % Start timeout timing. obj.BroadcastT1Time = tic; end end function processCTS(obj, newCTS) % processCTS Process TP Clear To Send messages. % % This method is used to manage clear to send messages for this % multiframe reception. % If the sequence has failed, do nothing. if obj.State == j1939.TPRxState.Failed return; end % Set the next expected sequence number from the message input. obj.NextSequenceNumber = newCTS.Data(3); end function processDT(obj, newDT) % processDT Process TP Data Transfer messages. % % This method is used to manage data transfer messages for this % multiframe reception. It adds the input DT message to the collected % incoming data. % If the sequence has failed, do nothing. if obj.State == j1939.TPRxState.Failed return; end % Ensure proper timeout monitoring for broadcast sequences. if obj.isBroadcast() % Check the elapsed time since the last TP message for this % broadcast sequence. if toc(obj.BroadcastT1Time) > j1939.Utility.TPTimeoutT1 % Fail this sequence due to the T1 timeout. obj.State = j1939.TPRxState.Failed; end end % Check that the new data transfer message has the expected % sequence numbering. if obj.NextSequenceNumber ~= newDT.Data(1) % Fail this sequence due to an out of sequence error. obj.State = j1939.TPRxState.Failed; end % Add this new data transfer to the data buffer taking care to % append properly to avoid any warnings or errors. We use the % sequence number of the DT message as the array index into the % holding buffer. This ensures that as messages arrive, they are % placed exactly in proper sequence. obj.DataTransferBuffer(newDT.Data(1)) = newDT; % Note that this packet in the sequence was received. obj.PacketReceiveStatus(newDT.Data(1)) = true; % If this is a broadcast, check for completion of the sequence. % Peer-to-peer sequences are completed via a CM acknowledgment. if obj.isBroadcast() % Make sure we have all of the packets for this broadcast. if all(obj.PacketReceiveStatus) obj.completeParameterGroup(); else % Reset the time counter. obj.BroadcastT1Time = tic; end end % Increment the next sequence number. obj.NextSequenceNumber = obj.NextSequenceNumber + 1; end function completeParameterGroup(obj, varargin) % completeParameterGroup Reconstruct a received multiframe parameter group. % % This method is used upon completed reception of all of the data % transfer messages of a multiframe sequence. It builds the final % singular parameter group out of the multiframe data. % If the sequence has failed, do nothing. if obj.State == j1939.TPRxState.Failed return; end % Check if all data transfers for this sequence have been received. if ~all(obj.PacketReceiveStatus) % If not, then exit. obj.State = j1939.TPRxState.Failed; return; end % Save the PGN. obj.CompletePG.PGN = obj.PGN; % Build the identifier. obj.CompletePG.ID = uint32(0); obj.CompletePG.ID = j1939.Utility.setPDUField( ... 'Priority', obj.Priority, obj.CompletePG.ID); obj.CompletePG.ID = j1939.Utility.setPDUField( ... 'PGN', obj.PGN, obj.CompletePG.ID); if obj.PDUFormatType < j1939.Utility.PDUFormatThreshold obj.CompletePG.ID = j1939.Utility.setPDUField( ... 'PDUSpecific', obj.DestinationAddress, obj.CompletePG.ID); end obj.CompletePG.ID = j1939.Utility.setPDUField( ... 'SourceAddress', obj.SourceAddress, obj.CompletePG.ID); % Set the fixed elements. obj.CompletePG.Extended = true; obj.CompletePG.Error = false; obj.CompletePG.Remote = false; % Load the data. newData = []; for ii = 1:obj.Packets newData = [newData obj.DataTransferBuffer(ii).Data(2:end)]; %#ok<AGROW> end % Remove any fill bytes. newData(obj.Size+1:end) = []; % Store the final data array. obj.CompletePG.Data = newData; % Set the timestamp depending on the type of transfer. if obj.isBroadcast() % Set the timestamp of the final PG to the latest timestamp of all % of the data transfer messages for a broadcast. obj.CompletePG.Timestamp = max([obj.DataTransferBuffer.Timestamp]); else % For a peer-to-peer transfer, use the timestamp from the % acknowledgment CM. obj.CompletePG.Timestamp = varargin{1}; end % Mark the state as complete. obj.State = j1939.TPRxState.Completed; end function out = isComplete(obj) % isComplete Check if the multiframe reception sequence is complete. % % This method is used to check if the multiframe message sequence for % the transfer represented by this object is complete. It returns a % boolean state result. % Return true of this multiframe packet sequence is complete and % the data is fully reconstituted. if obj.State == j1939.TPRxState.Completed out = true; else out = false; end end function out = isBroadcast(obj) % isBroadcast Check if the multiframe reception sequence is broadcast. % % This method is used to check if the multiframe message sequence for % the transfer represented by this object is of broadcast or % peer-to-peer type. It returns a boolean state result. if obj.DestinationAddress == j1939.Utility.DestinationAll out = true; else out = false; end end end end