示例#1
0
        public Try <bool> WriteHoldingRegisters(byte UnitId, ushort address, IEnumerable <ushort> values)
        {
            if (values == null)
            {
                return(Try.Failure <bool>(new ArgumentNullException(nameof(values))));
            }

            var vals = values.ToList();

            if (vals.Count == 0)
            {
                return(Try.Failure <bool>(new ArgumentOutOfRangeException("Cannot write 0 holding registers", nameof(values))));
            }

            if (vals.Count == 1)
            {
                return
                    (from pdu in Try.Apply(() => CreateWriteSingleRegisterPdu(address, vals[0]))
                     from snd in _mbTransport.Send(UnitId, pdu)
                     from res in _mbTransport.Receive(UnitId)
                     select CheckWriteSingleResponse(res, MbFunctionCode.WriteSingleRegister, address, vals[0]));
            }

            return
                (from pdu in Try.Apply(() => CreateWriteMultipleRegistersPdu(address, vals))
                 from snd in _mbTransport.Send(UnitId, pdu)
                 from res in _mbTransport.Receive(UnitId)
                 select CheckWriteMultipleResponse(res, MbFunctionCode.WriteMultipleRegisters, address, vals.Count));
        }
示例#2
0
        public Try <bool> Send(byte unitId, List <byte> adu)
        {
            if (!_socket.Connected)
            {
                return(Try.Failure <bool>(new SocketException((int)SocketError.NotConnected)));
            }

            if (_socket.Poll(0, SelectMode.SelectRead))
            {
                /* at this point we assume that there can't be anything to read,
                 * so socket received FINACK some time ago
                 * http://stackoverflow.com/questions/23665917/is-it-possible-to-detect-if-a-socket-is-in-the-close-wait-state/ */
                _socket.Close();
                return(Try.Failure <bool>(new SocketException((int)SocketError.NotConnected)));
            }

            async Task <int> send(ArraySegment <byte> segment) => await _socket.SendAsync(segment, SocketFlags.None);

            var result =
                from pdu in Try.Apply(() => new ArraySegment <byte>(MbHelpers.PrependMbapHeader(unitId, _transactionId, adu).ToArray()))
                from snd in Try.Apply(() => { var sent = send(pdu); sent.Wait(); return(sent.Result); })
                select snd == pdu.Count;

            // TODO: check for exceptions and so on....

            return(result);
        }
示例#3
0
        public Try <List <ushort> > ReadInputRegisters(byte unitId, ushort address, ushort count)
        {
            var result =
                from pdu in Try.Apply(() => CreateReadPdu(MbFunctionCode.ReadInputRegisters, address, count))
                from snd in _mbTransport.Send(unitId, pdu)
                from response in _mbTransport.Receive(unitId)
                select UnwrapAnalogPdu(MbFunctionCode.ReadInputRegisters, count, response);

            return(result);
        }
示例#4
0
        public Try <List <bool> > ReadCoils(byte unitId, ushort address, ushort count)
        {
            var result =
                from pdu in Try.Apply(() => CreateReadPdu(MbFunctionCode.ReadCoils, address, count))
                from snd in _mbTransport.Send(unitId, pdu)
                from response in _mbTransport.Receive(unitId)
                select UnwrapDiscretePdu(MbFunctionCode.ReadCoils, count, response);

            return(result);
        }
示例#5
0
        public Try <bool> WriteFile(byte unitId, ushort fileNumber, byte recordSize, ushort recordNumber, byte[] file)
        {
            _logger.Trace($"fileNumber={fileNumber},  recordSize={recordSize}, recordNumber={recordNumber}");

            if (file == null)
            {
                return(Try.Failure <bool>(new ArgumentNullException(nameof(file))));
            }

            return
                (from pdu in Try.Apply(() => CreateWriteFilePdu(fileNumber, recordSize, recordNumber, file))
                 from snd in _mbTransport.Send(unitId, pdu)
                 from res in _mbTransport.Receive(unitId)
                 select CheckWriteFileResponse(res, pdu));
        }
示例#6
0
        public Try <bool> Connect()
        {
            var endpoint = new IPEndPoint(IPAddress.Parse(_ip), _port);
            async Task connect() => await _socket.ConnectAsync(endpoint);
            async Task connectWithTimeout() => await Task.WhenAny(connect(), Task.Delay(_timeout));

            var t = Try.Apply(() => connectWithTimeout().Wait());

            if (!_socket.Connected && t.IsSuccess)
            {
                // timeout
                _socket.Close();
                t = Try.Failure <bool>(new SocketException((int)SocketError.TimedOut));
            }

            return(t);
        }
