-
Notifications
You must be signed in to change notification settings - Fork 43
Description
NuGet Package Version
3.4.0
Payment service provider
irrelevant
Payment terminal
irrelevant
Communication Logs
13:35:17.560 info: Portalum.Zvt.ZvtClient[0] RegistrationAsync - Execute
13:35:17.564 dbug: Portalum.Zvt.ZvtClient[0] SendCommandAsync - Send command to PT
13:35:17.568 dbug: Portalum.Zvt.SerialPortDeviceCommunication[0] SendRaw - 10-02-06-00-10-10-00-00-00-BE-09-78-03-01-06-06-26-04-0A-02-06-D3-10-03-D7-DE
More information
Should be easy to reproduce, by just sending a command without any device attached.
The SerialPortDeviceCommunication.SendAsync() may never return from
| var byte1 = (byte)this._serialPort.ReadByte(); |
I am not sure, why ReadByte() doesn't return -1 as stated in the MS documentation.
The byte, cast to an Int32, or -1 if the end of the stream has been read.
To avoid the synchronous blocking, we could check if there is any data to be read before calling ReadByte() like this:
if (_serialPort.BytesToRead <= 0)
{
await Task.Delay(10, cancellationToken).ConfigureAwait(false);
continue;
}However, there is still the issue, that if no timeout based CancellationToken was supplied to the SendAsync(), it will never exit the loop. Looking at the code, there are quite a lot of calls where the token is ommitted:
The call from SendCommandAsync() also does not implement an internal timeout. The user supplied token will be considered, but the timeout should be an implementation detail and not something, the user of the API has to consider by providing a timeout.
I am not sure about the best approach here. The ACK seems to belong to the serial protocol layer, so SendAsync() should probably implement a timeout directly instead of relying on a CancellationToken.
