internal virtual void Disconnect() { if (Disposed) { return; } ioc?.RemoveChannel(this); lock (ConnectionLock) { if (Status != ChannelStatus.CONNECTED && Status != ChannelStatus.CONNECTING) { 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 = MonitoredElements; p.Parameter1 = SID; p.Parameter2 = CID; p.SetUInt16(12 + 16, (ushort)MonitorMask); if (ioc != null) { try { ioc.Send(p); } catch { Disconnect(); } } else { Disconnect(); } }); } } }
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; Status = ChannelStatus.CONNECTED; ConnectionEvent.Set(); } } } } if (SID != 0) { //Console.WriteLine("SID " + SID + " STATUS CHANGED"); if (StatusChanged != null) { StatusChanged(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); //Status = ChannelStatus.CONNECTING; if (ioc != null) { ioc.Send(packet); } else { Disconnect(); return; } lock (ElapsedTimings) { if (!ElapsedTimings.ContainsKey("SendCreateChannel")) { ElapsedTimings.Add("SendCreateChannel", Stopwatch.Elapsed); } } }
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 ex) { } } } 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: { //Console.WriteLine("Received create channel"); 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; } } }