static void EncodeSubAckMessage(IByteBufferAllocator bufferAllocator, SubAckPacket message, List <object> output) { int payloadBufferSize = message.ReturnCodes.Count; int variablePartSize = PacketIdLength + payloadBufferSize; int fixedHeaderBufferSize = 1 + MaxVariableLength; IByteBuffer buf = null; try { buf = bufferAllocator.Buffer(fixedHeaderBufferSize + variablePartSize); buf.WriteByte(CalculateFirstByteOfFixedHeader(message)); WriteVariableLengthInt(buf, variablePartSize); buf.WriteShort(message.PacketId); foreach (QualityOfService qos in message.ReturnCodes) { buf.WriteByte((byte)qos); } output.Add(buf); buf = null; } finally { buf?.SafeRelease(); } }
public static SubAckPacket AddSubscriptions(ISessionState session, SubscribePacket packet, QualityOfService maxSupportedQos) { List <Subscription> subscriptions = session.Subscriptions; var returnCodes = new List <QualityOfService>(subscriptions.Count); foreach (SubscriptionRequest request in packet.Requests) { Subscription existingSubscription = null; for (int i = subscriptions.Count - 1; i >= 0; i--) { Subscription subscription = subscriptions[i]; if (subscription.TopicFilter.Equals(request.TopicFilter, StringComparison.Ordinal)) { subscriptions.RemoveAt(i); existingSubscription = subscription; break; } } QualityOfService finalQos = request.QualityOfService < maxSupportedQos ? request.QualityOfService : maxSupportedQos; subscriptions.Add(existingSubscription == null ? new Subscription(request.TopicFilter, request.QualityOfService) : existingSubscription.CreateUpdated(finalQos)); returnCodes.Add(finalQos); } var ack = new SubAckPacket { PacketId = packet.PacketId, ReturnCodes = returnCodes }; return(ack); }
bool TryDecodePacket(IChannelHandlerContext context, IByteBuffer buffer, out Packet packet) { if (!buffer.IsReadable(2)) { packet = null; return(false); } byte signature = buffer.ReadByte(); if (!TryDecodeRemainingLength(buffer, out int remainingLength) || !buffer.IsReadable(remainingLength)) { packet = null; return(false); } var fixedHeader = new FixedHeader(signature, remainingLength); switch (fixedHeader.PacketType) { case PacketType.CONNECT: packet = new ConnectPacket(); break; case PacketType.CONNACK: packet = new ConnAckPacket(); break; case PacketType.DISCONNECT: packet = new DisconnectPacket(); break; case PacketType.PINGREQ: packet = new PingReqPacket(); break; case PacketType.PINGRESP: packet = new PingRespPacket(); break; case PacketType.PUBACK: packet = new PubAckPacket(); break; case PacketType.PUBCOMP: packet = new PubCompPacket(); break; case PacketType.PUBLISH: packet = new PublishPacket(); break; case PacketType.PUBREC: packet = new PubRecPacket(); break; case PacketType.PUBREL: packet = new PubRelPacket(); break; case PacketType.SUBSCRIBE: packet = new SubscribePacket(); break; case PacketType.SUBACK: packet = new SubAckPacket(); break; case PacketType.UNSUBSCRIBE: packet = new UnsubscribePacket(); break; case PacketType.UNSUBACK: packet = new UnsubscribePacket(); break; default: throw new DecoderException("Unsupported Message Type"); } packet.FixedHeader = fixedHeader; packet.Decode(buffer); return(true); }
public async Task Subscribe(IChannelHandlerContext context, SubscribePacket packet) { if (packet != null) { var topics = packet.Requests.Select(p => p.TopicFilter).ToArray(); await _channelService.Suscribe(await _channelService.GetDeviceId(context.Channel), topics); await SubAck(context, SubAckPacket.InResponseTo(packet, QualityOfService.ExactlyOnce )); } }
static async Task RunMqttServerScenarioAsync(IChannel channel, ReadListeningHandler readListener) { var connectPacket = await readListener.ReceiveAsync(DefaultTimeout) as ConnectPacket; Assert.IsNotNull(connectPacket, "Must be a Connect pkt"); // todo verify await channel.WriteAndFlushAsync(new ConnAckPacket { ReturnCode = ConnectReturnCode.Accepted, SessionPresent = true }); var subscribePacket = await readListener.ReceiveAsync(DefaultTimeout) as SubscribePacket; Assert.IsNotNull(subscribePacket); // todo verify await channel.WriteAndFlushAsync(SubAckPacket.InResponseTo(subscribePacket, QualityOfService.ExactlyOnce)); var unsubscribePacket = await readListener.ReceiveAsync(DefaultTimeout) as UnsubscribePacket; Assert.IsNotNull(unsubscribePacket); // todo verify await channel.WriteAndFlushAsync(UnsubAckPacket.InResponseTo(unsubscribePacket)); var publishQos0Packet = await readListener.ReceiveAsync(DefaultTimeout) as PublishPacket; Assert.IsNotNull(publishQos0Packet); // todo verify var publishQos1Packet = await readListener.ReceiveAsync(DefaultTimeout) as PublishPacket; Assert.IsNotNull(publishQos1Packet); // todo verify int publishQos1PacketId = GetRandomPacketId(); await channel.WriteAndFlushManyAsync( PubAckPacket.InResponseTo(publishQos1Packet), new PublishPacket(QualityOfService.AtLeastOnce, false, false) { PacketId = publishQos1PacketId, TopicName = PublishS2CQos1Topic, Payload = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes(PublishS2CQos1Payload)) }); var pubAckPacket = await readListener.ReceiveAsync(DefaultTimeout) as PubAckPacket; Assert.AreEqual(publishQos1PacketId, pubAckPacket.PacketId); var disconnectPacket = await readListener.ReceiveAsync(DefaultTimeout) as DisconnectPacket; Assert.IsNotNull(disconnectPacket); }
void ProcessSubAck(SubAckPacket packet) { Contract.Assert(packet != null); TaskCompletionSource task; if (this.subscribeCompletions.TryRemove(packet.PacketId, out task)) { task.TryComplete(); } }
IEnumerable <TestScenarioStep> GetMqttServerScenario(Func <object> currentMessageFunc) { yield return(TestScenarioStep.MoreFeedbackExpected()); var connectPacket = Assert.IsType <ConnectPacket>(currentMessageFunc()); // todo verify yield return(TestScenarioStep.Message(new ConnAckPacket { ReturnCode = ConnectReturnCode.Accepted, SessionPresent = true })); var subscribePacket = Assert.IsType <SubscribePacket>(currentMessageFunc()); // todo verify yield return(TestScenarioStep.Message(SubAckPacket.InResponseTo(subscribePacket, QualityOfService.ExactlyOnce))); var unsubscribePacket = Assert.IsType <UnsubscribePacket>(currentMessageFunc()); // todo verify yield return(TestScenarioStep.Message(UnsubAckPacket.InResponseTo(unsubscribePacket))); var publishQos0Packet = Assert.IsType <PublishPacket>(currentMessageFunc()); // todo verify yield return(TestScenarioStep.MoreFeedbackExpected()); var publishQos1Packet = Assert.IsType <PublishPacket>(currentMessageFunc()); // todo verify int publishQos1PacketId = GetRandomPacketId(); yield return(TestScenarioStep.Messages(PubAckPacket.InResponseTo(publishQos1Packet), new PublishPacket(QualityOfService.AtLeastOnce, false, false) { PacketId = publishQos1PacketId, TopicName = PublishS2CQos1Topic, Payload = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes(PublishS2CQos1Payload)) })); var pubAckPacket = Assert.IsType <PubAckPacket>(currentMessageFunc()); Assert.Equal(publishQos1PacketId, pubAckPacket.PacketId); yield return(TestScenarioStep.MoreFeedbackExpected()); var disconnectPacket = Assert.IsType <DisconnectPacket>(currentMessageFunc()); }
static void EncodeSubAckMessage(DataWriter writer, SubAckPacket message) { int payloadBufferSize = message.ReturnCodes.Count; int variablePartSize = PACKET_ID_LENGTH + payloadBufferSize; writer.WriteByte(CalculateFirstByteOfFixedHeader(message)); WriteVariableLengthInt(writer, variablePartSize); writer.WriteInt16((short)message.PacketId); foreach (QualityOfService qos in message.ReturnCodes) { writer.WriteByte((byte)qos); } }
public void TestSubAckMessage(int packetId, QualityOfService[] qosValues) { var packet = new SubAckPacket(); packet.PacketId = packetId; packet.ReturnCodes = qosValues; SubAckPacket recoded = this.RecodePacket(packet, false, true); this.contextMock.Verify(x => x.FireChannelRead(It.IsAny <SubAckPacket>()), Times.Once); Assert.Equal(packet.ReturnCodes, recoded.ReturnCodes); Assert.Equal(packet.PacketId, recoded.PacketId); }
private async Task ProcessSubAckAsync(IChannelHandlerContext context, SubAckPacket packet) { if (packet.PacketId == GetCurrentPacketId()) { try { ChangeState(State.WaitForSuback, State.WaitForPubAck); await PublishRegisterAsync(context).ConfigureAwait(false); } catch (Exception ex) { await FailWithExceptionAsync(context, ex).ConfigureAwait(false); } } }
static void DecodeSubAckPayload(IByteBuffer buffer, SubAckPacket packet, ref int remainingLength) { var returnCodes = new MqttQos[remainingLength]; for (int i = 0; i < remainingLength; i++) { var returnCode = (MqttQos)buffer.ReadByte(); if (returnCode > MqttQos.ExactlyOnce && returnCode != MqttQos.Failure) { throw new DecoderException($"[MQTT-3.9.3-2]. Invalid return code: {returnCode}"); } returnCodes[i] = returnCode; } packet.ReturnCodes = returnCodes; remainingLength = 0; }
static void DecodeSubAckPayload(IByteBuffer buffer, SubAckPacket packet, ref int remainingLength) { var returnCodes = new QualityOfService[remainingLength]; for (int i = 0; i < remainingLength; i++) { var returnCode = (QualityOfService)buffer.ReadByte(); if (returnCode > QualityOfService.ExactlyOnce && returnCode != QualityOfService.Failure) { throw new DecoderException(string.Format("[MQTT-3.9.3-2]. Invalid return code: {0}", returnCode)); } returnCodes[i] = returnCode; } packet.ReturnCodes = returnCodes; remainingLength = 0; }
static void DecodeSubAckPayload(DataReader reader, SubAckPacket packet, ref uint remainingLength) { var returnCodes = new QualityOfService[remainingLength]; for (int i = 0; i < remainingLength; i++) { var returnCode = (QualityOfService)reader.ReadByte(); if (returnCode > QualityOfService.ExactlyOnce && returnCode != QualityOfService.Failure) { throw new DecoderException($"[MQTT-3.9.3-2]. Invalid return code: {returnCode}"); } returnCodes[i] = returnCode; } packet.ReturnCodes = returnCodes; remainingLength = 0; }
static void DecodeSubAckPayload(IByteBuffer buffer, SubAckPacket packet, ref int remainingLength) { var returnCodes = new QualityOfService[remainingLength]; for (int i = 0; i < remainingLength; i++) { var returnCode = (QualityOfService)buffer.ReadByte(); if (returnCode > QualityOfService.ExactlyOnce && returnCode != QualityOfService.Failure) { ThrowHelper.ThrowDecoderException_MQTT_393_2(returnCode); } returnCodes[i] = returnCode; } packet.ReturnCodes = returnCodes; remainingLength = 0; }
private async Task ProcessSubAckAsync(IChannelHandlerContext context, SubAckPacket packet) { if (packet.PacketId == GetCurrentPacketId()) { try { ChangeState(State.WaitForSuback, State.WaitForPubAck); await PublishRegisterAsync(context); } catch (Exception ex) { if (ex is AggregateException) { ex = ex.InnerException; } await FailWithExceptionAsync(context, ex); } } }
Packet DecodePacketInternal(IByteBuffer buffer, byte packetSignature, ref int remainingLength) { Packet packet; var fixedHeader = new FixedHeader(packetSignature, remainingLength); switch (fixedHeader.PacketType) { case PacketType.CONNECT: packet = new ConnectPacket(); break; case PacketType.CONNACK: packet = new ConnAckPacket(); break; case PacketType.DISCONNECT: packet = new DisconnectPacket(); break; case PacketType.PINGREQ: packet = new PingReqPacket(); break; case PacketType.PINGRESP: packet = new PingRespPacket(); break; case PacketType.PUBACK: packet = new PubAckPacket(); break; case PacketType.PUBCOMP: packet = new PubCompPacket(); break; case PacketType.PUBLISH: packet = new PublishPacket(); break; case PacketType.PUBREC: packet = new PubRecPacket(); break; case PacketType.PUBREL: packet = new PubRelPacket(); break; case PacketType.SUBSCRIBE: packet = new SubscribePacket(); break; case PacketType.SUBACK: packet = new SubAckPacket(); break; case PacketType.UNSUBSCRIBE: packet = new UnsubscribePacket(); break; case PacketType.UNSUBACK: packet = new UnsubscribePacket(); break; default: throw new DecoderException("Unsupported Message Type"); } packet.FixedHeader = fixedHeader; packet.Decode(buffer); remainingLength = packet.RemaingLength; return(packet); }
public void OnSubAck(IChannelHandlerContext context, SubAckPacket packet) { pendingSubscribes.TryRemove(packet.PacketId, out PendingSubscribe value); if (value == null) { return; } value.OnSubActReceived(); foreach (var callback in value.Callbacks) { var subscription = new Subscription(value.Topic, callback); topicSubscriptions.Put(value.Topic, subscription); callbackSubscriptions.Put(callback, subscription); } pendingSubscribeTopics.Remove(value.Topic); subscribedTopics.Add(value.Topic); value.Promise.TrySetResult(null); }
/// <summary> /// Subscribes the specified context. /// </summary> /// <param name="context">The context.</param> /// <param name="packet">The packet.</param> public async Task Subscribe(IChannelHandlerContext context, SubscribePacket packet) { if (packet != null) { var deviceId = await _channelService.GetDeviceId(context.Channel); var topics = packet.Requests.Select(p => p.TopicFilter).ToArray(); var message = TransportMessage.CreateInvokeMessage(new RemoteInvokeMessage { ServiceId = "Subscribe", Parameters = new Dictionary <string, object> { { "packet", packet } } }); WirteDiagnosticBefore(message, context.Channel.RemoteAddress.ToString(), deviceId, packet.PacketType); await _channelService.Suscribe(deviceId, topics); await SubAck(context, SubAckPacket.InResponseTo(packet, QualityOfService.ExactlyOnce)); WirteDiagnosticAfter(message); } }
public static SubAckPacket AddSubscriptions(ISessionState session, SubscribePacket packet, QualityOfService maxSupportedQos) { IReadOnlyList <ISubscription> subscriptions = session.Subscriptions; var returnCodes = new List <QualityOfService>(subscriptions.Count); foreach (SubscriptionRequest request in packet.Requests) { QualityOfService finalQos = request.QualityOfService < maxSupportedQos ? request.QualityOfService : maxSupportedQos; session.AddOrUpdateSubscription(request.TopicFilter, finalQos); returnCodes.Add(finalQos); } var ack = new SubAckPacket { PacketId = packet.PacketId, ReturnCodes = returnCodes }; return(ack); }
void ProcessSubAck(IChannelHandlerContext context, SubAckPacket packet) { if (Logging.IsEnabled) { Logging.Enter(this, context.Name, packet, nameof(ProcessSubAck)); } Contract.Assert(packet != null); TaskCompletionSource task; if (this.subscribeCompletions.TryRemove(packet.PacketId, out task)) { task.TryComplete(); } if (Logging.IsEnabled) { Logging.Exit(this, context.Name, packet, nameof(ProcessSubAck)); } }
private void ProcessMessage(SubAckPacket message) { }
public async Task SubAck(IChannelHandlerContext context, SubAckPacket packet) { await context.WriteAndFlushAsync(packet); }
public abstract void SubAck(IChannelHandlerContext context, SubAckPacket packet);
public static Packet DecodePacket(DataReader reader) { reader.ByteOrder = ByteOrder.BigEndian; int signature = reader.ReadByte(); int remainingLength = DecodeRemainingLength(reader); if (Signatures.IsPublish(signature)) { var qualityOfService = (QualityOfService)((signature >> 1) & 0x3); // take bits #1 and #2 ONLY and convert them into QoS value if (qualityOfService == QualityOfService.Reserved) { throw new Exception( $"Unexpected QoS value of {(int)qualityOfService} for {PacketType.PUBLISH} packet."); } bool duplicate = (signature & 0x8) == 0x8; // test bit#3 bool retain = (signature & 0x1) != 0; // test bit#0 var packet = new PublishPacket(qualityOfService, duplicate, retain); DecodePublishPacket(reader, packet, ref remainingLength); return(packet); } switch (signature & 240) // We don't care about flags for these packets { // case Signatures.Subscribe & 240: // var subscribePacket = new SubscribePacket(); // DecodePacketIdVariableHeader(reader, subscribePacket, ref remainingLength); // DecodeSubscribePayload(buffer, subscribePacket, ref remainingLength); // return subscribePacket; case Signatures.Connect: var connectPacket = new ConnectPacket(); DecodeConnectPacket(reader, connectPacket, ref remainingLength); return(connectPacket); case Signatures.PubAck: var pubAckPacket = new PubAckPacket(); DecodePacketIdVariableHeader(reader, pubAckPacket, ref remainingLength); return(pubAckPacket); case Signatures.ConnAck: var connAckPacket = new FbnsConnAckPacket(); DecodeConnAckPacket(reader, connAckPacket, ref remainingLength); return(connAckPacket); case Signatures.SubAck: var subAckPacket = new SubAckPacket(); DecodePacketIdVariableHeader(reader, subAckPacket, ref remainingLength); DecodeSubAckPayload(reader, subAckPacket, ref remainingLength); return(subAckPacket); case Signatures.UnsubAck: var unsubAckPacket = new UnsubAckPacket(); DecodePacketIdVariableHeader(reader, unsubAckPacket, ref remainingLength); return(unsubAckPacket); case Signatures.PingResp: return(PingRespPacket.Instance); default: throw new Exception($"Packet type {signature} not supported"); } }
private static Packet DecodePacketInternal(DataReader reader, int packetSignature, ref uint remainingLength) { if (Signatures.IsPublish(packetSignature)) { var qualityOfService = (QualityOfService)((packetSignature >> 1) & 0x3); // take bits #1 and #2 ONLY and convert them into QoS value if (qualityOfService == QualityOfService.Reserved) { throw new DecoderException( $"Unexpected QoS value of {(int)qualityOfService} for {PacketType.PUBLISH} packet."); } bool duplicate = (packetSignature & 0x8) == 0x8; // test bit#3 bool retain = (packetSignature & 0x1) != 0; // test bit#0 var packet = new PublishPacket(qualityOfService, duplicate, retain); DecodePublishPacket(reader, packet, ref remainingLength); return(packet); } switch (packetSignature & 240) // We don't care about flags for these packets { case Signatures.Subscribe& 240: var subscribePacket = new SubscribePacket(); DecodePacketIdVariableHeader(reader, subscribePacket, ref remainingLength); DecodeSubscribePayload(reader, subscribePacket, ref remainingLength); return(subscribePacket); case Signatures.Connect: var connectPacket = new FbnsConnectPacket(); DecodeConnectPacket(reader, connectPacket, ref remainingLength); return(connectPacket); case Signatures.ConnAck: var connAckPacket = new FbnsConnAckPacket(); DecodeConnAckPacket(reader, connAckPacket, ref remainingLength); return(connAckPacket); case Signatures.SubAck: var subAckPacket = new SubAckPacket(); DecodePacketIdVariableHeader(reader, subAckPacket, ref remainingLength); DecodeSubAckPayload(reader, subAckPacket, ref remainingLength); return(subAckPacket); case Signatures.Unsubscribe& 240: var unsubscribePacket = new UnsubscribePacket(); DecodePacketIdVariableHeader(reader, unsubscribePacket, ref remainingLength); DecodeUnsubscribePayload(reader, unsubscribePacket, ref remainingLength); return(unsubscribePacket); case Signatures.PingResp: return(PingRespPacket.Instance); case Signatures.PubAck: var pubAckPacket = new PubAckPacket(); DecodePacketIdVariableHeader(reader, pubAckPacket, ref remainingLength); return(pubAckPacket); default: return(null); //default: // throw new DecoderException($"Packet type {packetSignature} not supported"); } }
Packet DecodePacketInternal(IByteBuffer buffer, int packetSignature, ref int remainingLength, IChannelHandlerContext context) { if (Signatures.IsPublish(packetSignature)) { var qualityOfService = (QualityOfService)((packetSignature >> 1) & 0x3); // take bits #1 and #2 ONLY and convert them into QoS value if (qualityOfService == QualityOfService.Reserved) { ThrowHelper.ThrowDecoderException_UnexpectedQoSValueForPublish(qualityOfService); } bool duplicate = (packetSignature & 0x8) == 0x8; // test bit#3 bool retain = (packetSignature & 0x1) != 0; // test bit#0 var packet = new PublishPacket(qualityOfService, duplicate, retain); DecodePublishPacket(buffer, packet, ref remainingLength); return(packet); } switch (packetSignature) // strict match checks for valid message type + correct values in flags part { case Signatures.PubAck: var pubAckPacket = new PubAckPacket(); DecodePacketIdVariableHeader(buffer, pubAckPacket, ref remainingLength); return(pubAckPacket); case Signatures.PubRec: var pubRecPacket = new PubRecPacket(); DecodePacketIdVariableHeader(buffer, pubRecPacket, ref remainingLength); return(pubRecPacket); case Signatures.PubRel: var pubRelPacket = new PubRelPacket(); DecodePacketIdVariableHeader(buffer, pubRelPacket, ref remainingLength); return(pubRelPacket); case Signatures.PubComp: var pubCompPacket = new PubCompPacket(); DecodePacketIdVariableHeader(buffer, pubCompPacket, ref remainingLength); return(pubCompPacket); case Signatures.PingReq: if (!_isServer) { ValidateServerPacketExpected(packetSignature); } return(PingReqPacket.Instance); case Signatures.Subscribe: if (!_isServer) { ValidateServerPacketExpected(packetSignature); } var subscribePacket = new SubscribePacket(); DecodePacketIdVariableHeader(buffer, subscribePacket, ref remainingLength); DecodeSubscribePayload(buffer, subscribePacket, ref remainingLength); return(subscribePacket); case Signatures.Unsubscribe: if (!_isServer) { ValidateServerPacketExpected(packetSignature); } var unsubscribePacket = new UnsubscribePacket(); DecodePacketIdVariableHeader(buffer, unsubscribePacket, ref remainingLength); DecodeUnsubscribePayload(buffer, unsubscribePacket, ref remainingLength); return(unsubscribePacket); case Signatures.Connect: if (!_isServer) { ValidateServerPacketExpected(packetSignature); } var connectPacket = new ConnectPacket(); DecodeConnectPacket(buffer, connectPacket, ref remainingLength, context); return(connectPacket); case Signatures.Disconnect: if (!_isServer) { ValidateServerPacketExpected(packetSignature); } return(DisconnectPacket.Instance); case Signatures.ConnAck: if (_isServer) { ValidateClientPacketExpected(packetSignature); } var connAckPacket = new ConnAckPacket(); DecodeConnAckPacket(buffer, connAckPacket, ref remainingLength); return(connAckPacket); case Signatures.SubAck: if (_isServer) { ValidateClientPacketExpected(packetSignature); } var subAckPacket = new SubAckPacket(); DecodePacketIdVariableHeader(buffer, subAckPacket, ref remainingLength); DecodeSubAckPayload(buffer, subAckPacket, ref remainingLength); return(subAckPacket); case Signatures.UnsubAck: if (_isServer) { ValidateClientPacketExpected(packetSignature); } var unsubAckPacket = new UnsubAckPacket(); DecodePacketIdVariableHeader(buffer, unsubAckPacket, ref remainingLength); return(unsubAckPacket); case Signatures.PingResp: if (_isServer) { ValidateClientPacketExpected(packetSignature); } return(PingRespPacket.Instance); default: return(ThrowHelper.FromDecoderException_FirstPacketByteValueIsInvalid(packetSignature)); } }
private void HandleSubAck(SubAckPacket message) { }
Packet DecodePacketInternal(IByteBuffer buffer, int packetSignature, ref int remainingLength, IChannelHandlerContext context) { if (Signatures.IsPublish(packetSignature)) { var qualityOfService = (QualityOfService)((packetSignature >> 1) & 0x3); // take bits #1 and #2 ONLY and convert them into QoS value if (qualityOfService == QualityOfService.Reserved) { throw new DecoderException($"Unexpected QoS value of {(int)qualityOfService} for {PacketType.PUBLISH} packet."); } bool duplicate = (packetSignature & 0x8) == 0x8; // test bit#3 bool retain = (packetSignature & 0x1) != 0; // test bit#0 var packet = new PublishPacket(qualityOfService, duplicate, retain); DecodePublishPacket(buffer, packet, ref remainingLength); return(packet); } switch (packetSignature) // strict match checks for valid message type + correct values in flags part { case Signatures.PubAck: var pubAckPacket = new PubAckPacket(); DecodePacketIdVariableHeader(buffer, pubAckPacket, ref remainingLength); return(pubAckPacket); case Signatures.PubRec: var pubRecPacket = new PubRecPacket(); DecodePacketIdVariableHeader(buffer, pubRecPacket, ref remainingLength); return(pubRecPacket); case Signatures.PubRel: var pubRelPacket = new PubRelPacket(); DecodePacketIdVariableHeader(buffer, pubRelPacket, ref remainingLength); return(pubRelPacket); case Signatures.PubComp: var pubCompPacket = new PubCompPacket(); DecodePacketIdVariableHeader(buffer, pubCompPacket, ref remainingLength); return(pubCompPacket); case Signatures.PingReq: this.ValidateServerPacketExpected(packetSignature); return(PingReqPacket.Instance); case Signatures.Subscribe: this.ValidateServerPacketExpected(packetSignature); var subscribePacket = new SubscribePacket(); DecodePacketIdVariableHeader(buffer, subscribePacket, ref remainingLength); DecodeSubscribePayload(buffer, subscribePacket, ref remainingLength); return(subscribePacket); case Signatures.Unsubscribe: this.ValidateServerPacketExpected(packetSignature); var unsubscribePacket = new UnsubscribePacket(); DecodePacketIdVariableHeader(buffer, unsubscribePacket, ref remainingLength); DecodeUnsubscribePayload(buffer, unsubscribePacket, ref remainingLength); return(unsubscribePacket); case Signatures.Connect: this.ValidateServerPacketExpected(packetSignature); var connectPacket = new ConnectPacket(); DecodeConnectPacket(buffer, connectPacket, ref remainingLength, context); return(connectPacket); case Signatures.Disconnect: this.ValidateServerPacketExpected(packetSignature); return(DisconnectPacket.Instance); case Signatures.ConnAck: this.ValidateClientPacketExpected(packetSignature); var connAckPacket = new ConnAckPacket(); DecodeConnAckPacket(buffer, connAckPacket, ref remainingLength); return(connAckPacket); case Signatures.SubAck: this.ValidateClientPacketExpected(packetSignature); var subAckPacket = new SubAckPacket(); DecodePacketIdVariableHeader(buffer, subAckPacket, ref remainingLength); DecodeSubAckPayload(buffer, subAckPacket, ref remainingLength); return(subAckPacket); case Signatures.UnsubAck: this.ValidateClientPacketExpected(packetSignature); var unsubAckPacket = new UnsubAckPacket(); DecodePacketIdVariableHeader(buffer, unsubAckPacket, ref remainingLength); return(unsubAckPacket); case Signatures.PingResp: this.ValidateClientPacketExpected(packetSignature); return(PingRespPacket.Instance); default: throw new DecoderException($"First packet byte value of `{packetSignature}` is invalid."); } }