예제 #1
0
        private async Task HandleReadJobAsync(S7ReadJobDatagram data)
        {
            var readRequests = data.Items.Select(rq => new ReadRequestItem((PlcArea)rq.Area, rq.DbNumber, rq.ItemSpecLength, rq.Offset, (ItemDataTransportSize)rq.TransportSize, rq.Address)).ToList();
            var results      = await _provider.ReadAsync(readRequests).ConfigureAwait(false);

            await SendReadJobAck(results, data.Header.ProtocolDataUnitReference).ConfigureAwait(false);
        }
예제 #2
0
 private Task ReceivedReadJob(Memory <byte> buffer)
 {
     if (_provider != null)
     {
         var data = S7ReadJobDatagram.TranslateFromMemory(buffer);
         Task.Run(() => HandleReadJobAsync(data).ConfigureAwait(false)); // here we do not have to wayt because the receive buffer is fully converted and is not needed anymore
     }
     return(Task.CompletedTask);
 }
예제 #3
0
        private void ReceivedReadJob(Memory <byte> buffer)
        {
            var data = S7ReadJobDatagram.TranslateFromMemory(buffer);

            if (_readHandler.TryGetValue(data.Header.ProtocolDataUnitReference, out var cbh))
            {
                cbh.Event.Set(_defaultReadJobResult);
            }
            else
            {
                _logger.LogWarning("No read handler found for received read job reference {0}", data.Header.ProtocolDataUnitReference);
            }
        }
예제 #4
0
        private async Task <bool> ReadPackage(Dictionary <ReadItem, S7DataItemSpecification> result, ReadPackage normalized)
        {
            var id = GetNextReferenceId();

            using (var dgmem = S7ReadJobDatagram.TranslateToMemory(S7ReadJobDatagram.BuildRead(_s7Context, id, normalized.Items), out var dgmemLength))
            {
                using (var sendData = _transport.Build(dgmem.Memory.Slice(0, dgmemLength), out var sendLength))
                {
                    try
                    {
                        IEnumerable <S7DataItemSpecification> readResults = null;
                        CallbackHandler <IEnumerable <S7DataItemSpecification> > cbh;
                        using (await SemaphoreGuard.Async(_concurrentJobs).ConfigureAwait(false))
                        {
                            cbh = new CallbackHandler <IEnumerable <S7DataItemSpecification> >(id);
                            _readHandler.TryAdd(cbh.Id, cbh);
                            try
                            {
                                if (await _transport.Client.SendAsync(sendData.Memory.Slice(0, sendLength)).ConfigureAwait(false) != SocketError.Success)
                                {
                                    return(false);
                                }
                                readResults = await cbh.Event.WaitAsync(_s7Context.Timeout).ConfigureAwait(false);
                            }
                            finally
                            {
                                _readHandler.TryRemove(cbh.Id, out _);
                            }
                        }

                        HandlerErrorResult(id, readResults, cbh);

                        BildResults(result, normalized, readResults);
                    }
                    catch (TaskCanceledException)
                    {
                        ThrowHelper.ThrowTimeoutException();
                    }
                }
            }
            return(true);
        }
