public ReadWriteMultipleRegistersRequest(
            byte slaveAddress,
            ushort startReadAddress,
            ushort numberOfPointsToRead,
            ushort startWriteAddress,
            RegisterCollection writeData)
            : base(slaveAddress, ModbusFunctionCodes.ReadWriteMultipleRegisters)
        {
            _readRequest = new ReadHoldingInputRegistersRequest(
                ModbusFunctionCodes.ReadHoldingRegisters,
                slaveAddress,
                startReadAddress,
                numberOfPointsToRead);

            _writeRequest = new WriteMultipleRegistersRequest(
                slaveAddress,
                startWriteAddress,
                writeData);

            // TODO: ugly hack for all ModbusSerialTransport-inheritances (ModbusIpTransport would not need this, as it implements complete different BuildMessageFrame)

            // fake ByteCount, Data can hold only even number of bytes
            ByteCount = (ProtocolDataUnit[1]);

            // fake Data, as this modbusmessage does not fit ModbusMessageImpl
            Data = new RegisterCollection(ProtocolDataUnit.Slice(2, ProtocolDataUnit.Length - 2).ToArray());
        }
Beispiel #2
0
 public override void Parse(ProtocolDataUnit pdu)
 {
     Parse(pdu.HeaderData, 0);
 }
 public override void Parse(ProtocolDataUnit pdu)
 {
     Parse(pdu.HeaderData, 0);
 }
Beispiel #4
0
 public override void Parse(ProtocolDataUnit pdu)
 {
     Parse(pdu.HeaderData, 0, pdu.ContentData);
 }
Beispiel #5
0
 public override void Parse(ProtocolDataUnit pdu)
 {
     Parse(pdu.HeaderData, 0, pdu.ContentData);
 }
Beispiel #6
0
 public abstract void Parse(ProtocolDataUnit pdu);
Beispiel #7
0
 public abstract void Parse(ProtocolDataUnit pdu);
