private void ReceivedS7PendingAlarmsAckDatagram(Memory <byte> buffer) { var data = S7PendingAlarmAckDatagram.TranslateFromMemory(buffer); if (_alarmHandler.TryGetValue(data.UserData.Header.ProtocolDataUnitReference, out var cbh)) { if (data.UserData.Data == null) { _logger.LogWarning("No data from pending alarm ack received for reference {0}", data.UserData.Header.ProtocolDataUnitReference); } cbh.Event.Set(data); } else { _logger.LogWarning("No read handler found for received pending alarm ack reference {0}", data.UserData.Header.ProtocolDataUnitReference); } }
private void ReceivedS7PendingAlarmsAckDatagram(Memory <byte> buffer) { var data = S7PendingAlarmAckDatagram.TranslateFromMemory(buffer); if (_alarmHandler.TryGetValue(data.UserData.Header.ProtocolDataUnitReference, out var cbh)) { if (data.UserData.Parameter.ParamErrorCode != 0) { _logger.LogError("Error while reading pending alarms for reference {0}. ParamErrorCode: {1}", data.UserData.Header.ProtocolDataUnitReference, data.UserData.Parameter.ParamErrorCode); cbh.Exception = new Dacs7ParameterException(data.UserData.Parameter.ParamErrorCode); cbh.Event.Set(null); } if (data.UserData.Data == null) { _logger.LogWarning("No data from pending alarm ack received for reference {0}", data.UserData.Header.ProtocolDataUnitReference); } cbh.Event.Set(data); } else { _logger.LogWarning("No read handler found for received pending alarm ack reference {0}", data.UserData.Header.ProtocolDataUnitReference); } }
public async Task <IEnumerable <IPlcAlarm> > ReadPendingAlarmsAsync() { if (ConnectionState != ConnectionState.Opened) { ThrowHelper.ThrowNotConnectedException(); } var id = GetNextReferenceId(); var sequenceNumber = (byte)0x00; var alarms = new List <IPlcAlarm>(); IMemoryOwner <byte> memoryOwner = null; var currentPosition = 0; var totalLength = 0; try { S7PendingAlarmAckDatagram alarmResults = null; do { using (var dg = S7UserDataDatagram.TranslateToMemory(S7UserDataDatagram.BuildPendingAlarmRequest(_s7Context, id, sequenceNumber), out var memoryLength)) { using (var sendData = _transport.Build(dg.Memory.Slice(0, memoryLength), out var sendLength)) { CallbackHandler <S7PendingAlarmAckDatagram> cbh; using (await SemaphoreGuard.Async(_concurrentJobs).ConfigureAwait(false)) { cbh = new CallbackHandler <S7PendingAlarmAckDatagram>(id); _alarmHandler.TryAdd(cbh.Id, cbh); try { if (await _transport.Client.SendAsync(sendData.Memory.Slice(0, sendLength)).ConfigureAwait(false) != SocketError.Success) { return(null); } alarmResults = await cbh.Event.WaitAsync(_s7Context.Timeout).ConfigureAwait(false); } finally { _alarmHandler.TryRemove(cbh.Id, out _); } } HandleErrorResult(id, cbh, alarmResults); if (alarmResults.UserData.Data.UserDataLength > 4) { if (memoryOwner == null) { totalLength = BinaryPrimitives.ReadUInt16BigEndian(alarmResults.UserData.Data.Data.Span.Slice(4, 2)) + 6; // 6 is the header memoryOwner = MemoryPool <byte> .Shared.Rent(totalLength); } alarmResults.UserData.Data.Data.CopyTo(memoryOwner.Memory.Slice(currentPosition, alarmResults.UserData.Data.Data.Length)); currentPosition += alarmResults.UserData.Data.Data.Length; sequenceNumber = alarmResults.UserData.Parameter.SequenceNumber; } else { totalLength = 0; } } } } while (alarmResults.UserData.Parameter.LastDataUnit == 0x01); if (memoryOwner != null) { alarms = S7PendingAlarmAckDatagram.TranslateFromSslData(memoryOwner.Memory, totalLength); } } finally { memoryOwner?.Dispose(); } return(alarms); }
private void HandleErrorResult(ushort id, CallbackHandler <S7PendingAlarmAckDatagram> cbh, S7PendingAlarmAckDatagram alarmResults) { if (alarmResults == null) { if (_closeCalled) { ThrowHelper.ThrowNotConnectedException(); } else { if (cbh.Exception != null) { ThrowHelper.ThrowException(cbh.Exception); } ThrowHelper.ThrowReadTimeoutException(id); } } }
public async Task <IEnumerable <IPlcAlarm> > ReadPendingAlarmsAsync() { if (_closeCalled || ConnectionState != ConnectionState.Opened) { ThrowHelper.ThrowNotConnectedException(); } var id = GetNextReferenceId(); var sequenceNumber = (byte)0x00; var alarms = new List <IPlcAlarm>(); IMemoryOwner <byte> memoryOwner = null; var currentPosition = 0; var totalLength = 0; try { S7PendingAlarmAckDatagram alarmResults = null; do { using (var dg = S7UserDataDatagram.TranslateToMemory(S7UserDataDatagram.BuildPendingAlarmRequest(_s7Context, id, sequenceNumber), out var memoryLength)) { using (var sendData = _transport.Build(dg.Memory.Slice(0, memoryLength), out var sendLength)) { CallbackHandler <S7PendingAlarmAckDatagram> cbh = null; try { using (await SemaphoreGuard.Async(_concurrentJobs).ConfigureAwait(false)) { cbh = new CallbackHandler <S7PendingAlarmAckDatagram>(id); if (_alarmHandler.TryAdd(id, cbh)) { _logger?.LogTrace("Alarmhandler with id {id} was added.", id); try { if (await _transport.Connection.SendAsync(sendData.Memory.Slice(0, sendLength)).ConfigureAwait(false) != SocketError.Success) { // we return false, because if one send faild we expect also all other ones failed. _logger?.LogWarning("Could not send read pending alarm package with reference <{id}>.", id); return(null); } alarmResults = await cbh.Event.WaitAsync(_s7Context.Timeout).ConfigureAwait(false); } finally { _alarmHandler.TryRemove(id, out _); _logger?.LogTrace("Alarmhandler with id {id} was removed.", id); } } else { _logger?.LogWarning("Could not add pending alarm handler with reference <{id}>.", id); } } } catch (ObjectDisposedException) { if (cbh == null) { return(alarms); // client was shut down without any result, so we return an empty list. } // if we have a result we could handle it. } HandleErrorResult(id, cbh, alarmResults); if (alarmResults.UserData.Data.UserDataLength > 4) { if (memoryOwner == null) { totalLength = BinaryPrimitives.ReadUInt16BigEndian(alarmResults.UserData.Data.Data.Span.Slice(4, 2)) + 6; // 6 is the header memoryOwner = MemoryPool <byte> .Shared.Rent(totalLength); } alarmResults.UserData.Data.Data.CopyTo(memoryOwner.Memory.Slice(currentPosition, alarmResults.UserData.Data.Data.Length)); currentPosition += alarmResults.UserData.Data.Data.Length; sequenceNumber = alarmResults.UserData.Parameter.SequenceNumber; } else { totalLength = 0; } } } } while (alarmResults.UserData.Parameter.LastDataUnit == 0x01); if (memoryOwner != null) { alarms = S7PendingAlarmAckDatagram.TranslateFromSslData(memoryOwner.Memory, totalLength); } } finally { memoryOwner?.Dispose(); } return(alarms); }