private void HandleClientComm(object client)
        {
            TcpClient tcpClient = (TcpClient)client;

            byte[] Rcp = new byte[1500];

            try
            {
                NetworkStream clientStream = tcpClient.GetStream();

                int Lenght = clientStream.Read(Rcp, 0, 1500);

                if (Lenght >= 24)
                {
                    try
                    {
                        int Offset = 0;
                        Encapsulation_Packet Encapacket = new Encapsulation_Packet(Rcp, ref Offset, Lenght);
                        if (MessageReceived != null)
                        {
                            MessageReceived(this, Rcp, Encapacket, Offset, Lenght, (IPEndPoint)tcpClient.Client.RemoteEndPoint);
                        }
                    }
                    catch (Exception ex)
                    {
                        Trace.TraceError("Exception in tcp recieve: " + ex.Message);
                    }
                }
            }
            catch
            {
                // Client disconnected
                ClientsList.Remove(tcpClient);
            }
        }
        // Needed for a lot of operations
        private void RegisterSession()
        {
            if (autoConnect)
            {
                Connect();
            }

            if ((Tcpclient.IsConnected() == true) && (SessionHandle == 0))
            {
                byte[] b = new byte[] { 1, 0, 0, 0 };
                Encapsulation_Packet p = new Encapsulation_Packet(EncapsulationCommands.RegisterSession, 0, b);

                int ret;
                Encapsulation_Packet rep;
                int Offset = 0;

                lock (LockTransaction)
                    ret = Tcpclient.SendReceive(p, out rep, out Offset, ref packet);

                if (ret == 28)
                {
                    if (rep.IsOK)
                    {
                        SessionHandle = rep.Sessionhandle;
                    }
                }
            }
        }
        // Unicast ListIdentity
        public void DiscoverServers(IPEndPoint ep)
        {
            Encapsulation_Packet p = new Encapsulation_Packet(EncapsulationCommands.ListIdentity);

            p.Command = EncapsulationCommands.ListIdentity;
            udp.Send(p, ep);
            Trace.WriteLine("Send ListIdentity to " + ep.Address.ToString());
        }
 public void Send(Encapsulation_Packet SendPkt)
 {
     try
     {
         Tcpclient.Client.Send(SendPkt.toByteArray());
     }
     catch
     {
         Trace.WriteLine("Error in TcpClient Send");
         Tcpclient = null;
     }
 }
        public void UnRegisterSession()
        {
            if (SessionHandle != 0)
            {
                Encapsulation_Packet p = new Encapsulation_Packet(EncapsulationCommands.RegisterSession, SessionHandle);

                lock (LockTransaction)
                    Tcpclient.Send(p);

                SessionHandle = 0;
            }
        }
        // Unicast TCP ListIdentity for remote device, not UDP it's my choice because in such way
        // firewall could be configured only for TCP port (TCP is required for the others exchanges)
        public bool DiscoverServer()
        {
            if (autoConnect)
            {
                Connect();
            }

            try
            {
                if (Tcpclient.IsConnected())
                {
                    Encapsulation_Packet p = new Encapsulation_Packet(EncapsulationCommands.ListIdentity);
                    p.Command = EncapsulationCommands.ListIdentity;

                    int Length;
                    int Offset = 0;
                    Encapsulation_Packet Encapacket;

                    lock (LockTransaction)
                        Length = Tcpclient.SendReceive(p, out Encapacket, out Offset, ref packet);

                    Trace.WriteLine("Send ListIdentity to " + ep.Address.ToString());

                    if (Length < 26)
                    {
                        return(false);             // never appears in a normal situation
                    }
                    if ((Encapacket.Command == EncapsulationCommands.ListIdentity) && (Encapacket.Length != 0) && Encapacket.IsOK)
                    {
                        Offset += 2;
                        FromListIdentityResponse(packet, ref Offset);
                        if (DeviceArrival != null)
                        {
                            DeviceArrival(this);
                        }
                        return(true);
                    }
                    else
                    {
                        Trace.WriteLine("Unicast TCP ListIdentity fail");
                    }
                }
            }
            catch
            {
                Trace.WriteLine("Unicast TCP ListIdentity fail");
            }

            return(false);
        }
        void on_MessageReceived(object sender, byte[] packet, Encapsulation_Packet EncapPacket, int offset, int msg_length, System.Net.IPEndPoint remote_address)
        {
            // ListIdentity response
            if ((EncapPacket.Command == EncapsulationCommands.ListIdentity) && (EncapPacket.Length != 0) && EncapPacket.IsOK)
            {
                if (DeviceArrival != null)
                {
                    int NbDevices = BitConverter.ToUInt16(packet, offset);

                    offset += 2;
                    for (int i = 0; i < NbDevices; i++)
                    {
                        EnIPRemoteDevice device = new EnIPRemoteDevice(remote_address, TcpTimeout, packet, ref offset);
                        DeviceArrival(device);
                    }
                }
            }
        }
        public int SendReceive(Encapsulation_Packet SendPkt, out Encapsulation_Packet ReceivePkt, out int Offset, ref byte[] packet)
        {
            ReceivePkt = null;
            Offset     = 0;

            int Lenght = 0;

            try
            {
                // We are not working on a continous flow but with query/response datagram
                // So if something is here it's a previous lost (timeout) response packet
                // Flush all content.
                while (Tcpclient.Available != 0)
                {
                    Tcpclient.Client.Receive(packet);
                }

                Tcpclient.Client.Send(SendPkt.toByteArray());
                Lenght = Tcpclient.Client.Receive(packet);
                if (Lenght > 24)
                {
                    ReceivePkt = new Encapsulation_Packet(packet, ref Offset, Lenght);
                }
                if (Lenght == 0)
                {
                    Trace.WriteLine("Reception timeout with " + Tcpclient.Client.RemoteEndPoint.ToString());
                }
            }
            catch
            {
                Trace.WriteLine("Error in TcpClient Send Receive");
                Tcpclient = null;
            }

            return(Lenght);
        }
        private void OnReceiveData(IAsyncResult asyncResult)
        {
            System.Net.Sockets.UdpClient conn = (System.Net.Sockets.UdpClient)asyncResult.AsyncState;
            try
            {
                System.Net.IPEndPoint ep = new IPEndPoint(System.Net.IPAddress.Any, 0);
                byte[] local_buffer;
                int    rx = 0;

                try
                {
                    local_buffer = conn.EndReceive(asyncResult, ref ep);
                    rx           = local_buffer.Length;
                }
                catch (Exception) // ICMP port unreachable
                {
                    //restart data receive
                    conn.BeginReceive(OnReceiveData, conn);
                    return;
                }

                if (rx < 14)    // Sure it's too small
                {
                    //restart data receive
                    conn.BeginReceive(OnReceiveData, conn);
                    return;
                }

                try
                {
                    int Offset = 0;
                    Encapsulation_Packet Encapacket = new Encapsulation_Packet(local_buffer, ref Offset, rx);
                    //verify message
                    if (Encapacket.IsOK)
                    {
                        if (EncapMessageReceived != null)
                        {
                            EncapMessageReceived(this, local_buffer, Encapacket, Offset, rx, ep);
                        }
                    }
                    else
                    {
                        SequencedAddressItem Itempacket = new SequencedAddressItem(local_buffer, ref Offset, rx);
                        if (Itempacket.IsOK && (ItemMessageReceived != null))
                        {
                            ItemMessageReceived(this, local_buffer, Itempacket, Offset, rx, ep);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Trace.TraceError("Exception in udp recieve: " + ex.Message);
                }
                finally
                {
                    //restart data receive
                    conn.BeginReceive(OnReceiveData, conn);
                }
            }
            catch (Exception ex)
            {
                //restart data receive
                if (conn.Client != null)
                {
                    Trace.TraceError("Exception in Ip OnRecieveData: " + ex.Message);
                    conn.BeginReceive(OnReceiveData, conn);
                }
            }
        }
 public void Send(Encapsulation_Packet Packet, IPEndPoint ep)
 {
     byte[] b = Packet.toByteArray();
     m_exclusive_conn.Send(b, b.Length, ep);
 }
示例#11
0
        public EnIPNetworkStatus SendUCMM_RR_Packet(byte[] DataPath, CIPServiceCodes Service, byte[] data, ref int Offset, ref int Lenght, out byte[] packet)
        {
            packet = this.packet;

            if (autoRegisterSession)
            {
                RegisterSession();
            }
            if (SessionHandle == 0)
            {
                return(EnIPNetworkStatus.OffLine);
            }

            try
            {
                UCMM_RR_Packet       m = new UCMM_RR_Packet(Service, true, DataPath, data);
                Encapsulation_Packet p = new Encapsulation_Packet(EncapsulationCommands.SendRRData, SessionHandle, m.toByteArray());

                Encapsulation_Packet rep;
                Offset = 0;

                lock (LockTransaction)
                    Lenght = Tcpclient.SendReceive(p, out rep, out Offset, ref packet);

                String ErrorMsg = "TCP mistake";

                if (Lenght > 24)
                {
                    if ((rep.IsOK) && (rep.Command == EncapsulationCommands.SendRRData))
                    {
                        m = new UCMM_RR_Packet(packet, ref Offset, Lenght);
                        if ((m.IsOK) && (m.IsService(Service)))
                        {
                            // all is OK, and Offset is ready set at the beginning of data[]
                            return(EnIPNetworkStatus.OnLine);
                        }
                        else
                        {
                            ErrorMsg = m.GeneralStatus.ToString();
                        }
                    }
                    else
                    {
                        ErrorMsg = rep.Status.ToString();
                    }
                }

                Trace.WriteLine(Service.ToString() + " : " + ErrorMsg + " - Node " + EnIPPath.GetPath(DataPath) + " - Endpoint " + ep.ToString());

                if (ErrorMsg == "TCP mistake")
                {
                    return(EnIPNetworkStatus.OffLine);
                }

                if (Service == CIPServiceCodes.SetAttributeSingle)
                {
                    return(EnIPNetworkStatus.OnLineWriteRejected);
                }
                else
                {
                    return(EnIPNetworkStatus.OnLineReadRejected);
                }
            }
            catch
            {
                Trace.TraceWarning("Error while sending reques to endpoint " + ep.ToString());
                return(EnIPNetworkStatus.OffLine);
            }
        }