/// <summary> /// Clone this packet, creating an exact copy. /// As the clone function is an implementation of IClonable it must return an object. /// </summary> /// <returns></returns> public object Clone() { DataPacket p = DataPacket.Create(Data); p.Sender = this.Sender; p.Destination = this.Destination; return(p); }
/// <summary> /// Skips a given size from the data block /// </summary> /// <param name="size"></param> public DataPacket SkipSize(UInt32 size) { DataPacket p = DataPacket.Create(Data.Length - (int)size); p.Sender = this.Sender; p.Destination = this.Destination; Buffer.BlockCopy(this.Data, (int)size, p.Data, 0, p.Data.Length); return(p); }
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(); } }); } } }
internal EpicsChannel(EpicsClient client, string channelName) { this.ChannelName = channelName; this.Status = ChannelStatus.REQUESTED; this.Client = client; MonitorMask = MonitorMask.VALUE; HasValue = false; SearchPacket = DataPacket.Create(16 + ChannelName.Length + TypeHandling.Padding(ChannelName.Length)); SearchPacket.Command = (ushort)CommandID.CA_PROTO_SEARCH; SearchPacket.DataType = (ushort)EpicsConstants.DONT_REPLY; SearchPacket.DataCount = (ushort)EpicsConstants.CA_MINOR_PROTOCOL_REVISION; SearchPacket.Parameter1 = cid; SearchPacket.Parameter2 = cid; SearchPacket.SetDataAsString(ChannelName); }
internal void SendReadNotify <TType>(uint nbElements) { if (Client.Configuration.DebugTiming) { lock (ElapsedTimings) { if (!ElapsedTimings.ContainsKey("SendReadNotify")) { ElapsedTimings.Add("SendReadNotify", Stopwatch.Elapsed); } } } DataPacket packet = DataPacket.Create(16); packet.Command = (ushort)CommandID.CA_PROTO_READ_NOTIFY; Type t = typeof(TType); if (typeof(TType).IsArray) { t = (typeof(TType)).GetElementType(); } else if (t.IsGenericType) { if (t.GetGenericArguments().First() == typeof(object)) { t = t.GetGenericTypeDefinition().MakeGenericType(new Type[] { channelDefinedType }); } } if (t == typeof(object)) { t = channelDefinedType; } packet.DataType = (ushort)TypeHandling.Lookup[t]; packet.DataCount = nbElements; packet.Parameter1 = SID; uint ioid = (NextIoId++); packet.Parameter2 = ioid; lock (ioc.PendingIo) { ioc.PendingIo.Add(ioid, this); } ioc.Send(packet); }
void SendMonitor(EpicsChannel action) { if (ChannelDataCount == 0) { return; } //Console.WriteLine("Sending new event add"); DataPacket p = DataPacket.Create(16 + 16); p.Command = (ushort)CommandID.CA_PROTO_EVENT_ADD; Type t = typeof(TType); if (t.IsArray) { t = t.GetElementType(); } else if (t.IsGenericType) { if (t.GetGenericArguments().First() == typeof(object)) { t = t.GetGenericTypeDefinition().MakeGenericType(new Type[] { channelDefinedType }); } } p.DataType = (ushort)TypeHandling.Lookup[t]; p.DataCount = ChannelDataCount; p.Parameter1 = SID; p.Parameter2 = CID; p.SetUInt16(12 + 16, (ushort)MonitorMask); if (ioc != null) { ioc.Send(p); } }
internal void SetIoc(DataPipe pipe) { TcpReceiver tcpReceiver = (TcpReceiver)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"); EpicsChannel 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"); 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)EpicsConstants.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); } } }
protected DataPacket WritePacket <TType>(TType newValue) { int headerSize = 16; uint nbElem = 1; if (newValue is IEnumerable <object> ) { nbElem = (uint)((IEnumerable <object>)newValue).Count(); } Type t = typeof(TType); if (t.IsArray) { nbElem = (uint)((Array)((object)newValue)).Length; // if too many array elements, use extended header if (nbElem > 0xffff) { headerSize = 24; } t = t.GetElementType(); } else if (t.IsGenericType) { if (t.GetGenericArguments().First() == typeof(object)) { t = t.GetGenericTypeDefinition().MakeGenericType(new Type[] { channelDefinedType }); } } if (t == typeof(object)) { t = channelDefinedType; } int payloadSize = (int)(nbElem * TypeHandling.EpicsSize(t)); if (payloadSize % 8 > 0) { payloadSize += 8 - (payloadSize % 8); } // if payload too large, use extended header if (payloadSize > 0x4000) { headerSize = 24; } DataPacket packet = DataPacket.Create(headerSize + payloadSize); packet.Command = (ushort)CommandID.CA_PROTO_WRITE_NOTIFY; packet.DataCount = nbElem; packet.DataType = (ushort)TypeHandling.Lookup[t]; packet.Parameter1 = SID; uint ioid = (NextIoId++); packet.Parameter2 = ioid; if (nbElem > 1) { int pos = headerSize; int elementSize = TypeHandling.EpicsSize(t); foreach (var elem in (System.Collections.IEnumerable)newValue) { switch (TypeHandling.Lookup[t]) { case EpicsType.Int: packet.SetInt32(pos, (int)elem); break; case EpicsType.Short: packet.SetInt16(pos, (short)elem); break; case EpicsType.Float: packet.SetFloat(pos, (float)elem); break; case EpicsType.Double: packet.SetDouble(pos, (double)elem); break; case EpicsType.Byte: packet.SetByte(pos, (byte)elem); break; default: throw new Exception("Type not supported"); } pos += elementSize; } } else { switch (TypeHandling.Lookup[t]) { case EpicsType.Int: packet.SetInt32((int)packet.HeaderSize, (int)(object)newValue); break; case EpicsType.Short: packet.SetInt16((int)packet.HeaderSize, (short)(object)newValue); break; case EpicsType.Float: packet.SetFloat((int)packet.HeaderSize, (float)(object)newValue); break; case EpicsType.Double: packet.SetDouble((int)packet.HeaderSize, (double)(object)newValue); break; case EpicsType.String: packet.SetDataAsString((string)(object)newValue); break; case EpicsType.Byte: packet.SetByte((int)packet.HeaderSize, (byte)(object)newValue); break; default: throw new Exception("Type not currently supported."); } } return(packet); }