Skip to content

Commit c0807b5

Browse files
committed
Fixed an issue with UDP not recovering after a Communication Loss
- The Socket Receive Buffer is flushed if we receive an incorrect Service ID from the PLC.
1 parent 4ace4a0 commit c0807b5

File tree

3 files changed

+85
-0
lines changed

3 files changed

+85
-0
lines changed

RICADO.Omron/Channels/EthernetChannel.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,26 @@ internal async Task<ProcessRequestResult> ProcessRequestAsync(FINSRequest reques
147147
}
148148
catch (FINSException e)
149149
{
150+
if(e.Message.Contains("Service ID") && responseMessage.Length >= 9 && responseMessage.Span[9] != request.ServiceID)
151+
{
152+
try
153+
{
154+
if (!_semaphore.Wait(0))
155+
{
156+
await _semaphore.WaitAsync(cancellationToken);
157+
}
158+
159+
await PurgeReceiveBuffer(timeout, cancellationToken);
160+
}
161+
catch
162+
{
163+
}
164+
finally
165+
{
166+
_semaphore.Release();
167+
}
168+
}
169+
150170
throw new OmronException("Received a FINS Error Response from Omron PLC '" + _remoteHost + ":" + _port + "'", e);
151171
}
152172
}
@@ -162,6 +182,8 @@ internal async Task<ProcessRequestResult> ProcessRequestAsync(FINSRequest reques
162182

163183
protected abstract Task<ReceiveMessageResult> ReceiveMessageAsync(int timeout, CancellationToken cancellationToken);
164184

185+
protected abstract Task PurgeReceiveBuffer(int timeout, CancellationToken cancellationToken);
186+
165187
#endregion
166188

167189

RICADO.Omron/Channels/EthernetTCPChannel.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,40 @@ protected override Task<ReceiveMessageResult> ReceiveMessageAsync(int timeout, C
135135
return receiveMessageAsync(enTCPCommandCode.FINSFrame, timeout, cancellationToken);
136136
}
137137

138+
protected override async Task PurgeReceiveBuffer(int timeout, CancellationToken cancellationToken)
139+
{
140+
try
141+
{
142+
if (_client.Connected == false)
143+
{
144+
return;
145+
}
146+
147+
if(_client.Available == 0)
148+
{
149+
await Task.Delay(timeout / 4);
150+
}
151+
152+
DateTime startTimestamp = DateTime.UtcNow;
153+
Memory<byte> buffer = new byte[2000];
154+
155+
while (_client.Connected && _client.Available > 0 && DateTime.UtcNow.Subtract(startTimestamp).TotalMilliseconds < timeout)
156+
{
157+
try
158+
{
159+
await _client.ReceiveAsync(buffer, timeout, cancellationToken);
160+
}
161+
catch
162+
{
163+
return;
164+
}
165+
}
166+
}
167+
catch
168+
{
169+
}
170+
}
171+
138172
#endregion
139173

140174

RICADO.Omron/Channels/EthernetUDPChannel.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,35 @@ protected override async Task<ReceiveMessageResult> ReceiveMessageAsync(int time
190190
return result;
191191
}
192192

193+
protected override async Task PurgeReceiveBuffer(int timeout, CancellationToken cancellationToken)
194+
{
195+
try
196+
{
197+
if (_client.Available == 0)
198+
{
199+
await Task.Delay(timeout / 4);
200+
}
201+
202+
DateTime startTimestamp = DateTime.UtcNow;
203+
Memory<byte> buffer = new byte[2000];
204+
205+
while (_client.Available > 0 && DateTime.UtcNow.Subtract(startTimestamp).TotalMilliseconds < timeout)
206+
{
207+
try
208+
{
209+
await _client.ReceiveAsync(buffer, timeout, cancellationToken);
210+
}
211+
catch
212+
{
213+
return;
214+
}
215+
}
216+
}
217+
catch
218+
{
219+
}
220+
}
221+
193222
#endregion
194223

195224

0 commit comments

Comments
 (0)