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(); } } ); } } }
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; } } }
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 ); } } }