189 lines
8.2 KiB
C#
189 lines
8.2 KiB
C#
using System;
|
|
using System.Text;
|
|
using DTS.Common.Enums.Communication;
|
|
using DTS.Common.Enums.DASFactory;
|
|
using DTS.Common.ICommunication;
|
|
using DTS.Common.Utilities;
|
|
|
|
namespace DTS.DASLib.Command.SLICE.DownloadCommands
|
|
{
|
|
/// <summary>
|
|
/// This was ported from FirmwareTestUtility where it was written by Loc Pham
|
|
/// it is being included for
|
|
/// 10573 implement SW side of single command/streaming download
|
|
/// this command can be used to collect data that has been collecting in a buffer
|
|
/// from download streaming
|
|
/// </summary>
|
|
public class GetNextDownloadStreamDataSamples : EventDataCommands
|
|
{
|
|
protected override Commands Command => Commands.GetNextDownloadStreamDataSamples;
|
|
|
|
public GetNextDownloadStreamDataSamples(DTS.Common.Interface.DASFactory.ICommunication sock)
|
|
: base(sock)
|
|
{
|
|
baseCommand = new CommandPacket();
|
|
LogCommands = false;
|
|
baseCommand.SetCommand((byte)Commands.GetNextDownloadStreamDataSamples, "GetNextDownloadStreamDataSamples");
|
|
}
|
|
public GetNextDownloadStreamDataSamples(DTS.Common.Interface.DASFactory.ICommunication sock, int msTimeout)
|
|
: base(sock, msTimeout)
|
|
{
|
|
baseCommand = new CommandPacket();
|
|
LogCommands = false;
|
|
baseCommand.SetCommand((byte)Commands.GetNextDownloadStreamDataSamples, "GetNextDownloadStreamDataSamples");
|
|
}
|
|
|
|
public DownloadByteConverter DlData { get; private set; }
|
|
|
|
private ushort _lastSequenceProcessed = ushort.MaxValue;
|
|
private const int MAX_SEQUENCE_DIFF = 1000;
|
|
|
|
public void ProcessData()
|
|
{
|
|
var bytes = baseResponse.ToBytes();
|
|
var headerCrc = response.HeaderCRC;
|
|
response.ComputeCRCs();
|
|
if (headerCrc != response.HeaderCRC)
|
|
{
|
|
DlData = null;
|
|
return;
|
|
}
|
|
|
|
DlData = new DownloadByteConverter(bytes);
|
|
|
|
if (null == DlData) { return; }
|
|
if (_lastSequenceProcessed == DlData.SeqNumber)
|
|
{
|
|
DlData = null;
|
|
return;
|
|
}
|
|
var delta = Math.Abs(DlData.SeqNumber - _lastSequenceProcessed);
|
|
if (delta > MAX_SEQUENCE_DIFF && ushort.MaxValue != _lastSequenceProcessed && 0 != DlData.SeqNumber)
|
|
{
|
|
//per loc we shouldn't get here, the old code in the FWTU would apparently unintentionally throw an exception
|
|
//I've preserved that code in comments below
|
|
throw new Exception("sequence number overflow");
|
|
//DlData = null;
|
|
//_lastSequenceProcessed = DlData.SeqNumber;
|
|
//return;
|
|
}
|
|
_lastSequenceProcessed = DlData.SeqNumber;
|
|
}
|
|
|
|
/// <summary>
|
|
/// We need to override SyncExecute because we don't want to send anything (that would tell the G5 to stop sending). Instead we just want to
|
|
/// read whatever is out there. Otherwise this is mostly cut and paste of normal SyncExecute with some streamlining for our specific case.
|
|
/// </summary>
|
|
public override void SyncExecute()
|
|
{
|
|
// this is a try/finally to handle the ExecuteIsBusy
|
|
try
|
|
{
|
|
DlData = null;
|
|
// there can be only one!
|
|
recorder.ExecuteIsBusy = true;
|
|
|
|
if (recorder.IsCanceled())
|
|
{
|
|
throw new CanceledException();
|
|
}
|
|
|
|
UserCallback = null;
|
|
UserCallbackData = null;
|
|
IsSynchronous = true;
|
|
SyncEvent.Reset();
|
|
recorder.PseudoExecute(new byte[0], ExecuteCallback, null, IO_Timeout);
|
|
|
|
var syncExecTimeout = IO_Timeout;
|
|
|
|
try
|
|
{
|
|
if (!WaitWithCondition.Wait(SyncEvent, syncExecTimeout,
|
|
recorder.CancelEvent))
|
|
{
|
|
//timeout
|
|
LogString("SyncExecute: timeout");
|
|
throw new TimeoutException(MakeLogString("SyncExecute: timeout"));
|
|
}
|
|
}
|
|
catch (WaitWithCondition.ConditionMetException)
|
|
{
|
|
throw new CanceledException();
|
|
}
|
|
|
|
// we didn't timeout, check the result
|
|
switch (ComReport.Result)
|
|
{
|
|
case CommunicationConstantsAndEnums.CommunicationResult.Canceled:
|
|
throw new CanceledException();
|
|
|
|
case CommunicationConstantsAndEnums.CommunicationResult.ReceiveOK:
|
|
if (baseResponse == null)
|
|
{
|
|
LogString("SyncExecute: ReceiveOK but response==null!");
|
|
LogCommand(false);
|
|
}
|
|
else if (baseResponse.Status != DFConstantsAndEnums.CommandStatus.StatusNoError)
|
|
{
|
|
// didn't go well
|
|
var msg = MakeLogString("SyncExecute: response.Status = " + baseResponse.Status);
|
|
LogCommand(false);
|
|
switch (baseResponse.Status)
|
|
{
|
|
case DFConstantsAndEnums.CommandStatus.StatusInvalidModeForCommand:
|
|
throw new CommandException(CommandErrorReason.InvalidMode, msg);
|
|
case DFConstantsAndEnums.CommandStatus.StatusUnimplemented:
|
|
case DFConstantsAndEnums.CommandStatus.StatusInvalidCommand:
|
|
case DFConstantsAndEnums.CommandStatus.StatusInvalidCommandType:
|
|
throw new NotImplementedException(msg);
|
|
}
|
|
var ex = new Exception(msg);
|
|
ex.Data.Add("Status", baseResponse.Status);
|
|
throw ex;
|
|
}
|
|
|
|
// everything is fine, let it exit
|
|
if (LogCommands)
|
|
{
|
|
LogCommand(false);
|
|
}
|
|
break;
|
|
|
|
case CommunicationConstantsAndEnums.CommunicationResult.ReceiveFailed:
|
|
{
|
|
var msg = MakeLogString("SyncExecute: ComReport.Result == " + ComReport.Result);
|
|
LogCommand(false);
|
|
|
|
throw new CommandException(CommandErrorReason.ReceiveFailed, msg);
|
|
}
|
|
case CommunicationConstantsAndEnums.CommunicationResult.ReceiveTimeout:
|
|
{
|
|
var msg = MakeLogString("SyncExecute: ComReport.Result == " + ComReport.Result);
|
|
LogCommand(false);
|
|
throw new CommandException(CommandErrorReason.ReceiveFailed, msg);
|
|
}
|
|
|
|
case CommunicationConstantsAndEnums.CommunicationResult.SendFailed:
|
|
case CommunicationConstantsAndEnums.CommunicationResult.SendTimeout:
|
|
{
|
|
var msg = MakeLogString("SyncExecute: ComReport.Result == " + ComReport.Result);
|
|
LogCommand(false);
|
|
throw new CommandException(CommandErrorReason.SendFailed, msg);
|
|
}
|
|
|
|
default:
|
|
{
|
|
var msg = MakeLogString("SyncExecute: Unknown ComReport.Result == " + ComReport.Result);
|
|
LogCommand(false);
|
|
throw new Exception(msg);
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
recorder.ExecuteIsBusy = false;
|
|
}
|
|
}
|
|
}
|
|
}
|