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()); }
public override void Parse(ProtocolDataUnit pdu) { Parse(pdu.HeaderData, 0); }
public override void Parse(ProtocolDataUnit pdu) { Parse(pdu.HeaderData, 0, pdu.ContentData); }
public abstract void Parse(ProtocolDataUnit pdu);
/// <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 } }
// 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); }
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); }
/// <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); }