Skip to content

Commit

Permalink
Add Transaction logic for incoming Data
Browse files Browse the repository at this point in the history
  • Loading branch information
tinohager committed Aug 4, 2023
1 parent 398cfa3 commit ecc4cab
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 16 deletions.
15 changes: 11 additions & 4 deletions src/Portalum.Zvt/ZvtClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,8 @@ private async Task<CommandResponse> SendCommandAsync(
bool asyncCompletion = false)
{
using var timeoutCancellationTokenSource = new CancellationTokenSource(this._commandCompletionTimeout);
using var dataReceivedCancellationTokenSource = new CancellationTokenSource();
using var linkedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, dataReceivedCancellationTokenSource.Token, timeoutCancellationTokenSource.Token);
using var transactionFinishCancellationTokenSource = new CancellationTokenSource();
using var linkedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, transactionFinishCancellationTokenSource.Token, timeoutCancellationTokenSource.Token);

var commandResponse = new CommandResponse
{
Expand All @@ -301,25 +301,27 @@ void completionReceived(byte[] apduData)
{
commandResponse.State = CommandResponseState.Successful;

dataReceivedCancellationTokenSource.Cancel();
transactionFinishCancellationTokenSource.Cancel();
}

void abortReceived(string errorMessage)
{
commandResponse.State = CommandResponseState.Abort;
commandResponse.ErrorMessage = errorMessage;

dataReceivedCancellationTokenSource.Cancel();
transactionFinishCancellationTokenSource.Cancel();
}

void intermediateStatusInformationReceived(string status)
{
// Increase cancellation timeout
timeoutCancellationTokenSource.CancelAfter(this._commandCompletionTimeout);
}

bool startAsyncCompletionFired = false;
void statusInformationReceived(StatusInformation statusInformation)
{
// Increase cancellation timeout
timeoutCancellationTokenSource.CancelAfter(this._commandCompletionTimeout);

if (statusInformation.ErrorCode == 0 && asyncCompletion && !startAsyncCompletionFired)
Expand All @@ -340,6 +342,8 @@ void statusInformationReceived(StatusInformation statusInformation)
this._zvtCommunication.GetCompletionInfo += this.GetCompletionInfo;
}

this._zvtCommunication.TransactionActive();

this._logger.LogDebug($"{nameof(SendCommandAsync)} - Send command to PT");

var sendCommandResult = await this._zvtCommunication.SendCommandAsync(commandData, cancellationToken: cancellationToken);
Expand Down Expand Up @@ -373,6 +377,7 @@ void statusInformationReceived(StatusInformation statusInformation)
}

// There is no infinite timeout here, the timeout comes via the `timeoutCancellationTokenSource`
// Wait for TransactionFinish or Timeout
await Task.Delay(Timeout.InfiniteTimeSpan, linkedCancellationTokenSource.Token).ContinueWith(task =>
{
if (timeoutCancellationTokenSource.IsCancellationRequested)
Expand All @@ -384,6 +389,8 @@ await Task.Delay(Timeout.InfiniteTimeSpan, linkedCancellationTokenSource.Token).
}
finally
{
this._zvtCommunication.TransactionInactive();

this._receiveHandler.AbortReceived -= abortReceived;
this._receiveHandler.CompletionReceived -= completionReceived;
this._receiveHandler.IntermediateStatusInformationReceived -= intermediateStatusInformationReceived;
Expand Down
31 changes: 19 additions & 12 deletions src/Portalum.Zvt/ZvtCommunication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class ZvtCommunication : IDisposable
private CancellationTokenSource _commandCompletionCancellationTokenSource;
private byte[] _dataBuffer;
private bool _waitForCommandCompletion = false;
private bool _allowCompletion = false;
private bool _transactionActive = false;

/// <summary>
/// New data received from the pt device
Expand Down Expand Up @@ -74,6 +74,16 @@ protected virtual void Dispose(bool disposing)
}
}

public void TransactionActive()
{
this._transactionActive = true;
}

public void TransactionInactive()
{
this._transactionActive = false;
}

/// <summary>
/// Switch for incoming data
/// </summary>
Expand Down Expand Up @@ -142,6 +152,13 @@ protected virtual void ProcessData(byte[] data)
return;
}

if (!this._transactionActive)
{
this._logger.LogInformation($"{nameof(ProcessData)} - Receive data in transaction inactive state");
this._deviceCommunication.SendAsync(this._negativeIssueGoodsData);
return;
}

// Is StatusInformation and ErrorCode is 0
if (dataProcessed.Response is StatusInformation { ErrorCode: 0 })
{
Expand Down Expand Up @@ -185,13 +202,7 @@ protected virtual void ProcessData(byte[] data)
}
else if (dataProcessed.Response is Completion completion)
{
if (this._allowCompletion)
{
this._deviceCommunication.SendAsync(this._positiveCompletionData1);
return;
}

this._deviceCommunication.SendAsync(this._negativeIssueGoodsData);
this._deviceCommunication.SendAsync(this._positiveCompletionData1);
return;
}
else if (dataProcessed.Response is Abort abort)
Expand Down Expand Up @@ -233,7 +244,6 @@ public async virtual Task<SendCommandResult> SendCommandAsync(
int commandCompletionReceiveTimeoutMilliseconds = 5000,
CancellationToken cancellationToken = default)
{
this._allowCompletion = true;
this.ResetDataBuffer();

this._commandCompletionCancellationTokenSource?.Dispose();
Expand Down Expand Up @@ -277,18 +287,15 @@ await Task.Delay(commandCompletionReceiveTimeoutMilliseconds, linkedCancellation

if (this.CheckIsNotSupported())
{
this._allowCompletion = false;
return SendCommandResult.NotSupported;
}

if (this.CheckIsNegativeCompletion())
{
this._allowCompletion = false;
this._logger.LogError($"{nameof(SendCommandAsync)} - 'Negative completion' received");
return SendCommandResult.NegativeCompletionReceived;
}

this._allowCompletion = false;
this._logger.LogError($"{nameof(SendCommandAsync)} - Unknown Failure, DataBuffer {BitConverter.ToString(this._dataBuffer)}");
return SendCommandResult.UnknownFailure;
}
Expand Down

0 comments on commit ecc4cab

Please sign in to comment.