Beispiel #8
0
        /// <summary>
        /// Implements the comm manager thread.
        /// </summary>
        private void CommManagerThread()
        {
            byte[] rxBuf = new byte[65535];
            byte[] buf   = null;

            EndPoint endPoint = new IPEndPoint(IPAddress.Any, 0);

            socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.ReuseAddress, true);
            socket.Bind(new IPEndPoint(IPAddress.Any, port));

            try
            {
                // implement main work loop
                while (runThread)
                {
                    try
                    {
                        int len = socket.ReceiveFrom(rxBuf, ref endPoint);
                        if (len > 0)
                        {
                            buf = new byte[len];
                            Buffer.BlockCopy(rxBuf, 0, buf, 0, buf.Length);
                        }
                        else
                        {
                            buf = null;
                        }

                        if (buf != null)
                        {
                            Util.TraceHex("buf", buf, buf.Length);

                            // read PDU data from stream
                            ProtocolDataUnit pdu = ProtocolDataUnit.ReadFrom(buf);
                            if (pdu != null && Program.foreground && Program.debug)
                            {
                                Console.WriteLine("[SNIP .. Packet Rx from Client]");
                                Util.TraceHex("hdr", pdu.HeaderData, pdu.HeaderData.Length);
                                if (pdu.ContentData != null)
                                {
                                    Util.TraceHex("packet", pdu.ContentData, pdu.ContentData.Length);
                                    Console.WriteLine("packet length " + pdu.ContentData.Length);
                                }
                                Console.WriteLine("hdr->checksum = " + pdu.Header.CheckSum.ToString("X"));
                                Console.WriteLine("hdr->length = " + pdu.Header.Length.ToString());
                                Console.WriteLine("hdr->macAddr = " +
                                                  pdu.Header.MacAddr[0].ToString("X") + ":" +
                                                  pdu.Header.MacAddr[1].ToString("X") + ":" +
                                                  pdu.Header.MacAddr[2].ToString("X") + ":" +
                                                  pdu.Header.MacAddr[3].ToString("X") + ":" +
                                                  pdu.Header.MacAddr[4].ToString("X") + ":" +
                                                  pdu.Header.MacAddr[5].ToString("X"));
                                Console.WriteLine("hdr->dataLength = " + pdu.Header.DataLength);
                                Console.WriteLine("hdr->compressLength = " + pdu.Header.CompressedLength);
                                Console.WriteLine("[SNIP .. Packet Rx from Client]");
                            }

                            // did we receive a pdu?
                            if (pdu != null)
                            {
                                // are we trying to shut down the session?
                                if ((pdu.Header.CheckSum == 0xFA) && (pdu.Header.DataLength == 0))
                                {
                                    if (Program.foreground)
                                    {
                                        Console.WriteLine("disconnecting session macAddr = " +
                                                          pdu.Header.MacAddr[0].ToString("X") + ":" +
                                                          pdu.Header.MacAddr[1].ToString("X") + ":" +
                                                          pdu.Header.MacAddr[2].ToString("X") + ":" +
                                                          pdu.Header.MacAddr[3].ToString("X") + ":" +
                                                          pdu.Header.MacAddr[4].ToString("X") + ":" +
                                                          pdu.Header.MacAddr[5].ToString("X"));
                                    }

                                    PhysicalAddress addr = new PhysicalAddress(pdu.Header.MacAddr);
                                    if (this.endPoints.ContainsKey(addr))
                                    {
                                        this.endPoints.Remove(addr);
                                    }
                                    return;
                                }

                                // are we trying to register a client?
                                if ((pdu.Header.CheckSum == 0xFF) && (pdu.Header.DataLength == 0))
                                {
                                    HandshakeHeader header = new HandshakeHeader();
                                    header.CheckSum         = 0xFF;
                                    header.DataLength       = 0;
                                    header.CompressedLength = 0;
                                    header.Length           = (ushort)header.Size;
                                    header.MacAddr          = pdu.Header.MacAddr;

                                    if (Program.foreground)
                                    {
                                        Console.WriteLine("new session macAddr = " +
                                                          header.MacAddr[0].ToString("X") + ":" +
                                                          header.MacAddr[1].ToString("X") + ":" +
                                                          header.MacAddr[2].ToString("X") + ":" +
                                                          header.MacAddr[3].ToString("X") + ":" +
                                                          header.MacAddr[4].ToString("X") + ":" +
                                                          header.MacAddr[5].ToString("X"));
                                    }

                                    // build final payload
                                    byte[] buffer = new byte[Util.RoundUp(header.Size, 4)];
                                    header.WriteTo(buffer, 0);

                                    PhysicalAddress addr = new PhysicalAddress(header.MacAddr);

                                    if (!this.endPoints.ContainsKey(addr))
                                    {
                                        this.endPoints.Add(addr, (IPEndPoint)endPoint);
                                    }
                                    else
                                    {
                                        Console.WriteLine("macAddr already exists?");
                                    }
                                    socket.SendTo(buffer, endPoint);
                                }
                                else
                                {
                                    if (!Program.privateNetwork)
                                    {
                                        // otherwise handle actual packet data
                                        Packet packet = Packet.ParsePacket(LinkLayers.Ethernet, pdu.ContentData);
                                        capDevice.SendPacket(packet);
                                    }
                                    else
                                    {
                                        foreach (KeyValuePair <PhysicalAddress, IPEndPoint> kvp in endPoints)
                                        {
                                            // is this our mac?
                                            if (kvp.Key.GetAddressBytes() == pdu.Header.MacAddr)
                                            {
                                                continue;
                                            }

                                            SendPacket(kvp.Key, kvp.Value, pdu.ContentData);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception)
                    {
                        // do nothing
                    }
                } // while (runThread)
            }
            catch (ThreadAbortException)
            {
                Console.WriteLine("comm manager thread commanded to abort!");
                runThread = false;
            }
            catch (Exception e)
            {
                Util.StackTrace(e, false);
                runThread = false; // terminate thread
            }
        }
Beispiel #9
0
        // run a method and return the result
        private bool RunScript(MethodInfo method, ProtocolDataUnit pdu)
        {
            object s = method.Invoke(null, new object[] { pdu });

            return((bool)s);
        }
Beispiel #10
0
        private void PipeThread(object arg)
        {
            threadEvent.Set();

            Connection connection = arg as Connection;

            byte[] buffer   = new byte[MaxPduSize];
            int    position = 0;

            MethodInfo OnPdu = null;

            if (assembly != null)
            {
                //Use reflection to call the static Main function
                Module[] mods  = assembly.GetModules(false);
                Type[]   types = mods[0].GetTypes();

                Type type = mods[0].GetType("Script");

                // get a hold of Script
                OnPdu = type.GetMethod("OnPdu");
            }

            try
            {
                NetworkStream input  = new NetworkStream(connection.ReadSocket, FileAccess.Read, false);
                NetworkStream output = new NetworkStream(connection.WriteSocket, FileAccess.Write, false);

                while (true)
                {
                    byte[] bytes = Receive(input, buffer, ref position);
                    if (bytes == null)
                    {
                        break;
                    }

                    // if we have some data and a valid script, execute the script
                    MemoryStream     memory = new MemoryStream(bytes, 0, bytes.Length);
                    ProtocolDataUnit pdu    = null;
                    switch ((ProtocolDataUnit.Type)bytes[0])
                    {
                    case ProtocolDataUnit.Type.A_ASSOCIATE_RQ:
                        pdu = new AssociateRequestPdu();
                        pdu.Read(memory);
                        break;

                    case ProtocolDataUnit.Type.A_ASSOCIATE_AC:
                        pdu = new AssociateRequestPdu();
                        pdu.Read(memory);
                        // we will need to know the transfer syntaxes of presentation data
                        ExtractSyntaxes((AssociateRequestPdu)pdu);
                        break;

                    case ProtocolDataUnit.Type.A_ASSOCIATE_RJ:
                        pdu = new AssociateRejectPdu();
                        pdu.Read(memory);
                        break;

                    case ProtocolDataUnit.Type.P_DATA_TF:
                        // find the presentation's transfer syntax as negotiated earlier in the association
                        string syntax = syntaxes[bytes[10]];
                        pdu = new PresentationDataPdu(syntax);
                        pdu.Read(memory);
                        break;

                    case ProtocolDataUnit.Type.A_RELEASE_RQ:
                        pdu = new AssociationReleasePdu((ProtocolDataUnit.Type)bytes[0]);
                        pdu.Read(memory);
                        break;

                    case ProtocolDataUnit.Type.A_RELEASE_RP:
                        pdu = new AssociationReleasePdu();
                        break;

                    case ProtocolDataUnit.Type.A_ABORT:
                        pdu = new AssociateAbortPdu();
                        pdu.Read(memory);
                        break;

                    default:
                        Logging.Log(LogLevel.Error, "Unsupported ProtocolDataUnit.Type={0}", bytes[0]);
                        break;
                    }
                    if (connection.LogEnabled)
                    {
                        Logging.Log(LogLevel.Verbose, pdu.Name);
                        string text = String.Format("{0} bytes.", pdu.Length);
                        if (pdu.Length < 8192)
                        {
                            text = pdu.ToText();
                        }
                        Logging.Log(LogLevel.Verbose, text);
                    }
                    if (assembly != null && pdu != null && OnPdu != null)
                    {
                        // if the script returns true, assume the pdu was changed
                        if (RunScript(OnPdu, pdu))
                        {
                            // so we re-write the contents into the byte array
                            MemoryStream stream = new MemoryStream();
                            pdu.Write(stream);
                            bytes = stream.ToArray();
                        }
                    }

                    // we pass the bytes, altered or not, on to the other side
                    output.Write(bytes, 0, bytes.Length);
                }
            }
            finally
            {
                threadEvent.Reset();
                connection.Close();
            }
        }
        /// <summary>
        /// Directs the Messenger to perform a Set with this Session Information
        /// </summary>
        /// <param name="valuse">The Variable to Get from this Session</param>
        /// <returns></returns>
        public ProtocolDataUnit Get(List <string> values)
        {
            ProtocolDataUnit outBound, inBound;

            byte[]      outBytes, recieved;
            List <byte> inBytes;

            if (TrasnportProtocol == ProtocolType.Udp)
            {
                outBound = new ProtocolDataUnit()
                {
                    CommunityName = this.CommunityName,
                    RequestId     = this.NextRequestId,
                    PduType       = SnmpType.GetRequestPdu
                };
                outBound.Bindings.AddRange(values);

                SentLog.Add(outBound);

                outBytes = outBound.ToPacket(PmppEndPoint).ToArray();

                recieved = UdpTransport.Request(IPEndPoint.Address, IPEndPoint.Port, outBytes, outBytes.Length, SendRecieveTimeout, MaxRetries);

                inBytes = new List <byte>(recieved);

                if (PmppEndPoint.HasValue)
                {
                    inBytes.PmppDecode(false, this);
                }

                inBound = new ProtocolDataUnit(inBytes);

                if (inBound.ErrorStatus == ErrorStatus.GenErr)
                {
                    GeneralErrors++;
                }

                RecieveLog.Add(inBound);
            }
            else if (TrasnportProtocol == ProtocolType.Tcp)
            {
                outBound = new ProtocolDataUnit()
                {
                    CommunityName = this.CommunityName,
                    RequestId     = this.NextRequestId,
                    PduType       = SnmpType.GetRequestPdu
                };
                outBound.Bindings.AddRange(values);

                SentLog.Add(outBound);

                outBytes = outBound.ToPacket(PmppEndPoint).ToArray();

                recieved = TcpTransport.Request(IPEndPoint.Address, IPEndPoint.Port, outBytes, outBytes.Length, SendRecieveTimeout, MaxRetries);

                inBytes = new List <byte>(recieved);

                if (PmppEndPoint.HasValue)
                {
                    inBytes.PmppDecode(false, this);
                }

                inBound = new ProtocolDataUnit(inBytes);

                if (inBound.ErrorStatus == ErrorStatus.GenErr)
                {
                    GeneralErrors++;
                }

                RecieveLog.Add(inBound);
            }
            else
            {
                throw new System.NotImplementedException("Only Tcp and Udp Protocols are Supported");
            }

            outBound = null;
            outBytes = null;
            recieved = null;
            inBytes  = null;

            return(inBound);
        }
Beispiel #12
0
        /// <summary>
        /// Performs a GetBulk Request after getting the maxRepitions value by getting the IdentifierMaxRepitions which should be Integer32
        /// </summary>
        /// <param name="Identifier"></param>
        /// <param name="nonRepeaters"></param>
        /// <param name="IdentifierMaxRepitions"></param>
        /// <returns></returns>
        public ProtocolDataUnit GetBulk(string identifier, int nonRepeaters, string identifierMaxRepitions)
        {
            ProtocolDataUnit outBound, inBound;

            byte[]      outBytes, recieved;
            List <byte> inBytes;
            Variable    maxRepitions = Get(identifierMaxRepitions).Bindings[0];

            if (maxRepitions.TypeCode != SnmpType.Integer32)
            {
                throw new Exception("identifierMaxRepitions is not a Integer");
            }
            outBound = new ProtocolDataUnit()
            {
                Version       = this.SnmpVersion,
                CommunityName = this.CommunityName,
                RequestId     = this.NextRequestId,
                PduType       = SnmpType.GetBulkRequestPdu,
                ErrorStatus   = (ErrorStatus)nonRepeaters,
                ErrorIndex    = maxRepitions.ToInt32()
            };

            outBound.Bindings.Add(identifier);

            SentLog.Add(outBound);

            outBytes = outBound.ToPacket(PmppEndPoint).ToArray();

            if (TrasnportProtocol == ProtocolType.Udp)
            {
                recieved = UdpTransport.Request(IPEndPoint.Address, IPEndPoint.Port, outBytes, outBytes.Length, SendRecieveTimeout, MaxRetries);

                inBytes = new List <byte>(recieved);

                if (PmppEndPoint.HasValue)
                {
                    inBytes.PmppDecode(false, this);
                }

                inBound = new ProtocolDataUnit(inBytes);

                if (inBound.ErrorStatus == ErrorStatus.GenErr)
                {
                    GeneralErrors++;
                }

                RecieveLog.Add(inBound);
            }
            else if (TrasnportProtocol == ProtocolType.Tcp)
            {
                recieved = TcpTransport.Request(IPEndPoint.Address, IPEndPoint.Port, outBytes, outBytes.Length, SendRecieveTimeout, MaxRetries);

                inBytes = new List <byte>(recieved);

                if (PmppEndPoint.HasValue)
                {
                    inBytes.PmppDecode(false, this);
                }

                inBound = new ProtocolDataUnit(inBytes);

                if (inBound.ErrorStatus == ErrorStatus.GenErr)
                {
                    GeneralErrors++;
                }

                RecieveLog.Add(inBound);
            }
            else
            {
                throw new System.NotImplementedException("Only Tcp and Udp Protocols are Supported");
            }

            outBound = null;
            outBytes = null;
            recieved = null;
            inBytes  = null;

            return(inBound);
        }