/// <summary> /// Инициализация NMS-сообщения. /// </summary> /// <param name="source">Адрес источника сообщения.</param> /// <param name="destanation">Адрес получателя сообщения.</param> /// <param name="priority">Приоритет.</param> /// <param name="service">Тип сервиса.</param> /// <param name="isResponsible">Требуется ли ответ/подтверждение на запрос.</param> /// <param name="id">Идентификатор NMS-сообщения.</param> /// <param name="r1">Разрешено ли событие для <see cref="NmsServiceType.AlterEventConditionMonitoring"/>.</param> /// <param name="nmsData">NMS-данные.</param> /// <remarks>Это единственный метод, который может изменить сообщение. Должен вызываться в конструкторе.</remarks> protected void Initialize( Address source, Address destanation, PriorityType priority, NmsServiceType service, bool isResponsible, int id, bool r1, byte[] nmsData) { Contract.Requires(source != null); Contract.Requires(destanation != null); Contract.Requires(nmsData != null); Contract.Requires(nmsData.Length <= NmsMaxDataLength); Contract.Ensures(!IsResponse); Contract.Ensures(Datagram != null); Contract.Ensures(ServiceType == service); var nmsLength = Math.Min(nmsData.Length, NmsMaxDataLength); var data = new byte[NmsHeaderLength + nmsLength]; Array.Copy(nmsData, 0, data, NmsHeaderLength, nmsLength); data[0] = (byte)(((byte)service << 3) | ((id & 1023) >> 8)); data[1] = (byte)(id & 0xFF); data[2] = (byte)((isResponsible ? 0 : 0x80) | (r1 ? 0x40 : 0) | nmsLength & 0x3F); Datagram = new NibusDatagram(null, source, destanation, priority, ProtocolType.Nms, data); Contract.Assume(!IsResponse); }
public NmsInvalidMessage(NibusDatagram original, Exception exception) { Original = original; Exception = exception; Initialize(original.Source, original.Destanation, PriorityType.Normal, NmsServiceType.Invalid, false, 0, false, new byte[0]); }
/// <summary> /// The default Constructor. /// </summary> internal NmsUploadSegment(NibusDatagram datagram) : base(datagram) { Contract.Requires(datagram != null); Contract.Requires(datagram.ProtocolType == ProtocolType.Nms); Contract.Requires(datagram.Data.Count >= NmsHeaderLength); Contract.Assume(ServiceType == NmsServiceType.UploadSegment); }
/// <summary> /// The default Constructor. /// </summary> internal NmsRequestDomainDownload(NibusDatagram datagram) : base(datagram) { Contract.Requires(datagram != null); Contract.Requires(datagram.ProtocolType == ProtocolType.Nms); Contract.Requires(datagram.Data.Count >= NmsHeaderLength); Contract.Assume(ServiceType == NmsServiceType.RequestDomainDownload); }
/// <summary> /// The default Constructor. /// </summary> internal NmsStartProgramInvocation(NibusDatagram datagram) : base(datagram) { Contract.Requires(datagram != null); Contract.Requires(datagram.ProtocolType == ProtocolType.Nms); Contract.Requires(datagram.Data.Count >= NmsHeaderLength); Contract.Assume(ServiceType == NmsServiceType.StartProgramInvocation); }
internal NmsTerminateDownloadSequence(NibusDatagram datagram) : base(datagram) { Contract.Requires(datagram != null); Contract.Requires(datagram.ProtocolType == ProtocolType.Nms); Contract.Requires(datagram.Data.Count >= NmsHeaderLength); Contract.Assume(ServiceType == NmsServiceType.TerminateDownloadSequence); }
/// <summary> /// The default Constructor. /// </summary> internal NmsVerifyDomainChecksum(NibusDatagram datagram) : base(datagram) { Contract.Requires(datagram != null); Contract.Requires(datagram.ProtocolType == ProtocolType.Nms); Contract.Requires(datagram.Data.Count >= NmsHeaderLength); Contract.Assume(ServiceType == NmsServiceType.VerifyDomainChecksum); }
/// <summary> /// Конструктор создания NMS-сообщения из низлежащего сообщения <see cref="NibusDatagram"/>. /// </summary> /// <param name="datagram">Датаграмма.</param> /// <remarks> /// Минимальный размер длины данных <paramref name="datagram"/> должен быть не меньше размера /// заголовка <see cref="NmsMessage.NmsHeaderLength"/>. /// </remarks> /// <seealso cref="NmsMessage.CreateFrom"/> internal NmsEventNotification(NibusDatagram datagram) : base(datagram) { Contract.Requires(datagram != null); Contract.Requires(datagram.ProtocolType == ProtocolType.Nms); Contract.Requires(datagram.Data.Count >= NmsHeaderLength); Contract.Ensures(ServiceType == NmsServiceType.EventNotification); Contract.Assume(ServiceType == NmsServiceType.EventNotification); }
/// <summary> /// Конструктор создания NMS-сообщения сервиса <see cref="NmsServiceType.Write"/> /// из низлежащего сообщения <see cref="NibusDatagram"/>. /// </summary> /// <param name="datagram">Датаграмма.</param> /// <remarks> /// Минимальный размер длины данных <paramref name="datagram"/> должен быть не меньше размера /// заголовка <see cref="NmsMessage.NmsHeaderLength"/> плюс размер NMS-данных. /// </remarks> /// <seealso cref="NmsMessage.CreateFrom"/> /// <exception cref="InvalidNibusDatagram"></exception> internal NmsWrite(NibusDatagram datagram) : base(datagram) { Contract.Requires(datagram != null); Contract.Requires(datagram.ProtocolType == ProtocolType.Nms); Contract.Requires(datagram.Data.Count >= NmsHeaderLength); Contract.Ensures(ServiceType == NmsServiceType.Write); if (datagram.Data.Count < NmsHeaderLength + 1 || !IsResponse && datagram.Data.Count < NmsHeaderLength + 1 + GetSizeOf(ValueType)) { throw new InvalidNibusDatagram("Invalid NMS message length"); } Contract.Assume(ServiceType == NmsServiceType.Write); }
/// <summary> /// The default Constructor. /// </summary> public NmsReadMany(Address source, Address destanation, params int[] ids) { Contract.Requires(0 < ids.Length); //Contract.Requires(ids.Length <= NibusDatagram.MaxDataLength / 3); var data = ids.SelectMany( id => new[] { (byte)(((byte)NmsServiceType.Read << 3) | (id >> 8)), (byte)(id & 0xFF), (byte)0 }).ToArray(); Datagram = new NibusDatagram(null, source, destanation, PriorityType.Normal, ProtocolType.Nms, data); }
/// <summary> /// The default Constructor. /// </summary> internal NmsAlterEventConditionMonitoring(NibusDatagram datagram) : base(datagram) { Contract.Requires(datagram != null); Contract.Requires(datagram.ProtocolType == ProtocolType.Nms); Contract.Requires(datagram.Data.Count >= NmsHeaderLength); Contract.Ensures(ServiceType == NmsServiceType.AlterEventConditionMonitoring); if (IsResponse && datagram.Data.Count < NmsMaxDataLength + 1) { throw new InvalidNibusDatagram("Invalid NMS message length"); } Contract.Assume(ServiceType == NmsServiceType.AlterEventConditionMonitoring); }
/// <summary> /// Конструктор создания NMS-сообщения из низлежащего сообщения <see cref="NibusDatagram"/>. /// </summary> /// <param name="datagram">Датаграмма.</param> /// <remarks> /// Минимальный размер длины данных <paramref name="datagram"/> должен быть не меньше размера /// заголовка <see cref="NmsHeaderLength"/> плюс размер NMS-данных. /// Конструктор потомка !должен! проверить на валидность датаграмму /// и в случае ошибки сгенерировать исключение <see cref="InvalidNibusDatagram"/> /// </remarks> /// <seealso cref="CreateFrom"/> /// <exception cref="InvalidNibusDatagram">Ошибка при декодировании датаграммы.</exception> protected NmsMessage(NibusDatagram datagram) { Contract.Requires(datagram != null); Contract.Requires(datagram.ProtocolType == ProtocolType.Nms); Contract.Requires(datagram.Data.Count >= NmsHeaderLength); if (datagram.Data.Count < NmsHeaderLength || datagram.Data.Count < (datagram.Data[2] & 0x3F) + NmsHeaderLength) { throw new InvalidNibusDatagram("Invalid NMS message length"); } Contract.Ensures(Datagram != null); Datagram = datagram; }
/// <summary> /// Конструктор создания сообщения из датаграммы NiBUS. /// </summary> /// <param name="datagram">Датаграмма.</param> internal NmsDownloadSegment(NibusDatagram datagram) : base(datagram) { Contract.Requires(datagram != null); Contract.Requires(datagram.ProtocolType == ProtocolType.Nms); Contract.Requires(datagram.Data.Count >= NmsHeaderLength); Contract.Ensures(ServiceType == NmsServiceType.DownloadSegment); if (IsResponse && datagram.Data.Count < NmsHeaderLength + 1) { throw new ArgumentException(); } if (!IsResponse && datagram.Data.Count < NmsHeaderLength + sizeof(uint)) { throw new ArgumentException(); } Contract.Assume(ServiceType == NmsServiceType.DownloadSegment); }
/// <summary> /// Конструктор создания NMS-сообщения сервиса <see cref="NmsServiceType.Read"/> /// из низлежащего сообщения <see cref="NibusDatagram"/>. /// </summary> /// <param name="datagram">Датаграмма.</param> /// <remarks> /// Минимальный размер длины данных <paramref name="datagram"/> должен быть не меньше размера /// заголовка <see cref="NmsMessage.NmsHeaderLength"/> плюс размер NMS-данных. /// </remarks> /// <seealso cref="NmsMessage.CreateFrom"/> /// <exception cref="InvalidNibusDatagram"></exception> internal NmsRead(NibusDatagram datagram) : base(datagram) { Contract.Requires(datagram != null); Contract.Requires(datagram.ProtocolType == ProtocolType.Nms); Contract.Requires(datagram.Data.Count >= NmsHeaderLength); Contract.Ensures(ServiceType == NmsServiceType.Read); Contract.Assume(ServiceType == NmsServiceType.Read); if (!IsResponse) { return; } if (datagram.Data.Count < NmsHeaderLength + 3) { throw new InvalidNibusDatagram("Invalid NMS message length"); } _errorCode = datagram.Data[NmsHeaderLength + 0]; _valueType = (NmsValueType)datagram.Data[NmsHeaderLength + 1]; _value = ReadValue(_valueType, datagram.Data.ToArray(), NmsHeaderLength + 2); }
public void EncodeDecode_Equal( [ValueSource("Addresses")] Address destanation, [ValueSource("Addresses")] Address source, [Values(PriorityType.Realtime, PriorityType.AboveNormal, PriorityType.Normal, PriorityType.BelowNormal)] PriorityType priority, [Values(ProtocolType.Nms, ProtocolType.Sarp)] ProtocolType protocol) { var codec = new NibusDataCodec(); var datagramOrig = new NibusDatagram(codec, source, destanation, priority, protocol, new byte[] { 1, 2, 3, 4, 6, 7, 8, 9 }); codec.Encoder.Post(datagramOrig); var data = codec.Encoder.Receive(); codec.Decoder.Post(data); var datagramCopy = codec.Decoder.Receive(); Assert.That(datagramOrig.Destanation == datagramCopy.Destanation); Assert.That(datagramOrig.Source == datagramCopy.Source); Assert.That(datagramOrig.Priority == datagramCopy.Priority); Assert.That(datagramOrig.ProtocolType == datagramCopy.ProtocolType); Assert.That(datagramOrig.Data.SequenceEqual(datagramCopy.Data)); }
/// <summary> /// Фабричный метод создания NMS-сообщений на основе датаграммы. /// </summary> /// <param name="datagram">Датаграмма.</param> /// <returns>Экземпляр NMS-сообщения одного из производных типов от <see cref="NmsMessage"/></returns> /// <exception cref="InvalidNibusDatagram"></exception> internal static NmsMessage CreateFrom(NibusDatagram datagram) { Contract.Requires(datagram != null); Contract.Requires(datagram.ProtocolType == ProtocolType.Nms); if (datagram.Data.Count < NmsHeaderLength) { throw new InvalidNibusDatagram("Invalid NMS message length"); } Contract.Ensures(Contract.Result <NmsMessage>() != null); var serviceType = (NmsServiceType)(datagram.Data[0] >> 3); switch (serviceType) { case NmsServiceType.Read: return(new NmsRead(datagram)); case NmsServiceType.Write: return(new NmsWrite(datagram)); case NmsServiceType.InformationReport: return(new NmsInformationReport(datagram)); case NmsServiceType.AckEventNotification: return(new NmsAckEventNotification(datagram)); case NmsServiceType.AlterEventConditionMonitoring: return(new NmsAlterEventConditionMonitoring(datagram)); case NmsServiceType.RequestDomainUpload: return(new NmsRequestDomainUpload(datagram)); case NmsServiceType.InitiateUploadSequence: return(new NmsInitiateUploadSequence(datagram)); case NmsServiceType.UploadSegment: return(new NmsUploadSegment(datagram)); case NmsServiceType.RequestDomainDownload: return(new NmsRequestDomainDownload(datagram)); case NmsServiceType.InitiateDownloadSequence: return(new NmsInitiateDownloadSequence(datagram)); case NmsServiceType.DownloadSegment: return(new NmsDownloadSegment(datagram)); case NmsServiceType.VerifyDomainChecksum: return(new NmsVerifyDomainChecksum(datagram)); case NmsServiceType.ExecuteProgramInvocation: return(new NmsExecuteProgramInvocation(datagram)); case NmsServiceType.StartProgramInvocation: return(new NmsStartProgramInvocation(datagram)); case NmsServiceType.Stop: return(new NmsStop(datagram)); case NmsServiceType.Resume: return(new NmsResume(datagram)); case NmsServiceType.Reset: return(new NmsReset(datagram)); case NmsServiceType.Shutdown: return(new NmsShutdown(datagram)); default: throw new InvalidNibusDatagram("Unknown NMS service"); } }