internal void RegisterEvent(CAServer server, uint sid, uint subscriptionId, int dataCount, Constants.EpicsType type) { CARecord record = ((ServerTcpReceiver)this.Pipe.FirstFilter).FindRecord(server, sid); string property = ((ServerTcpReceiver)this.Pipe.FirstFilter).FindProperty(server, sid); DataPacket response = DataPacketBuilder.Encode( type, record[property], record, dataCount ); response.Command = (ushort)CommandID.CA_PROTO_EVENT_ADD; response.Parameter1 = 1; response.Parameter2 = (uint)subscriptionId; ((TcpReceiver)this.Pipe.FirstFilter).Send(response); EventHandler newEvent = delegate(object obj, EventArgs evt) { if (!record.IsDirty) { return; } DataPacket p = DataPacketBuilder.Encode(type, record[property], record, dataCount); p.Command = (ushort)CommandID.CA_PROTO_EVENT_ADD; p.Parameter1 = 1; p.Parameter2 = (uint)subscriptionId; ((TcpReceiver)this.Pipe.FirstFilter).Send(p); }; record.RecordProcessed += newEvent; lock (subscribedEvents) { subscribedEvents.Add( subscriptionId, new EpicsEvent { Handler = newEvent, Record = record, DataCount = dataCount, EpicsType = type, SID = sid } ); } }
internal void RegisterEvent(CAServer server, uint sid, uint subscriptionId, int nbElements, EpicsType type, MonitorMask mask) { CARecord record = ((ServerTcpReceiver)this.Pipe.FirstFilter).FindRecord(server, sid); string property = ((ServerTcpReceiver)this.Pipe.FirstFilter).FindProperty(server, sid); DataPacket response = DataPacketBuilder.Encode(type, record[property], record, (nbElements == 0) ? record.ElementsInRecord : Math.Min(nbElements, record.ElementsInRecord)); response.Command = (ushort)CommandID.CA_PROTO_EVENT_ADD; response.Parameter1 = 1; response.Parameter2 = (uint)subscriptionId; ((TcpReceiver)this.Pipe.FirstFilter).Send(response); var lastStatus = record.AlarmStatus; EventHandler newEvent = delegate(object obj, EventArgs evt) { if (!record.IsDirty) { return; } // We have a alarm mask, if the status didn't change, don't send the event if (mask == MonitorMask.ALARM && lastStatus == record.AlarmStatus) { return; } lastStatus = record.AlarmStatus; DataPacket p = DataPacketBuilder.Encode(type, record[property], record, (nbElements == 0) ? record.ElementsInRecord : Math.Min(nbElements, record.ElementsInRecord)); p.Command = (ushort)CommandID.CA_PROTO_EVENT_ADD; p.Parameter1 = 1; p.Parameter2 = (uint)subscriptionId; ((TcpReceiver)this.Pipe.FirstFilter).Send(p); }; record.RecordProcessed += newEvent; lock (subscribedEvents) { subscribedEvents.Add(subscriptionId, new EpicsEvent { Handler = newEvent, Record = record, DataCount = nbElements, EpicsType = type, SID = sid }); } }
public override void ProcessData(DataPacket packet) { if (DateTime.Now < Server.WaitTill) { return; } //Console.WriteLine("Pipe " + (Pipe.FirstFilter is UdpReceiver ? "UDP" : "TCP") + ": " + ((CommandID)packet.Command)); 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; } // Send back the echo else { ((ServerTcpReceiver)Pipe[0]).Send(packet); } break; case CommandID.CA_PROTO_SEARCH: { var fullChannelName = packet.GetDataAsString(0); var channelName = fullChannelName; var property = "VAL"; if (fullChannelName.IndexOf('.') != -1) { property = fullChannelName.Split('.').Last(); channelName = fullChannelName.Split('.').First(); } if (!Server.Records.Contains(channelName)) { break; } if (Server.Records[channelName].FindType(property) == EpicsType.Invalid) { break; } DataPacket response = DataPacket.Create(8 + 16); response.Command = (ushort)CommandID.CA_PROTO_SEARCH; response.DataType = (ushort)Server.TcpPort; response.DataCount = 0; response.Parameter1 = 0xffffffff; response.Parameter2 = packet.Parameter1; response.SetUInt16(16, (ushort)CAConstants.CA_MINOR_PROTOCOL_REVISION); response.Destination = packet.Sender; ((UdpReceiver)this.Pipe[0]).Send(response); } break; case CommandID.CA_PROTO_CREATE_CHAN: { var fullChannelName = packet.GetDataAsString(0); var channelName = fullChannelName; var property = "VAL"; if (fullChannelName.IndexOf('.') != -1) { property = fullChannelName.Split('.').Last(); channelName = fullChannelName.Split('.').First(); } if (!Server.Records.Contains(channelName)) { break; } if (Server.Records[channelName].FindType(property) == EpicsType.Invalid) { break; } DataPacket access = DataPacket.Create(16); access.Command = (ushort)CommandID.CA_PROTO_ACCESS_RIGHTS; access.Parameter1 = packet.Parameter1; access.Parameter2 = (int)AccessRights.ReadAndWrite; ((ServerTcpReceiver)this.Pipe.FirstFilter).Send(access); DataPacket response = DataPacket.Create(16); response.Command = (ushort)CommandID.CA_PROTO_CREATE_CHAN; response.DataType = (ushort)Server.Records[channelName].FindType(property); response.DataCount = (uint)(property == "VAL" ? Server.Records[channelName].ElementsInRecord : 1); response.Parameter1 = packet.Parameter1; response.Parameter2 = ((ServerTcpReceiver)this.Pipe.FirstFilter).RegisterChannel(channelName + "." + property); ((ServerTcpReceiver)this.Pipe.FirstFilter).Send(response); } break; case CommandID.CA_PROTO_READ_NOTIFY: { var record = ((ServerTcpReceiver)this.Pipe.FirstFilter).FindRecord(this.Server, packet.Parameter1); object val = ((ServerTcpReceiver)this.Pipe.FirstFilter).RecordValue(this.Server, packet.Parameter1); if (stringTypes.Contains((EpicsType)packet.DataType) && val == null) { val = ""; } var nbElements = packet.DataCount == 0 ? record.ElementsInRecord : Math.Min(record.ElementsInRecord, (int)packet.DataCount); DataPacket response = DataPacketBuilder.Encode((EpicsType)packet.DataType, val, record, nbElements); response.Command = (ushort)CommandID.CA_PROTO_READ_NOTIFY; response.Parameter1 = 1; response.Parameter2 = packet.Parameter2; ((TcpReceiver)this.Pipe.FirstFilter).Send(response); } break; case CommandID.CA_PROTO_WRITE: { ((ServerTcpReceiver)this.Pipe.FirstFilter).PutValue(this.Server, packet); } break; case CommandID.CA_PROTO_WRITE_NOTIFY: { ((ServerTcpReceiver)this.Pipe.FirstFilter).PutValue(this.Server, packet); DataPacket response = DataPacket.Create(16); response.Command = (ushort)CommandID.CA_PROTO_WRITE_NOTIFY; response.DataType = packet.DataType; response.DataCount = packet.DataCount; response.Parameter1 = 1; response.Parameter2 = packet.Parameter2; ((ServerTcpReceiver)this.Pipe.FirstFilter).Send(response); } break; case CommandID.CA_PROTO_EVENT_ADD: { uint sid = packet.Parameter1; uint subscriptionId = packet.Parameter2; uint dataCount = packet.DataCount; EpicsType type = (EpicsType)packet.DataType; ((ServerTcpReceiver)this.Pipe.FirstFilter).RegisterEvent(this.Server, sid, subscriptionId, (int)dataCount, type, (MonitorMask)packet.GetUInt16((int)packet.HeaderSize + 12)); } break; case CommandID.CA_PROTO_EVENT_CANCEL: { ((ServerTcpReceiver)this.Pipe.FirstFilter).UnregisterEvent(this.Server, packet.Parameter2); } break; default: break; } } }