internal override void Decode(Channel channel, uint nbElements) { Status = (AlarmStatus)channel.DecodeData <ushort>(1, 0); Severity = (AlarmSeverity)channel.DecodeData <ushort>(1, 2); int pos = 4; Type t = typeof(TType); if (t.IsArray) { t = t.GetElementType(); } if (t == typeof(object)) { t = channel.ChannelDefinedType; } if ( t == typeof(double) || t == typeof(float) ) { Precision = channel.DecodeData <short>(1, pos); pos += 4; // 2 for precision field + 2 padding for "RISC alignment" } if (t != typeof(string)) { EGU = channel.DecodeData <string>(1, pos, 8); pos += 8; int tSize = TypeHandling.EpicsSize(t); // HighDisplayLimit = channel.DecodeData<TType>(1, pos) ; HighDisplayLimit = Convert.ToDouble(channel.DecodeData(t, 1, pos)); pos += tSize; // LowDisplayLimit = channel.DecodeData<TType>(1, pos) ; LowDisplayLimit = Convert.ToDouble(channel.DecodeData(t, 1, pos)); pos += tSize; // HighAlertLimit = channel.DecodeData<TType>(1, pos) ; HighAlertLimit = Convert.ToDouble(channel.DecodeData(t, 1, pos)); pos += tSize; // HighWarnLimit = channel.DecodeData<TType>(1, pos) ; HighWarnLimit = Convert.ToDouble(channel.DecodeData(t, 1, pos)); pos += tSize; // LowWarnLimit = channel.DecodeData<TType>(1, pos) ; LowWarnLimit = Convert.ToDouble(channel.DecodeData(t, 1, pos)); pos += tSize; // LowAlertLimit = channel.DecodeData<TType>(1, pos) ; LowAlertLimit = Convert.ToDouble(channel.DecodeData(t, 1, pos)); pos += tSize; } else { EGU = ""; } if (t == typeof(byte)) { pos++; // 1 padding for "RISC alignment" } Value = channel.DecodeData <TType>(nbElements, pos); }
internal Channel(CAClient client, string channelName) { ChannelName = channelName; Status = ChannelStatus.REQUESTED; 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)CAConstants.DONT_REPLY; SearchPacket.DataCount = (ushort)CAConstants.CA_MINOR_PROTOCOL_REVISION; SearchPacket.Parameter1 = cid; SearchPacket.Parameter2 = cid; SearchPacket.SetDataAsString(ChannelName); }
internal object DecodeData(Type t, uint nbElements = 1, int startPost = 0, int maxSize = 40) { if ( t.IsSubclassOf(typeof(Decodable)) && !t.IsArray ) { Decodable res = (Decodable)t.GetConstructor( System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance, null, new Type[] {}, null ).Invoke( new object[] {} ); res.Decode( this, nbElements ); return(res); } if (t == typeof(object)) { t = channelDefinedType; } Type baseT = t; if (baseT.IsArray) { baseT = t.GetElementType(); } if (t.IsArray) { Type dl = typeof(List <>); Type genList = dl.MakeGenericType( new Type[] { baseT } ); System.Collections.IList res = (System.Collections.IList)Activator.CreateInstance(genList); int pos = (int)RawData.HeaderSize + startPost; int elementSize = TypeHandling.EpicsSize(baseT); for (int i = 0; i < nbElements; i++) { switch (TypeHandling.Lookup[baseT]) { case EpicsType.Int: res.Add( RawData.GetInt32(pos) ); break; case EpicsType.Short: res.Add( RawData.GetInt16(pos) ); break; case EpicsType.Float: res.Add( RawData.GetFloat(pos) ); break; case EpicsType.Double: res.Add( RawData.GetDouble(pos) ); break; case EpicsType.Byte: res.Add( RawData.GetByte(pos) ); break; default: throw new Exception("Type not supported"); } pos += elementSize; } return(( (dynamic)res ).ToArray()); } if (baseT == typeof(DateTime)) { long secs = RawData.GetUInt32( (int)RawData.HeaderSize + startPost ); long nanoSecs = RawData.GetUInt32( (int)RawData.HeaderSize + startPost + 4) ; DateTime d = ( new DateTime( timestampBase.Ticks + (secs * 10000000L) + (nanoSecs / 100L) ) ).ToLocalTime(); return(d); } switch (TypeHandling.Lookup[baseT]) { case EpicsType.Internal_UInt: return(RawData.GetUInt32((int)RawData.HeaderSize + startPost)); case EpicsType.Internal_UShort: return(RawData.GetUInt16((int)RawData.HeaderSize + startPost)); case EpicsType.Int: return(RawData.GetInt32((int)RawData.HeaderSize + startPost)); case EpicsType.Short: return(RawData.GetInt16((int)RawData.HeaderSize + startPost)); case EpicsType.Float: return(RawData.GetFloat((int)RawData.HeaderSize + startPost)); case EpicsType.Double: return(RawData.GetDouble((int)RawData.HeaderSize + startPost)); case EpicsType.String: return(RawData.GetDataAsString(startPost, maxSize)); case EpicsType.Byte: return(RawData.GetByte((int)RawData.HeaderSize + startPost)); default: // throw new Exception("Type not supported") ; return(new object()); } }
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); }
public void Init(CAClient client, IPEndPoint dest) { this.Client = client; this.m_destinationEndPoint = dest; m_socket = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp ); m_socket.SetSocketOption( SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true ); m_socket.Connect(dest); base.Start(m_socket); DataPacket p = DataPacket.Create(16); p.Command = (ushort)CommandID.CA_PROTO_VERSION; p.DataType = 1; p.DataCount = (uint)CAConstants.CA_MINOR_PROTOCOL_REVISION; p.Parameter1 = 0; p.Parameter2 = 0; Send(p); p = DataPacket.Create( 16 + this.Client.Configuration.Hostname.Length + TypeHandling.Padding( this.Client.Configuration.Hostname.Length ) ); p.Command = (ushort)CommandID.CA_PROTO_HOST_NAME; p.DataCount = 0; p.DataType = 0; p.Parameter1 = 0; p.Parameter2 = 0; p.SetDataAsString( this.Client.Configuration.Hostname ); Send(p); p = DataPacket.Create( 16 + this.Client.Configuration.Username.Length + TypeHandling.Padding( this.Client.Configuration.Username.Length ) ); p.Command = (ushort)CommandID.CA_PROTO_CLIENT_NAME; p.DataCount = 0; p.DataType = 0; p.Parameter1 = 0; p.Parameter2 = 0; p.SetDataAsString( this.Client.Configuration.Username ); Send(p); }