示例#7
0
        public Try <bool> WriteCoils(byte unitId, ushort address, IEnumerable <bool> values)
        {
            if (values == null)
            {
                return(Try.Failure <bool>(new ArgumentNullException("values")));
            }

            var vals = values.ToList();

            if (vals.Count == 1)
            {
                return
                    (from pdu in Try.Apply(() => CreateWriteSingleCoilPdu(address, vals[0]))
                     from snd in _mbTransport.Send(unitId, pdu)
                     from res in _mbTransport.Receive(unitId)
                     select CheckWriteSingleResponse(res, MbFunctionCode.WriteSingleCoil, address, (ushort)(vals[0] ? 0xff00 : 0x0000)));
            }

            return
                (from pdu in Try.Apply(() => CreateWriteMultipleCoilsPdu(address, vals))
                 from snd in _mbTransport.Send(unitId, pdu)
                 from res in _mbTransport.Receive(unitId)
                 select CheckWriteMultipleResponse(res, MbFunctionCode.WriteMultipleCoils, address, vals.Count));
        }
示例#8
0
        public void ApplySuccArgs()
        {
            var comp = tryadd.Apply(three).Apply(four);

            Assert.Equal(seven.Try(), comp.Try());
        }
示例#9
0
        public Try <List <byte> > Receive(byte expectedUnitId)
        {
            if (!_socket.Connected)
            {
                return(Try.Failure <List <byte> >(new SocketException((int)SocketError.NotConnected)));
            }

            var buffer = new List <byte>();

            async Task receive()
            {
                do
                {
                    var segment  = new ArraySegment <byte>(new byte[512]);
                    var received = await _socket.ReceiveAsync(segment, SocketFlags.None);

                    buffer.AddRange(segment.Array.Take(received));
                } while (_socket.Available != 0);
            }

            bool rectimeout = false;
            async Task receiveWithTimeout() => await Task.WhenAny(receive(), Task.Delay(_timeout).ContinueWith(
                                                                      t => rectimeout = true));

            var result =
                from rec in Try.Apply(() => receiveWithTimeout().Wait())
                from res in Try.Apply(() =>
            {
                if (rectimeout)
                {
                    _socket.Close();
                    throw new SocketException((int)SocketError.TimedOut);
                }

                if (buffer.Count == 0)
                {
                    _socket.Close();
                    throw new SocketException((int)SocketError.NotConnected);
                }

                (var transId, var unitId, var pdu) = MbHelpers.UnwrapMbapHeader(buffer);

                if (transId != _transactionId)
                {
                    var message = $"Sent transaction id {_transactionId}, received {transId}. Dropping response.";
                    _logger.Debug(message);
                    throw new Exception(message);
                }

                if (unitId != expectedUnitId)
                {
                    var message = $"Sent unit id {expectedUnitId}, received {unitId}. Dropping response.";
                    _logger.Debug(message);
                    throw new Exception(message);
                }

                return(pdu);
            })
                select res;

            NextTransaction();

            return(result);
        }
示例#10
0
 /// <summary>
 /// Apply Try values to a Try function of arity 2
 /// </summary>
 /// <param name="self">Try function</param>
 /// <param name="arg1">Try argument</param>
 /// <param name="arg2">Try argument</param>
 /// <returns>Returns the result of applying the Try arguments to the Try function</returns>
 public static Try <R> apply <T1, T2, R>(Try <Func <T1, T2, R> > self, Try <T1> arg1, Try <T2> arg2) =>
 self.Apply(arg1, arg2);
示例#11
0
 /// <summary>
 /// Apply a Try value to a Try function of arity 2
 /// </summary>
 /// <param name="self">Try function</param>
 /// <param name="arg">Try argument</param>
 /// <returns>Returns the result of applying the Try argument to the Try function:
 /// a Try function of arity 1</returns>
 public static Try <Func <T2, R> > apply <T1, T2, R>(Try <Func <T1, T2, R> > self, Try <T1> arg) =>
 self.Apply(arg);
示例#12
0
 /// <summary>
 /// Apply a Try value to a Try function
 /// </summary>
 /// <param name="self">Try function</param>
 /// <param name="arg">Try argument</param>
 /// <returns>Returns the result of applying the Try argument to the Try function</returns>
 public static Try <R> apply <T, R>(Try <Func <T, R> > self, Try <T> arg) =>
 self.Apply(arg);