internal ChannelMonitor(CARecord record, string property, CAServerChannel channel, EpicsType type, int dataCount, MonitorMask monitorMask, int subscriptionId) { Record = record; Property = property; Channel = channel; Type = type; DataCount = dataCount; MonitorMask = monitorMask; SubscriptionId = subscriptionId; try { object val = Record[Property.ToString()]; if (val == null) val = 0; byte[] realData = val.ToByteArray(Type, Record); Channel.sendMonitorChange(SubscriptionId, Type, DataCount, EpicsTransitionStatus.ECA_NORMAL, realData); lastValue = Record[Property]; Record.RecordProcessed += new EventHandler(Record_RecordProcessed); } catch (Exception e) { Channel.sendMonitorChange(SubscriptionId, Type, DataCount, EpicsTransitionStatus.ECA_ADDFAIL, new byte[0]); } }
/// <summary> /// The channel created message. /// </summary> /// <param name="clientId"> /// The client id. /// </param> /// <param name="serverId"> /// The server id. /// </param> /// <param name="dataType"> /// The data type. /// </param> /// <param name="dataCount"> /// The data count. /// </param> /// <param name="access"> /// The access. /// </param> /// <returns> /// </returns> internal byte[] channelCreatedMessage( int clientId, int serverId, EpicsType dataType, int dataCount, AccessRights access) { var mem = new MemoryStream(); var writer = new BinaryWriter(mem); mem.Capacity = 32; writer.Write(NetworkByteConverter.ToByteArray(CommandID.CA_PROTO_ACCESS_RIGHTS)); writer.Write(new byte[6]); writer.Write(NetworkByteConverter.ToByteArray((UInt32)clientId)); writer.Write(NetworkByteConverter.ToByteArray((UInt32)access)); writer.Write(NetworkByteConverter.ToByteArray(CommandID.CA_PROTO_CREATE_CHAN)); writer.Write(new byte[2]); writer.Write(NetworkByteConverter.ToByteArray((UInt16)dataType)); writer.Write(NetworkByteConverter.ToByteArray((UInt16)dataCount)); writer.Write(NetworkByteConverter.ToByteArray((UInt32)clientId)); writer.Write(NetworkByteConverter.ToByteArray((UInt32)serverId)); var buffer = mem.GetBuffer(); writer.Close(); mem.Dispose(); return(buffer); }
internal CAChannelMonitor(CARecord record, string property, CAServerChannel channel, EpicsType type, int dataCount, MonitorMask monitorMask, int subscriptionId) { Record = record; Property = property; Channel = channel; Type = type; DataCount = dataCount; MonitorMask = monitorMask; SubscriptionId = subscriptionId; try { object val = Record[Property.ToString()]; if (val == null) { val = 0; } byte[] realData = val.ToByteArray(Type, Record); using (Record.CreateAtomicChange(false)) Channel.TcpConnection.Send(Channel.Server.Filter.MonitorChangeMessage(SubscriptionId, Channel.ClientId, Type, DataCount, val.ToByteArray(Type, Record))); Record.RecordProcessed += new EventHandler(Record_RecordProcessed); } catch (Exception e) { Channel.TcpConnection.Send(Channel.Server.Filter.MonitorChangeMessage(SubscriptionId, Channel.ClientId, Type, DataCount, new byte[0])); } }
/// <summary> /// The set message. /// </summary> /// <param name="values"> /// The values. /// </param> /// <param name="type"> /// The type. /// </param> /// <param name="SID"> /// The sid. /// </param> /// <param name="CID"> /// The cid. /// </param> /// <param name="callBack"> /// The call back. /// </param> /// <typeparam name="dataType"> /// </typeparam> /// <returns> /// </returns> internal byte[] setMessage <dataType>(dataType[] values, EpicsType type, uint SID, uint CID, bool callBack) { var mem = new MemoryStream(); var writer = new BinaryWriter(mem); // possible max length = extended header (16byte) + count*40byte mem.Capacity = 16 + values.Length * 40; // jump to the end of the header. mem.Position = 16; foreach (var value in values) { writer.Write(NetworkByteConverter.objectToByte(value, type)); } // shrink to what we really need mem.Capacity = (int)mem.Position; // jump to the beginning mem.Position = 0; writer.Write(NetworkByteConverter.ToByteArray(callBack ? CommandID.CA_PROTO_WRITE_NOTIFY : CommandID.CA_PROTO_WRITE)); writer.Write(NetworkByteConverter.ToByteArray((UInt16)(mem.Capacity - 16))); writer.Write(NetworkByteConverter.ToByteArray((UInt16)type)); writer.Write(NetworkByteConverter.ToByteArray((UInt16)values.Length)); writer.Write(NetworkByteConverter.ToByteArray(SID)); writer.Write(NetworkByteConverter.ToByteArray(CID)); var buffer = mem.GetBuffer(); writer.Close(); mem.Dispose(); return(buffer); }
static public DataPacket Encode(EpicsType type, object value, CARecord record, int nbElements = 1) { DataPacket res = DataPacket.Create(16 + 424); res.DataCount = 1; res.DataType = (ushort)type; res.SetInt16(16, (short)record.AlarmStatus); res.SetInt16(16 + 2, (short)record.CurrentAlarmSeverity); string[] names = Enum.GetNames(value.GetType()); res.SetInt16(16 + 4, (short)names.Length); res.SetInt16(16 + 422, Convert.ToInt16(value)); for (int i = 0; i < names.Length; i++) { res.SetDataAsString( names[i], 6 + i * 26, 26 ); } return(res); }
/// <summary> /// The monitor change message. /// </summary> /// <param name="subscriptionId"> /// The subscription id. /// </param> /// <param name="clientId"> /// The client id. /// </param> /// <param name="dataType"> /// The data type. /// </param> /// <param name="dataCount"> /// The data count. /// </param> /// <param name="data"> /// The data. /// </param> /// <returns> /// </returns> internal byte[] monitorChangeMessage(int subscriptionId, int clientId, EpicsType dataType, int dataCount, byte[] data) { var mem = new MemoryStream(); var writer = new BinaryWriter(mem); var padding = 0; if (data.Length % 8 == 0) { padding = 8; } else { padding = 8 - (data.Length % 8); } mem.Capacity = 16 + data.Length + padding; writer.Write(NetworkByteConverter.ToByteArray(CommandID.CA_PROTO_EVENT_ADD)); writer.Write(NetworkByteConverter.ToByteArray((UInt16)(data.Length + padding))); writer.Write(NetworkByteConverter.ToByteArray((UInt16)dataType)); writer.Write(NetworkByteConverter.ToByteArray((UInt16)dataCount)); writer.Write(NetworkByteConverter.ToByteArray((UInt32)clientId)); writer.Write(NetworkByteConverter.ToByteArray((UInt32)subscriptionId)); writer.Write(data); writer.Write(new byte[padding]); var buffer = mem.GetBuffer(); writer.Close(); mem.Dispose(); return(buffer); }
internal static object ByteToObject(this byte[] payload, EpicsType epicsType) { switch (epicsType) { case EpicsType.String: return(ByteConverter.ToString(payload)); case EpicsType.Short: return(ByteConverter.ToInt16(payload)); case EpicsType.UShort: return(ByteConverter.ToUInt16(payload)); case EpicsType.Float: return(ByteConverter.ToFloat(payload)); case EpicsType.Byte: return(ByteConverter.ToByte(payload, 0)); case EpicsType.Int: return(ByteConverter.ToInt32(payload)); case EpicsType.Double: return(ByteConverter.ToDouble(payload)); default: throw new Exception("Type " + epicsType.ToString() + " not yet supported"); } }
internal CAChannelMonitor(CARecord record, string property, CAServerChannel channel, EpicsType type, int dataCount, MonitorMask monitorMask, int subscriptionId) { Record = record; Property = property; Channel = channel; Type = type; DataCount = dataCount; MonitorMask = monitorMask; SubscriptionId = subscriptionId; try { object val = Record[Property.ToString()]; if (val == null) val = 0; byte[] realData = val.ToByteArray(Type, Record); Channel.TcpConnection.Send(Channel.Server.Filter.MonitorChangeMessage(SubscriptionId, Channel.ClientId, Type, DataCount, val.ToByteArray(Type, Record))); lastValue = Record[Property]; Record.RecordProcessed += new EventHandler(Record_RecordProcessed); } catch (Exception e) { Channel.TcpConnection.Send(Channel.Server.Filter.MonitorChangeMessage(SubscriptionId, Channel.ClientId, Type, DataCount, new byte[0])); } }
/// <summary> /// /// </summary> /// <param name="clientId">IMPORTANT IT's not sure yet that this has to be the cliendId could also be the ioId</param> /// <param name=IOID>IMPORTANT IT's not sure yet that this has to be the ioId could also be the cliendId</param> /// <param name="dataType"></param> /// <param name="dataCount"></param> /// <param name="data"></param> /// <returns></returns> public byte[] ChannelReadMessage(int clientId, int ioId, EpicsType dataType, int dataCount, byte[] data) { MemoryStream mem = new MemoryStream(); BinaryWriter writer = new BinaryWriter(mem); int padding = 8; /*if (dataCount > 60000) * padding = 0;*/ if (data.Length % 8 != 0) { padding = (padding - (data.Length % 8)); } mem.Capacity = 16 + data.Length + padding; writer.Write(((UInt16)CommandID.CA_PROTO_READ_NOTIFY).ToByteArray()); if (dataCount > 30000) { writer.Write(new byte[] { 0xFF, 0xFF }); } else { writer.Write(((UInt16)(data.Length + padding)).ToByteArray()); } writer.Write(((UInt16)dataType).ToByteArray()); if (dataCount > 30000) { writer.Write(new byte[] { 0x00, 0x00 }); } else { writer.Write(((UInt16)dataCount).ToByteArray()); } // Seems again an issue with the specifications where only a value of 1 works. //writer.Write(((UInt32)clientId).ToByteArray()); writer.Write(((UInt32)1).ToByteArray()); writer.Write(((UInt32)ioId).ToByteArray()); if (dataCount > 30000) { writer.Write(((UInt32)(data.Length + padding)).ToByteArray()); byte[] b = ((UInt32)(dataCount)).ToByteArray(); writer.Write(b); } writer.Write(data); if (padding > 0) { writer.Write(new byte[padding]); } byte[] buffer = mem.ToArray(); writer.Close(); mem.Dispose(); return(buffer); }
internal byte[] MonitorChangeMessage(int subscriptionId, int clientId, EpicsType dataType, int dataCount, byte[] data) { MemoryStream mem = new MemoryStream(); BinaryWriter writer = new BinaryWriter(mem); int padding = 0; if (data.Length % 8 == 0) { padding = 8; } else { padding = (8 - (data.Length % 8)); } mem.Capacity = 16 + data.Length + padding; writer.Write(((ushort)CommandID.CA_PROTO_EVENT_ADD).ToByteArray()); if (dataCount > 30000) { writer.Write(new byte[] { 0xFF, 0xFF }); } else { writer.Write(((UInt16)(data.Length + padding)).ToByteArray()); } writer.Write(((UInt16)dataType).ToByteArray()); if (dataCount > 30000) { writer.Write(new byte[] { 0x00, 0x00 }); } else { writer.Write(((UInt16)dataCount).ToByteArray()); } //writer.Write(NetworkByteConverter.ToByteArray((UInt32)clientId)); // Christoph implementation // Cosylab would send 0 which doesn't work writer.Write(((UInt32)1).ToByteArray()); // Value found to work... no idea why writer.Write(((UInt32)subscriptionId).ToByteArray()); if (dataCount > 30000) { writer.Write(((UInt32)(data.Length + padding)).ToByteArray()); writer.Write(((UInt32)dataCount).ToByteArray()); } writer.Write(data); writer.Write(new byte[padding]); byte[] buffer = mem.GetBuffer(); writer.Close(); mem.Dispose(); return(buffer); }
internal void AddMonitor(EpicsType type, int dataCount, int subscriptionId, MonitorMask mask) { //does he request to add a subscriptionId at the same Id as it already exist? lock (monitors) { if (monitors.ContainsKey(subscriptionId)) { return; } monitors.Add(subscriptionId, new CAChannelMonitor(Record, Property, this, type, dataCount, mask, subscriptionId)); } }
static public DataPacket Encode(EpicsType type, object source, CARecord record, int nbElements = 1) { switch (type) { case EpicsType.Byte: case EpicsType.Short: case EpicsType.Int: case EpicsType.Float: case EpicsType.Double: case EpicsType.String: return(SimpleChannel.Encode(type, source, record, nbElements)); case EpicsType.Status_Byte: case EpicsType.Status_Short: case EpicsType.Status_Int: case EpicsType.Status_Float: case EpicsType.Status_Double: case EpicsType.Status_String: return(ExtChannel.Encode(type, source, record, nbElements)); case EpicsType.Time_Byte: case EpicsType.Time_Short: case EpicsType.Time_Int: case EpicsType.Time_Float: case EpicsType.Time_Double: case EpicsType.Time_String: return(TimeChannel.Encode(type, source, record, nbElements)); case EpicsType.Control_Byte: case EpicsType.Control_Short: case EpicsType.Control_Int: case EpicsType.Control_Float: case EpicsType.Control_Double: case EpicsType.Control_String: return(ControlChannel.Encode(type, source, record, nbElements)); case EpicsType.Display_Byte: case EpicsType.Display_Short: case EpicsType.Display_Int: case EpicsType.Display_Float: case EpicsType.Display_Double: case EpicsType.Display_String: return(DisplayChannel.Encode(type, source, record, nbElements)); case EpicsType.Labeled_Enum: return(EnumControlChannel.Encode(type, source, record, nbElements)); default: throw new Exception("Not yet supported"); } }
static public DataPacket Encode(EpicsType type, object value, CARecord record, int nbElements = 1) { int size = 12; int startPos = 0; switch (type) { case EpicsType.Time_Double: size += 4 + nbElements * 8; startPos = 4; break; case EpicsType.Time_Byte: size += 3 + nbElements; startPos = 3; break; case EpicsType.Time_Int: case EpicsType.Time_Float: size += nbElements * 4; startPos = 0; break; case EpicsType.Time_Short: size += 2 + nbElements * 2; startPos = 2; break; case EpicsType.Time_String: startPos = 0; size += 40; break; default: break; } size += DataPacketBuilder.Padding(size); DataPacket res = DataPacket.Create(16 + size); res.DataCount = (uint)nbElements; res.DataType = (ushort)type; res.SetInt16(16, (short)record.AlarmStatus); res.SetInt16(16 + 2, (short)record.CurrentAlarmSeverity); res.SetDateTime(16 + 4, DateTime.Now); DataPacketBuilder.Encode(res, type, 12 + startPos, value, nbElements); return(res); }
/// <summary> /// The add monitor. /// </summary> /// <param name="type"> /// The type. /// </param> /// <param name="dataCount"> /// The data count. /// </param> /// <param name="subscriptionId"> /// The subscription id. /// </param> /// <param name="mask"> /// The mask. /// </param> internal void addMonitor(EpicsType type, int dataCount, int subscriptionId, MonitorMask mask) { // does he request to add a subscriptionId at the same Id as it already exist? if (this.monitors.ContainsKey(subscriptionId)) { return; } lock (this.monitors) { this.monitors.Add( subscriptionId, new EpicsServerMonitor(this.Record, this.Property, this, type, dataCount, mask, subscriptionId)); } }
/// <summary> /// recalls the object to Byte function with the right datatype-struct for easy coding /// </summary> internal static byte[] ToByteArray(this object src, EpicsType epicsType, CARecord record, int dataCount) { //Type valueType = record["VAL"].GetType(); Type valueType = src.GetType(); object mySrc = src; if (valueType.IsEnum) { return(ToByteArray <Enum>(src, epicsType, record, dataCount)); } string name; if (valueType.IsGenericType && valueType.Name.Split(new char[] { '`' })[0] == "ArrayContainer") { name = valueType.GetGenericArguments()[0].Name; mySrc = ((dynamic)src).arrayValues; } else if (valueType.IsArray) { name = valueType.GetElementType().Name; } else { name = valueType.Name; } switch (name) { case "String": return(ToByteArray <string>(mySrc, epicsType, record, dataCount)); case "Int32": return(ToByteArray <int>(mySrc, epicsType, record, dataCount)); case "Int16": return(ToByteArray <short>(mySrc, epicsType, record, dataCount)); case "Single": return(ToByteArray <float>(mySrc, epicsType, record, dataCount)); case "Double": return(ToByteArray <double>(mySrc, epicsType, record, dataCount)); case "Byte": return(ToByteArray <byte>(mySrc, epicsType, record, dataCount)); default: throw new Exception("Wrong DataType defined"); } }
internal void SetServerChannel(uint sid, EpicsType epicsType, uint dataCount) { // Console.WriteLine("Setting channel SID " + this.ChannelName + " " + sid) ; lock ( ConnectionLock ) { if (ioc == null) { Disconnect(); return; } lock (ioc.ChannelSID) { if (!ioc.ChannelSID.ContainsKey(this.ChannelName)) { ioc.ChannelSID.Add( this.ChannelName, sid ); } } SID = sid; channelDefinedType = TypeHandling.ReverseLookup[epicsType]; if (MonitoredType == null) { MonitoredType = channelDefinedType; } MonitoredElements = ChannelDataCount = dataCount; Status = ChannelStatus.CONNECTED; ConnectionEvent.Set(); } if (Client.Configuration.DebugTiming) { lock ( ElapsedTimings ) { if (!ElapsedTimings.ContainsKey("CreateChannel")) { ElapsedTimings.Add( "CreateChannel", Stopwatch.Elapsed ); } } } }
public byte[] ChannelCreatedMessage(int clientId, int serverId, EpicsType dataType, int dataCount, AccessRights access) { MemoryStream mem = new MemoryStream(); BinaryWriter writer = new BinaryWriter(mem); mem.Capacity = 32; writer.Write(((UInt16)CommandID.CA_PROTO_ACCESS_RIGHTS).ToByteArray()); writer.Write(new byte[6]); writer.Write(((UInt32)clientId).ToByteArray()); writer.Write(((UInt32)access).ToByteArray()); writer.Write(((UInt16)CommandID.CA_PROTO_CREATE_CHAN).ToByteArray()); if (dataCount > 30000) { writer.Write(new byte[] { 0xFF, 0xFF }); } else { writer.Write(new byte[2]); } writer.Write(((UInt16)dataType).ToByteArray()); if (dataCount > 30000) { writer.Write(new byte[] { 0x00, 0x00 }); } else { writer.Write(((UInt16)dataCount).ToByteArray()); } writer.Write(((UInt32)clientId).ToByteArray()); writer.Write(((UInt32)serverId).ToByteArray()); if (dataCount > 30000) { // Size writer.Write(((UInt32)0).ToByteArray()); // Data count writer.Write(((UInt32)dataCount).ToByteArray()); } byte[] buffer = mem.ToArray(); writer.Close(); mem.Dispose(); return(buffer); }
internal byte[] ChannelWroteMessage(int clientId, int ioId, EpicsType dataType, int dataCount, EpicsTransitionStatus status) { MemoryStream mem = new MemoryStream(); BinaryWriter writer = new BinaryWriter(mem); mem.Capacity = 16; writer.Write(((ushort)CommandID.CA_PROTO_WRITE_NOTIFY).ToByteArray()); writer.Write(new byte[2]); writer.Write(((UInt16)dataType).ToByteArray()); writer.Write(((UInt16)dataCount).ToByteArray()); writer.Write(((UInt32)status).ToByteArray()); writer.Write(((UInt32)ioId).ToByteArray()); byte[] buffer = mem.GetBuffer(); writer.Close(); mem.Dispose(); return(buffer); }
internal byte[] MonitorCloseMessage(EpicsType dataType, int serverId, int subscriptionId) { MemoryStream mem = new MemoryStream(); BinaryWriter writer = new BinaryWriter(mem); mem.Capacity = 16; writer.Write(((ushort)CommandID.CA_PROTO_EVENT_CANCEL).ToByteArray()); writer.Write(new byte[2]); writer.Write(((UInt16)dataType).ToByteArray()); writer.Write(new byte[2]); writer.Write(((UInt32)serverId).ToByteArray()); writer.Write(((UInt32)subscriptionId).ToByteArray()); byte[] buffer = mem.GetBuffer(); writer.Close(); mem.Dispose(); return(buffer); }
/// <summary> /// The get message. /// </summary> /// <param name="type"> /// The type. /// </param> /// <param name="count"> /// The count. /// </param> /// <param name="SID"> /// The sid. /// </param> /// <param name="CID"> /// The cid. /// </param> /// <returns> /// </returns> internal byte[] getMessage(EpicsType type, ushort count, uint SID, uint CID) { var mem = new MemoryStream(); var writer = new BinaryWriter(mem); mem.Capacity = 16; writer.Write(NetworkByteConverter.ToByteArray(CommandID.CA_PROTO_READ_NOTIFY)); writer.Write(new byte[2]); writer.Write(NetworkByteConverter.ToByteArray((UInt16)type)); writer.Write(NetworkByteConverter.ToByteArray(count)); writer.Write(NetworkByteConverter.ToByteArray(SID)); writer.Write(NetworkByteConverter.ToByteArray(CID)); var buffer = mem.GetBuffer(); writer.Close(); mem.Dispose(); return(buffer); }
/// <summary> /// The monitor close message. /// </summary> /// <param name="dataType"> /// The data type. /// </param> /// <param name="serverId"> /// The server id. /// </param> /// <param name="subscriptionId"> /// The subscription id. /// </param> /// <returns> /// </returns> internal byte[] monitorCloseMessage(EpicsType dataType, int serverId, int subscriptionId) { var mem = new MemoryStream(); var writer = new BinaryWriter(mem); mem.Capacity = 16; writer.Write(NetworkByteConverter.ToByteArray(CommandID.CA_PROTO_EVENT_CANCEL)); writer.Write(new byte[2]); writer.Write(NetworkByteConverter.ToByteArray((UInt16)dataType)); writer.Write(new byte[2]); writer.Write(NetworkByteConverter.ToByteArray((UInt32)serverId)); writer.Write(NetworkByteConverter.ToByteArray((UInt32)subscriptionId)); var buffer = mem.GetBuffer(); writer.Close(); mem.Dispose(); return(buffer); }
internal void ReadValue(int ioId, EpicsType type, int dataCount) { byte[] val; if (Record.Scan == ScanAlgorithm.PASSIVE) { Record.CallPrepareRecord(); } object objVal = Record[Property]; if (objVal == null) { objVal = 0; } try { using (Record.CreateAtomicChange(false)) { if (type == EpicsType.Labeled_Enum) { val = objVal.LabelsToByteArray(Record); } else if (objVal.GetType().IsArray) { val = objVal.ToByteArray(type, Record, dataCount); } else { val = objVal.ToByteArray(type, Record); } } TcpConnection.Send(Server.Filter.ChannelReadMessage(ClientId, ioId, type, dataCount, val)); } catch (Exception e) { /*Console.WriteLine(e.Message + "\n\r" + e.StackTrace); * TcpConnection.Send(Server.Filter.ErrorMessage(ClientId, EpicsTransitionStatus.ECA_BADTYPE, "WRONG TYPE", new byte[16]));*/ } }
/// <summary> /// The create subscription message. /// </summary> /// <param name="SID"> /// The sid. /// </param> /// <param name="SubscriptionID"> /// The subscription id. /// </param> /// <param name="type"> /// The type. /// </param> /// <param name="dataCount"> /// The data count. /// </param> /// <param name="mask"> /// The mask. /// </param> /// <returns> /// </returns> internal byte[] createSubscriptionMessage( uint SID, uint SubscriptionID, EpicsType type, ushort dataCount, MonitorMask mask) { var mem = new MemoryStream(); var writer = new BinaryWriter(mem); mem.Capacity = 32; writer.Write(NetworkByteConverter.ToByteArray(CommandID.CA_PROTO_EVENT_ADD)); writer.Write(NetworkByteConverter.ToByteArray((UInt16)16)); writer.Write(NetworkByteConverter.ToByteArray((UInt16)type)); writer.Write(NetworkByteConverter.ToByteArray(dataCount)); writer.Write(NetworkByteConverter.ToByteArray(SID)); writer.Write(NetworkByteConverter.ToByteArray(SubscriptionID)); writer.Write(new byte[12]); writer.Write(NetworkByteConverter.ToByteArray((UInt16)mask)); var buffer = mem.GetBuffer(); writer.Close(); mem.Dispose(); return(buffer); }
/// <summary> /// The set message. /// </summary> /// <param name="value"> /// The value. /// </param> /// <param name="type"> /// The type. /// </param> /// <param name="SID"> /// The sid. /// </param> /// <param name="CID"> /// The cid. /// </param> /// <param name="callBack"> /// The call back. /// </param> /// <returns> /// </returns> internal byte[] setMessage(object value, EpicsType type, uint SID, uint CID, bool callBack) { var mem = new MemoryStream(); var writer = new BinaryWriter(mem); var payload = NetworkByteConverter.objectToByte(value, type); var padding = 0; if (payload.Length % 8 == 0) { padding = 8; } else { padding = 8 - (payload.Length % 8); } mem.Capacity = 16 + payload.Length + padding; // add the versioning message writer.Write(NetworkByteConverter.ToByteArray(callBack ? CommandID.CA_PROTO_WRITE_NOTIFY : CommandID.CA_PROTO_WRITE)); writer.Write(NetworkByteConverter.ToByteArray((UInt16)(payload.Length + padding))); writer.Write(NetworkByteConverter.ToByteArray((UInt16)type)); writer.Write(new byte[2] { 0, 1 }); writer.Write(NetworkByteConverter.ToByteArray(SID)); writer.Write(NetworkByteConverter.ToByteArray(CID)); writer.Write(payload); writer.Write(new byte[padding]); var buffer = mem.GetBuffer(); writer.Close(); mem.Dispose(); return(buffer); }
/// <summary> /// The channel wrote message. /// </summary> /// <param name="clientId"> /// The client id. /// </param> /// <param name="ioId"> /// The io id. /// </param> /// <param name="dataType"> /// The data type. /// </param> /// <param name="dataCount"> /// The data count. /// </param> /// <param name="status"> /// The status. /// </param> /// <returns> /// </returns> internal byte[] channelWroteMessage( int clientId, int ioId, EpicsType dataType, int dataCount, EpicsTransitionStatus status) { var mem = new MemoryStream(); var writer = new BinaryWriter(mem); mem.Capacity = 16; writer.Write(NetworkByteConverter.ToByteArray(CommandID.CA_PROTO_WRITE_NOTIFY)); writer.Write(new byte[2]); writer.Write(NetworkByteConverter.ToByteArray((UInt16)dataType)); writer.Write(NetworkByteConverter.ToByteArray((UInt16)dataCount)); writer.Write(NetworkByteConverter.ToByteArray((UInt32)status)); writer.Write(NetworkByteConverter.ToByteArray((UInt32)ioId)); var buffer = mem.GetBuffer(); writer.Close(); mem.Dispose(); return(buffer); }
static public DataPacket Encode(EpicsType type, object value, CARecord record, int nbElements = 1) { int size = 0; switch (type) { case EpicsType.Double: size += 4 + nbElements * 8; break; case EpicsType.Byte: size += nbElements; break; case EpicsType.Int: case EpicsType.Float: size += nbElements * 4; break; case EpicsType.Short: size += nbElements * 2; break; case EpicsType.String: size += 40; break; default: break; } DataPacket res = DataPacket.Create(16 + size + DataPacketBuilder.Padding(size)); res.DataCount = (uint)nbElements; res.DataType = (ushort)type; DataPacketBuilder.Encode(res, type, 0, value, nbElements); return(res); }
public byte[] ChannelCreatedMessage(int clientId, int serverId, EpicsType dataType, int dataCount, AccessRights access) { MemoryStream mem = new MemoryStream(); BinaryWriter writer = new BinaryWriter(mem); mem.Capacity = 32; writer.Write(((UInt16)CommandID.CA_PROTO_ACCESS_RIGHTS).ToByteArray()); writer.Write(new byte[6]); writer.Write(((UInt32)clientId).ToByteArray()); writer.Write(((UInt32)access).ToByteArray()); writer.Write(((UInt16)CommandID.CA_PROTO_CREATE_CHAN).ToByteArray()); if (dataCount > 30000) writer.Write(new byte[] { 0xFF, 0xFF }); else writer.Write(new byte[2]); writer.Write(((UInt16)dataType).ToByteArray()); if (dataCount > 30000) writer.Write(new byte[] { 0x00, 0x00 }); else writer.Write(((UInt16)dataCount).ToByteArray()); writer.Write(((UInt32)clientId).ToByteArray()); writer.Write(((UInt32)serverId).ToByteArray()); if (dataCount > 30000) { // Size writer.Write(((UInt32)0).ToByteArray()); // Data count writer.Write(((UInt32)dataCount).ToByteArray()); } byte[] buffer = mem.ToArray(); writer.Close(); mem.Dispose(); return buffer; }
internal EpicsServerMonitor( EpicsRecord record, RecordProperty property, EpicsServerChannel channel, EpicsType type, int dataCount, MonitorMask monitorMask, int subscriptionId) { this.record = record; this.property = property; this.channel = channel; this.type = type; this.dataCount = dataCount; this.monitorMask = monitorMask; this.subscriptionId = subscriptionId; try { var val = this.record[this.property.ToString()]; if (val == null) { val = 0; } var realData = NetworkByteConverter.objectToByte(val, this.type, this.record); this.channel.sendMonitorChange( this.subscriptionId, this.type, this.dataCount, EpicsTransitionStatus.ECA_NORMAL, realData); this.StartMonitor(); } catch (Exception e) { this.channel.sendMonitorChange( this.subscriptionId, this.type, this.dataCount, EpicsTransitionStatus.ECA_ADDFAIL, new byte[0]); } }
/// <summary> /// The read value. /// </summary> /// <param name="ioId"> /// The io id. /// </param> /// <param name="type"> /// The type. /// </param> /// <param name="dataCount"> /// The data count. /// </param> internal void readValue(int ioId, EpicsType type, int dataCount) { byte[] val; var objVal = this.Record[this.Property.ToString()]; if (objVal == null) { objVal = 0; } try { if (dataCount == 1) { val = NetworkByteConverter.objectToByte(objVal, type, this.Record); } else { if (objVal.GetType().IsGenericType) { val = NetworkByteConverter.objectToByte(objVal, type, this.Record, dataCount); } else { return; } } this.Conn.Send(this.Server.Codec.channelReadMessage(this.ClientId, ioId, type, dataCount, val)); } catch (Exception e) { this.Conn.Send( this.Server.Codec.errorMessage(this.ClientId, EpicsTransitionStatus.ECA_BADTYPE, "WRONG TYPE", new byte[16])); } }
/// <summary> /// The put value. /// </summary> /// <param name="ioId"> /// The io id. /// </param> /// <param name="type"> /// The type. /// </param> /// <param name="dataCount"> /// The data count. /// </param> /// <param name="payload"> /// The payload. /// </param> internal void putValue(int ioId, EpicsType type, int dataCount, byte[] payload) { try { object val; if (dataCount == 1) { val = NetworkByteConverter.byteToObject(payload, type); } else { val = NetworkByteConverter.byteToObject(payload, type, dataCount); } if (this.Property == RecordProperty.VAL) { if (dataCount == 1) { this.Record["VAL"] = Convert.ChangeType(val, this.Record.GetValueType()); } else { switch (this.Record.type) { case EpicsType.String: ((EpicsArray<string>)this.Record["VAL"]).Set(val); break; case EpicsType.Double: ((EpicsArray<double>)this.Record["VAL"]).Set(val); break; case EpicsType.Float: ((EpicsArray<float>)this.Record["VAL"]).Set(val); break; case EpicsType.Int: ((EpicsArray<int>)this.Record["VAL"]).Set(val); break; case EpicsType.Short: ((EpicsArray<short>)this.Record["VAL"]).Set(val); break; case EpicsType.SByte: ((EpicsArray<sbyte>)this.Record["VAL"]).Set(val); break; } } } else { this.Record[this.Property.ToString()] = Convert.ChangeType(val, this.Record[this.Property.ToString()].GetType()); } this.Conn.Send( this.Server.Codec.channelWroteMessage(this.ClientId, ioId, type, dataCount, EpicsTransitionStatus.ECA_NORMAL)); } catch (Exception exp) { this.Conn.Send( this.Server.Codec.errorMessage( this.ClientId, EpicsTransitionStatus.ECA_BADSTR, "Message was not correct", new byte[16])); return; } }
/// <summary> /// The send monitor change. /// </summary> /// <param name="subscriptionId"> /// The subscription id. /// </param> /// <param name="dataType"> /// The data type. /// </param> /// <param name="dataCount"> /// The data count. /// </param> /// <param name="status"> /// The status. /// </param> /// <param name="data"> /// The data. /// </param> internal void sendMonitorChange( int subscriptionId, EpicsType dataType, int dataCount, EpicsTransitionStatus status, byte[] data) { this.Conn.Send(this.Server.Codec.monitorChangeMessage(subscriptionId, this.ClientId, dataType, dataCount, data)); }
internal byte[] MonitorChangeMessage(int subscriptionId, int clientId, EpicsType dataType, int dataCount, byte[] data) { MemoryStream mem = new MemoryStream(); BinaryWriter writer = new BinaryWriter(mem); int padding = 0; if (data.Length % 8 == 0) padding = 8; else padding = (8 - (data.Length % 8)); mem.Capacity = 16 + data.Length + padding; writer.Write(((ushort)CommandID.CA_PROTO_EVENT_ADD).ToByteArray()); if (dataCount > 30000) writer.Write(new byte[] { 0xFF, 0xFF }); else writer.Write(((UInt16)(data.Length + padding)).ToByteArray()); writer.Write(((UInt16)dataType).ToByteArray()); if (dataCount > 30000) writer.Write(new byte[] { 0x00, 0x00 }); else writer.Write(((UInt16)dataCount).ToByteArray()); //writer.Write(NetworkByteConverter.ToByteArray((UInt32)clientId)); // Christoph implementation // Cosylab would send 0 which doesn't work writer.Write(((UInt32)1).ToByteArray()); // Value found to work... no idea why writer.Write(((UInt32)subscriptionId).ToByteArray()); if (dataCount > 30000) { writer.Write(((UInt32)(data.Length + padding)).ToByteArray()); writer.Write(((UInt32)dataCount).ToByteArray()); } writer.Write(data); writer.Write(new byte[padding]); byte[] buffer = mem.GetBuffer(); writer.Close(); mem.Dispose(); return buffer; }
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; } } }
internal void PutValue(int ioId, EpicsType type, int dataCount, byte[] payload) { try { object val; if (!Record.CanBeRemotlySet) { TcpConnection.Send(Server.Filter.ChannelWroteMessage(ClientId, ioId, type, dataCount, EpicsTransitionStatus.ECA_NORMAL)); return; } if (dataCount == 1) { val = payload.ByteToObject(type); Record[Property] = Convert.ChangeType(val, Record.GetPropertyType(Property)); } else { val = payload.ByteToObject(type, dataCount); int nb = Math.Min(((Array)Record[Property]).Length, dataCount); Type t = Record.GetPropertyType(Property).GetElementType(); if (Record.CallPropertySet(new PropertyDelegateEventArgs { OldValue = Record[Property], NewValue = val, Property = Property })) { int i = 0; foreach (object element in ((IEnumerable)val)) { Record.SetArrayValue(Property, i, Convert.ChangeType(element, t)); i++; } } } TcpConnection.Send(Server.Filter.ChannelWroteMessage(ClientId, ioId, type, dataCount, EpicsTransitionStatus.ECA_NORMAL)); } catch (Exception exp) { TcpConnection.Send(Server.Filter.ErrorMessage(ClientId, EpicsTransitionStatus.ECA_BADSTR, "Message was not correct", new byte[16])); return; } }
/// <summary> /// The monitor close message. /// </summary> /// <param name="dataType"> /// The data type. /// </param> /// <param name="serverId"> /// The server id. /// </param> /// <param name="subscriptionId"> /// The subscription id. /// </param> /// <returns> /// </returns> internal byte[] monitorCloseMessage(EpicsType dataType, int serverId, int subscriptionId) { var mem = new MemoryStream(); var writer = new BinaryWriter(mem); mem.Capacity = 16; writer.Write(NetworkByteConverter.ToByteArray(CommandID.CA_PROTO_EVENT_CANCEL)); writer.Write(new byte[2]); writer.Write(NetworkByteConverter.ToByteArray((UInt16)dataType)); writer.Write(new byte[2]); writer.Write(NetworkByteConverter.ToByteArray((UInt32)serverId)); writer.Write(NetworkByteConverter.ToByteArray((UInt32)subscriptionId)); var buffer = mem.GetBuffer(); writer.Close(); mem.Dispose(); return buffer; }
/// <summary> /// The monitor change message. /// </summary> /// <param name="subscriptionId"> /// The subscription id. /// </param> /// <param name="clientId"> /// The client id. /// </param> /// <param name="dataType"> /// The data type. /// </param> /// <param name="dataCount"> /// The data count. /// </param> /// <param name="data"> /// The data. /// </param> /// <returns> /// </returns> internal byte[] monitorChangeMessage(int subscriptionId, int clientId, EpicsType dataType, int dataCount, byte[] data) { var mem = new MemoryStream(); var writer = new BinaryWriter(mem); var padding = 0; if (data.Length % 8 == 0) { padding = 8; } else { padding = 8 - (data.Length % 8); } mem.Capacity = 16 + data.Length + padding; writer.Write(NetworkByteConverter.ToByteArray(CommandID.CA_PROTO_EVENT_ADD)); writer.Write(NetworkByteConverter.ToByteArray((UInt16)(data.Length + padding))); writer.Write(NetworkByteConverter.ToByteArray((UInt16)dataType)); writer.Write(NetworkByteConverter.ToByteArray((UInt16)dataCount)); writer.Write(NetworkByteConverter.ToByteArray((UInt32)clientId)); writer.Write(NetworkByteConverter.ToByteArray((UInt32)subscriptionId)); writer.Write(data); writer.Write(new byte[padding]); var buffer = mem.GetBuffer(); writer.Close(); mem.Dispose(); return buffer; }
/// <summary> /// The channel wrote message. /// </summary> /// <param name="clientId"> /// The client id. /// </param> /// <param name="ioId"> /// The io id. /// </param> /// <param name="dataType"> /// The data type. /// </param> /// <param name="dataCount"> /// The data count. /// </param> /// <param name="status"> /// The status. /// </param> /// <returns> /// </returns> internal byte[] channelWroteMessage( int clientId, int ioId, EpicsType dataType, int dataCount, EpicsTransitionStatus status) { var mem = new MemoryStream(); var writer = new BinaryWriter(mem); mem.Capacity = 16; writer.Write(NetworkByteConverter.ToByteArray(CommandID.CA_PROTO_WRITE_NOTIFY)); writer.Write(new byte[2]); writer.Write(NetworkByteConverter.ToByteArray((UInt16)dataType)); writer.Write(NetworkByteConverter.ToByteArray((UInt16)dataCount)); writer.Write(NetworkByteConverter.ToByteArray((UInt32)status)); writer.Write(NetworkByteConverter.ToByteArray((UInt32)ioId)); var buffer = mem.GetBuffer(); writer.Close(); mem.Dispose(); return buffer; }
internal void AddMonitor(EpicsType type, int dataCount, int subscriptionId, MonitorMask mask) { //does he request to add a subscriptionId at the same Id as it already exist? lock (monitors) { if (monitors.ContainsKey(subscriptionId)) return; monitors.Add(subscriptionId, new CAChannelMonitor(Record, Property, this, type, dataCount, mask, subscriptionId)); } }
internal byte[] MonitorCloseMessage(EpicsType dataType, int serverId, int subscriptionId) { MemoryStream mem = new MemoryStream(); BinaryWriter writer = new BinaryWriter(mem); mem.Capacity = 16; writer.Write(((ushort)CommandID.CA_PROTO_EVENT_CANCEL).ToByteArray()); writer.Write(new byte[2]); writer.Write(((UInt16)dataType).ToByteArray()); writer.Write(new byte[2]); writer.Write(((UInt32)serverId).ToByteArray()); writer.Write(((UInt32)subscriptionId).ToByteArray()); byte[] buffer = mem.GetBuffer(); writer.Close(); mem.Dispose(); return buffer; }
/// <summary> /// Function for full change from an Object to Byte. /// </summary> /// <typeparam name="dataType">Datatype of the source</typeparam> /// <param name="src">Src object which shall be transferred</param> /// <param name="epicsType">Target epics type</param> /// <param name="record">Record from where the value comes</param> /// <param name="dataCount">Count of data requested</param> /// <returns></returns> internal static byte[] ToByteArray <dataType>(object src, EpicsType epicsType, CARecord record, int dataCount) { dataType[] source; if (src.GetType().IsArray) { source = new dataType[dataCount]; int i = 0; foreach (object element in ((System.Collections.IEnumerable)src)) { if (i >= source.Length) { break; } source[i] = (dataType)Convert.ChangeType(element, typeof(dataType)); i++; } } else { source = new dataType[] { (dataType)Convert.ChangeType(src, typeof(dataType)) } }; using (MemoryStream mem = new MemoryStream()) { using (BinaryWriter writer = new BinaryWriter(mem)) { switch (epicsType) { #region simple Types case EpicsType.String: for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(source[i].ToString(), true)); } return(mem.ToArray()); case EpicsType.Short: for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(Convert.ToInt16(source[i]))); } return(mem.ToArray()); case EpicsType.Float: for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(Convert.ToSingle(source[i]))); } return(mem.ToArray()); case EpicsType.Byte: for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(Convert.ToByte(source[i]))); } return(mem.ToArray()); case EpicsType.Int: for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(Convert.ToInt32(source[i]))); } return(mem.ToArray()); case EpicsType.Double: for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(Convert.ToDouble(source[i]))); } return(mem.ToArray()); #endregion #region StatusTypes case EpicsType.Status_Double: writer.Write(ToByteArray((ushort)(record["STAT"] ?? -1))); writer.Write(ToByteArray((ushort)(record["SEVR"] ?? -1))); writer.Write(ToByteArray((uint)0)); // Skip 4 bytes for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(Convert.ToDouble(source[i]))); } return(mem.ToArray()); case EpicsType.Status_Float: writer.Write(ToByteArray((ushort)(record["STAT"] ?? 0))); writer.Write(ToByteArray((ushort)(record["SEVR"] ?? 0))); for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(Convert.ToSingle(source[i]))); } return(mem.ToArray()); case EpicsType.Status_Int: writer.Write(ToByteArray((ushort)(record["STAT"] ?? 0))); writer.Write(ToByteArray((ushort)(record["SEVR"] ?? 0))); for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(Convert.ToInt32(source[i]))); } return(mem.ToArray()); case EpicsType.Status_Byte: writer.Write(ToByteArray((ushort)(record["STAT"] ?? 0))); writer.Write(ToByteArray((ushort)(record["SEVR"] ?? 0))); for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(Convert.ToByte(source[i]))); } return(mem.ToArray()); case EpicsType.Status_Short: writer.Write(ToByteArray((ushort)(record["STAT"] ?? 0))); writer.Write(ToByteArray((ushort)(record["SEVR"] ?? 0))); for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(Convert.ToInt16(source[i]))); } return(mem.ToArray()); case EpicsType.Status_String: writer.Write(ToByteArray((ushort)(record["STAT"] ?? 0))); writer.Write(ToByteArray((ushort)(record["SEVR"] ?? 0))); for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(source[i].ToString(), true)); } return(mem.ToArray()); #endregion #region TimeTypes case EpicsType.Time_Double: writer.Write(ToByteArray((ushort)(record["STAT"] ?? 0))); writer.Write(ToByteArray((ushort)(record["SEVR"] ?? 0))); writer.Write(ToByteArray((DateTime)(record["TIME"] ?? 0))); writer.Write(ToByteArray((UInt32)0)); // Skip 4 bytes for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(Convert.ToDouble(source[i]))); } return(mem.ToArray()); case EpicsType.Time_Float: writer.Write(ToByteArray((ushort)(record["STAT"] ?? 0))); writer.Write(ToByteArray((ushort)(record["SEVR"] ?? 0))); writer.Write(ToByteArray((DateTime)(record["TIME"] ?? 0))); for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(Convert.ToSingle(source[i]))); } return(mem.ToArray()); case EpicsType.Time_Int: writer.Write(ToByteArray((ushort)(record["STAT"] ?? 0))); writer.Write(ToByteArray((ushort)(record["SEVR"] ?? 0))); writer.Write(ToByteArray((DateTime)(record["TIME"] ?? 0))); for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(Convert.ToInt32(source[i]))); } return(mem.ToArray()); case EpicsType.Time_Short: writer.Write(ToByteArray((ushort)(record["STAT"] ?? 0))); writer.Write(ToByteArray((ushort)(record["SEVR"] ?? 0))); writer.Write(ToByteArray((DateTime)(record["TIME"] ?? 0))); writer.Write(new byte[2]); for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(Convert.ToInt16(source[i]))); } return(mem.ToArray()); case EpicsType.Time_String: writer.Write(ToByteArray((ushort)(record["STAT"] ?? 0))); writer.Write(ToByteArray((ushort)(record["SEVR"] ?? 0))); writer.Write(ToByteArray((DateTime)(record["TIME"] ?? 0))); for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(source[i].ToString(), true)); } return(mem.ToArray()); case EpicsType.Time_Byte: writer.Write(ToByteArray((ushort)(record["STAT"] ?? 0))); writer.Write(ToByteArray((ushort)(record["SEVR"] ?? 0))); writer.Write(ToByteArray((DateTime)(record["TIME"] ?? 0))); for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(Convert.ToByte(source[i]))); } return(mem.ToArray()); #endregion #region ControlTypes case EpicsType.Control_Double: writer.Write(ToByteArray((ushort)(record["STAT"] ?? 0))); writer.Write(ToByteArray((ushort)(record["SEVR"] ?? 0))); writer.Write(ToByteArray((short)(record["PREC"] ?? 0))); writer.Write(new byte[] { 0, 0 }); writer.Write(ToByteArray((string)(record["EGU"] ?? ""), 8)); writer.Write(ToByteArray(record.GetDouble("HIGHDISP"))); writer.Write(ToByteArray(record.GetDouble("LOWDISP"))); writer.Write(ToByteArray(record.GetDouble("HIHI"))); writer.Write(ToByteArray(record.GetDouble("HIGH"))); writer.Write(ToByteArray(record.GetDouble("LOW"))); writer.Write(ToByteArray(record.GetDouble("LOLO"))); writer.Write(ToByteArray(record.GetDouble("HOPR"))); writer.Write(ToByteArray(record.GetDouble("LOPR"))); for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(Convert.ToDouble(source[i]))); } return(mem.ToArray()); case EpicsType.Control_Float: writer.Write(ToByteArray((ushort)(record["STAT"] ?? 0))); writer.Write(ToByteArray((ushort)(record["SEVR"] ?? 0))); writer.Write(ToByteArray((short)(record["PREC"] ?? 0))); writer.Write(new byte[] { 0, 0 }); writer.Write(ToByteArray((string)(record["EGU"] ?? ""), 8)); writer.Write(ToByteArray(record.GetFloat("HIGHDISP"))); writer.Write(ToByteArray(record.GetFloat("LOWDISP"))); writer.Write(ToByteArray(record.GetFloat("HIHI"))); writer.Write(ToByteArray(record.GetFloat("HIGH"))); writer.Write(ToByteArray(record.GetFloat("LOW"))); writer.Write(ToByteArray(record.GetFloat("LOLO"))); writer.Write(ToByteArray(record.GetFloat("HOPR"))); writer.Write(ToByteArray(record.GetFloat("LOPR"))); for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(Convert.ToSingle(source[i]))); } return(mem.ToArray()); case EpicsType.Control_Int: writer.Write(ToByteArray((ushort)(record["STAT"] ?? 0))); writer.Write(ToByteArray((ushort)(record["SEVR"] ?? 0))); //writer.Write(new byte[] { 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77 }); writer.Write(ToByteArray((string)(record["EGU"] ?? ""), 8)); writer.Write(ToByteArray(record.GetInt("HIGHDISP"))); writer.Write(ToByteArray(record.GetInt("LOWDISP"))); writer.Write(ToByteArray(record.GetInt("HIHI"))); writer.Write(ToByteArray(record.GetInt("HIGH"))); writer.Write(ToByteArray(record.GetInt("LOW"))); writer.Write(ToByteArray(record.GetInt("LOLO"))); writer.Write(ToByteArray(record.GetInt("HOPR"))); writer.Write(ToByteArray(record.GetInt("LOPR"))); for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(Convert.ToInt32(source[i]))); } return(mem.ToArray()); case EpicsType.Control_Short: writer.Write(ToByteArray((ushort)(record["STAT"] ?? 0))); writer.Write(ToByteArray((ushort)(record["SEVR"] ?? 0))); writer.Write(ToByteArray((string)(record["EGU"] ?? ""), 8)); writer.Write(ToByteArray(record.GetShort("HIGHDISP"))); writer.Write(ToByteArray(record.GetShort("LOWDISP"))); writer.Write(ToByteArray(record.GetShort("HIHI"))); writer.Write(ToByteArray(record.GetShort("HIGH"))); writer.Write(ToByteArray(record.GetShort("LOW"))); writer.Write(ToByteArray(record.GetShort("LOLO"))); writer.Write(ToByteArray(record.GetShort("HOPR"))); writer.Write(ToByteArray(record.GetShort("LOPR"))); for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(Convert.ToInt16(source[i]))); } return(mem.ToArray()); case EpicsType.Control_Byte: throw new Exception("NOT IMPLEMENTED"); case EpicsType.Control_String: writer.Write(ToByteArray((ushort)record["STAT"])); writer.Write(ToByteArray((ushort)record["SEVR"])); for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(Convert.ToString(source[i]), true)); } return(mem.ToArray()); #endregion #region GraphicsTypes case EpicsType.Display_Double: writer.Write(ToByteArray((ushort)(record["STAT"] ?? 0))); writer.Write(ToByteArray((ushort)(record["SEVR"] ?? 0))); writer.Write(ToByteArray((short)(record["PREC"] ?? 0))); writer.Write(new byte[] { 0, 0 }); writer.Write(ToByteArray((string)(record["EGU"] ?? ""), 8)); writer.Write(ToByteArray(record.GetDouble("HIGHDISP"))); writer.Write(ToByteArray(record.GetDouble("LOWDISP"))); writer.Write(ToByteArray(record.GetDouble("HIHI"))); writer.Write(ToByteArray(record.GetDouble("HIGH"))); writer.Write(ToByteArray(record.GetDouble("LOW"))); writer.Write(ToByteArray(record.GetDouble("LOLO"))); for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(Convert.ToDouble(source[i]))); } return(mem.ToArray()); case EpicsType.Display_Float: writer.Write(ToByteArray((ushort)(record["STAT"] ?? 0))); writer.Write(ToByteArray((ushort)(record["SEVR"] ?? 0))); writer.Write(ToByteArray((short)(record["PREC"] ?? 0))); writer.Write(new byte[] { 0, 0 }); writer.Write(ToByteArray((string)(record["EGU"] ?? ""), 8)); writer.Write(ToByteArray(record.GetFloat("HIGHDISP"))); writer.Write(ToByteArray(record.GetFloat("LOWDISP"))); writer.Write(ToByteArray(record.GetFloat("HIHI"))); writer.Write(ToByteArray(record.GetFloat("HIGH"))); writer.Write(ToByteArray(record.GetFloat("LOW"))); writer.Write(ToByteArray(record.GetFloat("LOLO"))); for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(Convert.ToSingle(source[i]))); } return(mem.ToArray()); case EpicsType.Display_Int: writer.Write(ToByteArray((ushort)(record["STAT"] ?? 0))); writer.Write(ToByteArray((ushort)(record["SEVR"] ?? 0))); writer.Write(ToByteArray((string)(record["EGU"] ?? ""), 8)); writer.Write(ToByteArray(record.GetInt("HIGHDISP"))); writer.Write(ToByteArray(record.GetInt("LOWDISP"))); writer.Write(ToByteArray(record.GetInt("HIHI"))); writer.Write(ToByteArray(record.GetInt("HIGH"))); writer.Write(ToByteArray(record.GetInt("LOW"))); writer.Write(ToByteArray(record.GetInt("LOLO"))); for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(Convert.ToInt32(source[i]))); } return(mem.ToArray()); case EpicsType.Display_Short: writer.Write(ToByteArray((ushort)(record["STAT"] ?? 0))); writer.Write(ToByteArray((ushort)(record["SEVR"] ?? 0))); writer.Write(ToByteArray((string)(record["EGU"] ?? ""), 8)); writer.Write(ToByteArray(record.GetShort("HIGHDISP"))); writer.Write(ToByteArray(record.GetShort("LOWDISP"))); writer.Write(ToByteArray(record.GetShort("HIHI"))); writer.Write(ToByteArray(record.GetShort("HIGH"))); writer.Write(ToByteArray(record.GetShort("LOW"))); writer.Write(ToByteArray(record.GetShort("LOLO"))); for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(Convert.ToInt16(source[i]))); } return(mem.ToArray()); case EpicsType.Display_Byte: throw new Exception("NOT IMPLEMENTED"); case EpicsType.Display_String: writer.Write(ToByteArray((ushort)(record["STAT"] ?? 0))); writer.Write(ToByteArray((ushort)(record["SEVR"] ?? 0))); for (int i = 0; i < dataCount; i++) { writer.Write(ToByteArray(Convert.ToString(source[i]), true)); } return(mem.ToArray()); #endregion default: return(null); } } } }
/// <summary> /// The channel created message. /// </summary> /// <param name="clientId"> /// The client id. /// </param> /// <param name="serverId"> /// The server id. /// </param> /// <param name="dataType"> /// The data type. /// </param> /// <param name="dataCount"> /// The data count. /// </param> /// <param name="access"> /// The access. /// </param> /// <returns> /// </returns> internal byte[] channelCreatedMessage( int clientId, int serverId, EpicsType dataType, int dataCount, AccessRights access) { var mem = new MemoryStream(); var writer = new BinaryWriter(mem); mem.Capacity = 32; writer.Write(NetworkByteConverter.ToByteArray(CommandID.CA_PROTO_ACCESS_RIGHTS)); writer.Write(new byte[6]); writer.Write(NetworkByteConverter.ToByteArray((UInt32)clientId)); writer.Write(NetworkByteConverter.ToByteArray((UInt32)access)); writer.Write(NetworkByteConverter.ToByteArray(CommandID.CA_PROTO_CREATE_CHAN)); writer.Write(new byte[2]); writer.Write(NetworkByteConverter.ToByteArray((UInt16)dataType)); writer.Write(NetworkByteConverter.ToByteArray((UInt16)dataCount)); writer.Write(NetworkByteConverter.ToByteArray((UInt32)clientId)); writer.Write(NetworkByteConverter.ToByteArray((UInt32)serverId)); var buffer = mem.GetBuffer(); writer.Close(); mem.Dispose(); return buffer; }
internal static object ByteToObject(this byte[] payload, EpicsType epicsType, int datacount) { switch (epicsType) { /// -> basic types case EpicsType.String: { string[] arr = new string[datacount]; for (int i = 0; i < datacount; i++) { string tmp = ByteConverter.ToString(payload, i * 40); arr[i] = tmp; /*offset += tmp.Length + 1;*/ } return(arr); } case EpicsType.Short: { short[] arr = new short[datacount]; for (int i = 0; i < datacount; i++) { arr[i] = ByteConverter.ToInt16(payload, i * 2); } return(arr); } case EpicsType.Float: { float[] arr = new float[datacount]; for (int i = 0; i < datacount; i++) { arr[i] = ByteConverter.ToFloat(payload, i * 4); } return(arr); } case EpicsType.Byte: { byte[] arr = new byte[datacount]; for (int i = 0; i < datacount; i++) { arr[i] = ByteConverter.ToByte(payload, i); } return(arr); } case EpicsType.Int: { int[] arr = new int[datacount]; for (int i = 0; i < datacount; i++) { arr[i] = ByteConverter.ToInt32(payload, i * 4); } return(arr); } case EpicsType.Double: { double[] arr = new double[datacount]; for (int i = 0; i < datacount; i++) { arr[i] = ByteConverter.ToDouble(payload, i * 8); } return(arr); } default: throw new Exception("Type " + epicsType.ToString() + " not yet supported"); } }
/// <summary> /// The send monitor close. /// </summary> /// <param name="subscriptionId"> /// The subscription id. /// </param> /// <param name="type"> /// The type. /// </param> internal void sendMonitorClose(int subscriptionId, EpicsType type) { this.Conn.Send(this.Server.Codec.monitorCloseMessage(type, this.ServerId, subscriptionId)); }
/// <summary> /// /// </summary> /// <param name="clientId">IMPORTANT IT's not sure yet that this has to be the cliendId could also be the ioId</param> /// <param name=IOID>IMPORTANT IT's not sure yet that this has to be the ioId could also be the cliendId</param> /// <param name="dataType"></param> /// <param name="dataCount"></param> /// <param name="data"></param> /// <returns></returns> public byte[] ChannelReadMessage(int clientId, int ioId, EpicsType dataType, int dataCount, byte[] data) { MemoryStream mem = new MemoryStream(); BinaryWriter writer = new BinaryWriter(mem); int padding = 8; /*if (dataCount > 60000) padding = 0;*/ if (data.Length % 8 != 0) padding = (padding - (data.Length % 8)); mem.Capacity = 16 + data.Length + padding; writer.Write(((UInt16)CommandID.CA_PROTO_READ_NOTIFY).ToByteArray()); if (dataCount > 30000) writer.Write(new byte[] { 0xFF, 0xFF }); else writer.Write(((UInt16)(data.Length + padding)).ToByteArray()); writer.Write(((UInt16)dataType).ToByteArray()); if (dataCount > 30000) writer.Write(new byte[] { 0x00, 0x00 }); else writer.Write(((UInt16)dataCount).ToByteArray()); // Seems again an issue with the specifications where only a value of 1 works. //writer.Write(((UInt32)clientId).ToByteArray()); writer.Write(((UInt32)1).ToByteArray()); writer.Write(((UInt32)ioId).ToByteArray()); if (dataCount > 30000) { writer.Write(((UInt32)(data.Length + padding)).ToByteArray()); byte[] b = ((UInt32)(dataCount)).ToByteArray(); writer.Write(b); } writer.Write(data); if(padding > 0) writer.Write(new byte[padding]); byte[] buffer = mem.ToArray(); writer.Close(); mem.Dispose(); return buffer; }
internal byte[] ChannelWroteMessage(int clientId, int ioId, EpicsType dataType, int dataCount, EpicsTransitionStatus status) { MemoryStream mem = new MemoryStream(); BinaryWriter writer = new BinaryWriter(mem); mem.Capacity = 16; writer.Write(((ushort)CommandID.CA_PROTO_WRITE_NOTIFY).ToByteArray()); writer.Write(new byte[2]); writer.Write(((UInt16)dataType).ToByteArray()); writer.Write(((UInt16)dataCount).ToByteArray()); writer.Write(((UInt32)status).ToByteArray()); writer.Write(((UInt32)ioId).ToByteArray()); byte[] buffer = mem.GetBuffer(); writer.Close(); mem.Dispose(); return buffer; }
internal void PutValue(int ioId, EpicsType type, int dataCount, byte[] payload, bool notify) { try { object val; if (!Record.CanBeRemotlySet) { TcpConnection.Send(Server.Filter.ChannelWroteMessage(ClientId, ioId, type, dataCount, EpicsTransitionStatus.ECA_NORMAL)); return; } if (dataCount == 1) { val = payload.ByteToObject(type); using (Record.CreateAtomicChange()) { if (Record[Property] is Enum) { if (val is String) { Record[Property] = Enum.Parse(Record[Property].GetType(), (string)val); } else { Record[Property] = int.Parse(val.ToString()); } } else { Record[Property] = Convert.ChangeType(val, Record.GetPropertyType(Property)); } } } else { val = payload.ByteToObject(type, dataCount); int nb = Math.Min(((dynamic)Record[Property]).Length, dataCount); Type t = Record.GetPropertyType(Property); if (t.Name.Split('`')[0] == "ArrayContainer") { t = t.GetGenericArguments().First(); } else { t = t.GetElementType(); } if (Record.CallPropertySet(new PropertyDelegateEventArgs { OldValue = Record[Property], NewValue = val, Property = Property })) { int i = 0; using (Record.CreateAtomicChange()) { foreach (object element in ((IEnumerable)val)) { Record.SetArrayValue(Property, i, Convert.ChangeType(element, t)); i++; } } } } if (notify) { TcpConnection.Send(Server.Filter.ChannelWroteMessage(ClientId, ioId, type, dataCount, EpicsTransitionStatus.ECA_NORMAL)); } } catch (Exception exp) { TcpConnection.Send(Server.Filter.ErrorMessage(ClientId, EpicsTransitionStatus.ECA_BADSTR, "Message was not correct", new byte[16])); return; } }
internal void ReadValue(int ioId, EpicsType type, int dataCount) { byte[] val; if (Record.Scan == ScanAlgorithm.PASSIVE) Record.CallPrepareRecord(); object objVal = Record[Property]; if (objVal == null) objVal = 0; try { if (objVal.GetType().IsArray) val = objVal.ToByteArray(type, Record, dataCount); else val = objVal.ToByteArray(type, Record); TcpConnection.Send(Server.Filter.ChannelReadMessage(ClientId, ioId, type, dataCount, val)); } catch (Exception e) { Console.WriteLine(e.Message + "\n\r" + e.StackTrace); TcpConnection.Send(Server.Filter.ErrorMessage(ClientId, EpicsTransitionStatus.ECA_BADTYPE, "WRONG TYPE", new byte[16])); } }