Example #1
0
        /// <summary>
        /// Creates a <c>BidMessage</c> object with its encoding in a byte array.
        /// </summary>
        /// <param name="function">the message's function code.</param>
        /// <param name="message">the message encoded in a byte array.</param>
        /// <param name="offset">the start index in the byte array.</param>
        /// <param name="count">the actual length of message.</param>
        /// <returns>An initialized <c>BidMessage</c> object.</returns>
        /// <exception cref="System.NotSupportedException"><c>function</c> is not supported or the message is malformed.</exception>
        public static BidMessage Create(FunctionCodes function, byte[] message, int offset, int count)
        {
            BidMessage result = null;

            switch (function)
            {
            case FunctionCodes.Quote:
                result = CreateQuoteMessage(message, offset, count);
                break;

            case FunctionCodes.SessionKeyReply:
                result = new SessionKeyReplyMessage(message, offset);
                break;

            case FunctionCodes.LoginReply:
                result = new LoginReplyMessage(message, offset);
                break;

            default:
                throw new NotSupportedException("Unsuppoted message function code.");
            }

            Debug.Assert(result != null);
            return(result);
        }
Example #2
0
 public MessageFormat(byte unitId, FunctionCodes code, byte[] data)
 {
     this.UnitID       = unitId;
     this.FunctionCode = code;
     this.Rawdata      = new byte[data.Length];
     Array.Copy(data, 0, this.Rawdata, 0, this.Rawdata.Length);
 }
Example #3
0
 public bool IsInFunction(string function)
 {
     if (FunctionCodes.Any(r => function.Contains(r)))
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
Example #4
0
        /// <summary>按功能码读取</summary>
        /// <param name="code"></param>
        /// <param name="host"></param>
        /// <param name="address"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        /// <exception cref="NotSupportedException"></exception>
        public virtual Byte[] Read(FunctionCodes code, Byte host, UInt16 address, UInt16 count)
        {
            switch (code)
            {
            case FunctionCodes.ReadCoil: return(ReadCoil(host, address, count));

            case FunctionCodes.ReadDiscrete: return(ReadDiscrete(host, address, count));

            case FunctionCodes.ReadRegister: return(ReadRegister(host, address, count));

            case FunctionCodes.ReadInput: return(ReadInput(host, address, count));

            default:
                break;
            }

            throw new NotSupportedException();
        }
Example #5
0
        /// <summary>按功能码写入</summary>
        /// <param name="code"></param>
        /// <param name="host"></param>
        /// <param name="address"></param>
        /// <param name="values"></param>
        /// <returns></returns>
        public virtual Byte[] Write(FunctionCodes code, Byte host, UInt16 address, UInt16[] values)
        {
            switch (code)
            {
            case FunctionCodes.WriteCoil: return(WriteCoil(host, address, values[0]));

            case FunctionCodes.WriteRegister: return(WriteRegister(host, address, values[0]));

            case FunctionCodes.WriteCoils: return(WriteCoils(host, address, values));

            case FunctionCodes.WriteRegisters: return(WriteRegisters(host, address, values));

            default:
                break;
            }

            throw new NotSupportedException();
        }
Example #6
0
        /// <summary>发送两字节命令,并接收返回</summary>
        /// <param name="host"></param>
        /// <param name="code"></param>
        /// <param name="address"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public override Byte[] SendCommand(Byte host, FunctionCodes code, UInt16 address, Object value)
        {
            Open();

            var cmd = new Byte[8];

            cmd[0] = host;
            cmd[1] = (Byte)code;
            cmd[2] = (Byte)(address >> 8);
            cmd[3] = (Byte)(address & 0xFF);

            if (value is UInt16 v)
            {
                cmd[4] = (Byte)(v >> 8);
                cmd[5] = (Byte)(v & 0xFF);
            }

            var crc = Crc(cmd, 0, cmd.Length - 2);

            cmd[6] = (Byte)(crc & 0xFF);
            cmd[7] = (Byte)(crc >> 8);

            {
                using var span = Tracer?.NewSpan("modbus:SendCommand", cmd.ToHex());

                WriteLog("{0}=> {1}", PortName, cmd.ToHex("-"));
                _port.Write(cmd, 0, cmd.Length);
                Thread.Sleep(10);
            }

            // 串口速度较慢,等待收完数据
            WaitMore(_port);

            try
            {
                using var span = Tracer?.NewSpan("modbus:ReceiveCommand");

                var rs = new Byte[32];
                var c  = _port.Read(rs, 0, rs.Length);
                rs = rs.ReadBytes(0, c);
                WriteLog("{0}<= {1}", PortName, rs.ToHex("-"));

                if (span != null)
                {
                    span.Tag = rs.ToHex();
                }

                if (rs.Length < 2 + 2)
                {
                    return(null);
                }

                // 校验Crc
                crc = Crc(rs, 0, rs.Length - 2);
                var crc2 = rs.ToUInt16(rs.Length - 2);
                if (crc != crc2)
                {
                    WriteLog("Crc Error {0:X4}!={1:X4} !", crc, crc2);
                }

                return(rs.ReadBytes(2, rs.Length - 2 - 2));
            }
            catch (TimeoutException) { return(null); }
        }
Example #7
0
        /// <summary>发送两字节命令,并接收返回</summary>
        /// <param name="host"></param>
        /// <param name="code"></param>
        /// <param name="address"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public override Byte[] SendCommand(Byte host, FunctionCodes code, UInt16 address, Object value)
        {
            Open();

            var tid = Interlocked.Increment(ref _transactionId);

            var msg = new ModbusMessage
            {
                TransactionId = (UInt16)tid,
                ProtocolId    = ProtocolId,
                Host          = host,
                Code          = code,
                Address       = address,
                //Count = value
            };

            if (value is UInt16 v)
            {
                msg.Count = v;
            }
            else if (value is Packet pk)
            {
                msg.Payload = pk;
            }
            else if (value is Byte[] buf)
            {
                msg.Payload = buf;
            }

            WriteLog("=> {0}", msg);
            var cmd = msg.ToPacket().ToArray();

            {
                using var span = Tracer?.NewSpan("modbus:SendCommand", cmd.ToHex());

                _stream.Write(cmd, 0, cmd.Length);
                Thread.Sleep(10);
            }

            using var span2 = Tracer?.NewSpan("modbus:ReceiveCommand");
            try
            {
                var buf = new Byte[BufferSize];
                var c   = _stream.Read(buf, 0, buf.Length);
                buf = buf.ReadBytes(0, c);

                if (span2 != null)
                {
                    span2.Tag = buf.ToHex();
                }

                var rs = ModbusMessage.Read(buf, true);
                if (rs == null)
                {
                    return(null);
                }

                WriteLog("<= {0}", rs);

                return(rs.Payload?.ToArray());
            }
            catch (Exception ex)
            {
                span2?.SetError(ex, null);
                if (ex is TimeoutException)
                {
                    return(null);
                }
                throw;
            }
        }
Example #8
0
 /// <summary>发送两字节命令,并接收返回</summary>
 /// <param name="host">主机。一般是1</param>
 /// <param name="code">功能码</param>
 /// <param name="address">地址。例如0x0002</param>
 /// <param name="value">数据值</param>
 /// <returns></returns>
 public abstract Byte[] SendCommand(Byte host, FunctionCodes code, UInt16 address, Object value);