示例#1
0
        internal virtual void Disconnect( )
        {
            if (Disposed)
            {
                return;
            }
            if (ioc != null)
            {
                ioc.RemoveChannel(this);
            }
            lock ( ConnectionLock )
            {
                if (Status != ChannelStatus.CONNECTED)
                {
                    return;
                }
                Status          = ChannelStatus.DISCONNECTED;
                StartSearchTime = DateTime.Now;
                ioc             = null;
                SID             = 0;

                if (PrivMonitorChanged != null)
                {
                    AfterConnect(
                        action => {
                        if (MonitoredType == null)
                        {
                            return;
                        }

                        DataPacket p = DataPacket.Create(
                            16 + 16
                            );
                        p.Command    = (ushort)CommandID.CA_PROTO_EVENT_ADD;
                        p.DataType   = (ushort)TypeHandling.Lookup[MonitoredType];
                        p.DataCount  = ChannelDataCount;
                        p.Parameter1 = SID;
                        p.Parameter2 = CID;

                        p.SetUInt16(
                            12 + 16,
                            (ushort)MonitorMask
                            );

                        if (ioc != null)
                        {
                            ioc.Send(p);
                        }
                        else
                        {
                            Disconnect();
                        }
                    }
                        );
                }
            }
        }
示例#2
0
        public override void ProcessData(DataPacket packet)
        {
            lock (lockObject)
            {
                switch ((CommandID)packet.Command)
                {
                case CommandID.CA_PROTO_VERSION:
                    break;

                case CommandID.CA_PROTO_ECHO:
                    // We sent the echo... we should therefore avoid to answer it
                    if (Pipe.GeneratedEcho)
                    {
                        Pipe.GeneratedEcho = false;
                    }
                    else
                    {
                        // Send back the echo
                        (
                            (ClientTcpReceiver)Pipe[0]
                        ).Send(packet);
                    }
                    break;

                case CommandID.CA_PROTO_SEARCH:
                {
                    int port = packet.DataType;
                    // Console.WriteLine("Answer from: " + packet.Sender.Address + ":" + port) ;
                    Channel channel = Client.GetChannelByCid(packet.Parameter2);
                    if (channel == null)
                    {
                        return;
                    }
                    IPAddress addr = packet.Sender.Address;
                    if (packet.Parameter1 != 0xFFFFFFFF)
                    {
                        addr = IPAddress.Parse(
                            "" + packet.Data[8] + "." + packet.Data[8 + 1] + "." + packet.Data[8 + 2] + "." + packet.Data[8 + 3]
                            );
                    }
                    channel.SearchAnswerFrom = packet.Sender.Address;
                    if (Client.Configuration.DebugTiming)
                    {
                        lock (channel.ElapsedTimings)
                        {
                            if (!channel.ElapsedTimings.ContainsKey("SearchResponse"))
                            {
                                channel.ElapsedTimings.Add(
                                    "SearchResponse",
                                    channel.Stopwatch.Elapsed
                                    );
                            }
                        }
                    }
                    if (channel != null)
                    {
                        try
                        {
                            channel.SetIoc(
                                Client.GetIocConnection(
                                    new IPEndPoint(
                                        addr,
                                        port
                                        )
                                    )
                                );
                        }
                        catch (Exception)
                        {
                        }
                    }
                }
                break;

                case CommandID.CA_PROTO_ACCESS_RIGHTS:
                {
                    Channel channel = Client.GetChannelByCid(packet.Parameter1);
                    if (channel != null)
                    {
                        channel.AccessRight = (AccessRights)(
                            (ushort)packet.Parameter2
                            );
                    }
                    break;
                }

                case CommandID.CA_PROTO_CREATE_CHAN:
                {
                    Channel channel = Client.GetChannelByCid(packet.Parameter1);
                    if (channel != null)
                    {
                        channel.SetServerChannel(
                            packet.Parameter2,
                            (EpicsType)packet.DataType,
                            packet.DataCount
                            );
                    }
                    break;
                }

                case CommandID.CA_PROTO_READ_NOTIFY:
                {
                    ClientTcpReceiver ioc = (ClientTcpReceiver)Pipe[0];
                    Channel           channel;
                    lock (ioc.PendingIo)
                    {
                        channel = ioc.PendingIo[packet.Parameter2];
                    }
                    if (channel != null)
                    {
                        channel.SetGetRawValue(packet);
                    }
                    break;
                }

                case CommandID.CA_PROTO_WRITE_NOTIFY:
                {
                    ClientTcpReceiver ioc = (ClientTcpReceiver)Pipe[0];
                    Channel           channel;
                    lock (ioc.PendingIo)
                    {
                        channel = ioc.PendingIo[packet.Parameter2];
                    }
                    if (channel != null)
                    {
                        channel.SetWriteNotify();
                    }
                    break;
                }

                case CommandID.CA_PROTO_EVENT_ADD:
                {
                    Channel channel = Client.GetChannelByCid(packet.Parameter2);
                    if (channel != null)
                    {
                        channel.UpdateMonitor(packet);
                    }
                    break;
                }

                case CommandID.CA_PROTO_SERVER_DISCONN:
                {
                    List <Channel>    connectedChannels;
                    ClientTcpReceiver receiver = (
                        (ClientTcpReceiver)Pipe[0]
                        );
                    lock (receiver.ConnectedChannels)
                    {
                        connectedChannels = receiver.ConnectedChannels.Where(
                            row => row.CID == packet.Parameter1
                            ).ToList();
                    }
                    foreach (Channel channel in connectedChannels)
                    {
                        lock (receiver.ChannelSID)
                        {
                            receiver.ChannelSID.Remove(channel.ChannelName);
                        }
                        channel.Disconnect();
                    }
                }
                break;

                default:
                    break;
                }
            }
        }