예제 #5
0
        private async Task <bool> ReadPackage(Dictionary <ReadItem, S7DataItemSpecification> result, ReadPackage normalized)
        {
            var id = GetNextReferenceId();

            using (var dgmem = S7ReadJobDatagram.TranslateToMemory(S7ReadJobDatagram.BuildRead(_s7Context, id, normalized.Items), out var dgmemLength))
            {
                using (var sendData = _transport.Build(dgmem.Memory.Slice(0, dgmemLength), out var sendLength))
                {
                    try
                    {
                        IEnumerable <S7DataItemSpecification> readResults            = null;
                        CallbackHandler <IEnumerable <S7DataItemSpecification> > cbh = null;
                        try
                        {
                            if (_concurrentJobs == null)
                            {
                                return(false);
                            }
                            using (await SemaphoreGuard.Async(_concurrentJobs).ConfigureAwait(false))
                            {
                                cbh = new CallbackHandler <IEnumerable <S7DataItemSpecification> >(id);
                                if (_readHandler.TryAdd(id, cbh))
                                {
                                    _logger?.LogTrace("Read handler with id {id} was added.", id);
                                    try
                                    {
                                        if (await _transport.Connection.SendAsync(sendData.Memory.Slice(0, sendLength)).ConfigureAwait(false) != SocketError.Success)
                                        {
                                            // we cancel return false, because if on esend faild we expect also all other ones failed.
                                            _logger?.LogWarning("Could not send read package with reference <{id}>.", id);
                                            return(false);
                                        }
                                        readResults = await cbh.Event.WaitAsync(_s7Context.Timeout).ConfigureAwait(false);
                                    }
                                    finally
                                    {
                                        _readHandler.TryRemove(id, out _);
                                        _logger?.LogTrace("Read handler with id {id} was removed.", id);
                                    }
                                }
                                else
                                {
                                    _logger?.LogWarning("Could not add read handler with reference <{id}>.", id);
                                }
                            }
                        }
                        catch (ObjectDisposedException)
                        {
                            if (cbh == null)
                            {
                                return(false);
                            }
                        }

                        HandlerErrorResult(id, readResults, cbh);

                        BildResults(result, normalized, readResults);
                    }
                    catch (TaskCanceledException)
                    {
                        ThrowHelper.ThrowTimeoutException();
                    }
                }
            }
            return(true);
        }
예제 #6
0
        public async Task <IEnumerable <S7DataItemSpecification> > ReadAsync(IEnumerable <ReadItem> vars)
        {
            if (ConnectionState != ConnectionState.Opened)
            {
                throw new Dacs7NotConnectedException();
            }

            var result = vars.ToDictionary(x => x, x => null as S7DataItemSpecification);

            foreach (var normalized in CreateReadPackages(_s7Context, vars))
            {
                var id       = GetNextReferenceId();
                var sendData = DataTransferDatagram.TranslateToMemory(
                    DataTransferDatagram.Build(_context,
                                               S7ReadJobDatagram.TranslateToMemory(
                                                   S7ReadJobDatagram.BuildRead(_s7Context, id, normalized.Items))).FirstOrDefault());


                try
                {
                    IEnumerable <S7DataItemSpecification> readResults = null;
                    using (await SemaphoreGuard.Async(_concurrentJobs))
                    {
                        var cbh = new CallbackHandler <IEnumerable <S7DataItemSpecification> >(id);
                        _readHandler.TryAdd(cbh.Id, cbh);
                        try
                        {
                            if (await _socket.SendAsync(sendData) != SocketError.Success)
                            {
                                return(new List <S7DataItemSpecification>());
                            }
                            readResults = await cbh.Event.WaitAsync(_timeout);
                        }
                        finally
                        {
                            _readHandler.TryRemove(cbh.Id, out _);
                        }
                    }

                    if (readResults == null)
                    {
                        throw new TimeoutException();
                    }

                    var items = normalized.Items.GetEnumerator();
                    foreach (var item in readResults)
                    {
                        if (items.MoveNext())
                        {
                            if (items.Current.IsPart)
                            {
                                if (!result.TryGetValue(items.Current.Parent, out var parent) || parent == null)
                                {
                                    parent = new S7DataItemSpecification
                                    {
                                        TransportSize = item.TransportSize,
                                        Length        = items.Current.Parent.Length,
                                        Data          = new byte[items.Current.Parent.Length]
                                    };
                                    result[items.Current.Parent] = parent;
                                }

                                parent.ReturnCode = item.ReturnCode;
                                item.Data.CopyTo(parent.Data.Slice(items.Current.Offset - items.Current.Parent.Offset, items.Current.Length));
                            }
                            else
                            {
                                result[items.Current] = item;
                            }
                        }
                    }
                }
                catch (TaskCanceledException)
                {
                    throw new TimeoutException();
                }
            }
            return(result.Values);
        }