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)); }
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); }
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); }
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); }
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)); }
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); }
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)); }
public void ApplySuccArgs() { var comp = tryadd.Apply(three).Apply(four); Assert.Equal(seven.Try(), comp.Try()); }
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); }
/// <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);
/// <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);
/// <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);