示例#3
0
        internal void SetIoc(DataPipe pipe)
        {
            ClientTcpReceiver tcpReceiver = (ClientTcpReceiver)pipe[0];

            tcpReceiver.AddChannel(this);
            lock ( ConnectionLock )
            {
                if (!Client.Searcher.Contains(this))
                {
                    return;
                }

                Client.Searcher.Remove(this);
                SID = 0;

                ioc = tcpReceiver;
                lock (ioc.ChannelSID)
                {
                    // Console.WriteLine(ioc.ChannelSID.Count) ;
                    // Channel already known
                    if (ioc.ChannelSID.ContainsKey(ChannelName))
                    {
                        SID = ioc.ChannelSID[ChannelName];
                        // Console.WriteLine("Here") ;
                        Channel chan = ioc.ConnectedChannels.FirstOrDefault(
                            row =>
                            row.ChannelName == ChannelName &&
                            row.ChannelDataCount != 0
                            );
                        if (chan != null)
                        {
                            this.ChannelDataCount   = chan.ChannelDataCount;
                            this.channelDefinedType = chan.channelDefinedType;
                            this.ChannelDataCount   = chan.ChannelDataCount;
                            this.channelDefinedType = chan.ChannelDefinedType;
                            Status = ChannelStatus.CONNECTED;
                            ConnectionEvent.Set();
                        }
                    }
                }
            }
            if (SID != 0)
            {
                // Console.WriteLine("SID " + SID + " STATUS CHANGED") ;
                StatusChanged?.Invoke(this, Status);
                return;
            }
            if (Client.Configuration.DebugTiming)
            {
                lock ( ElapsedTimings )
                {
                    if (!ElapsedTimings.ContainsKey("IocConnection"))
                    {
                        ElapsedTimings.Add(
                            "IocConnection",
                            Stopwatch.Elapsed
                            );
                    }
                }
            }

            // We need to create the channel
            int padding;

            if (ChannelName.Length % 8 == 0)
            {
                padding = 8;
            }
            else
            {
                padding = (
                    8
                    - (ChannelName.Length % 8)
                    );
            }

            DataPacket packet = DataPacket.Create(
                16 + ChannelName.Length + padding
                );

            packet.Command    = (ushort)CommandID.CA_PROTO_CREATE_CHAN;
            packet.DataType   = 0;
            packet.DataCount  = 0;
            packet.Parameter1 = cid;
            packet.Parameter2 = (uint)CAConstants.CA_MINOR_PROTOCOL_REVISION;
            packet.SetDataAsString(ChannelName);

            if (ioc != null)
            {
                ioc.Send(packet);
            }
            else
            {
                Disconnect();
                return;
            }

            lock ( ElapsedTimings )
            {
                if (!ElapsedTimings.ContainsKey("SendCreateChannel"))
                {
                    ElapsedTimings.Add(
                        "SendCreateChannel",
                        Stopwatch.Elapsed
                        );
                }
            }
        }