IEnumerable <TestScenarioStep> GetPart2SpecificSteps(Func <object> currentMessageFunc) { yield return(TestScenarioStep.ReadMore()); var packets = new Packet[2]; for (int i = packets.Length - 1; i >= 0; i--) { packets[i] = Assert.IsAssignableFrom <Packet>(currentMessageFunc()); if (i > 0) { yield return(TestScenarioStep.ReadMore()); } } PublishPacket qos1Packet = Assert.Single(packets.OfType <PublishPacket>()); Assert.Equal(QualityOfService.AtLeastOnce, qos1Packet.QualityOfService); this.AssertPacketCoreValue(qos1Packet, Encoding.ASCII.GetString(qos1Packet.Payload.ToArray())); PubRelPacket pubRelQos2Packet = Assert.Single(packets.OfType <PubRelPacket>()); yield return(TestScenarioStep.Write( false, PubAckPacket.InResponseTo(qos1Packet), PubCompPacket.InResponseTo(pubRelQos2Packet), DisconnectPacket.Instance)); }
public async Task PubComp(IChannelHandlerContext context, PubCompPacket packet) { int messageId = packet.PacketId; var mqttChannel = _channelService.GetMqttChannel(await _channelService.GetDeviceId(context.Channel)); var message = mqttChannel.GetMqttMessage(messageId); message.ConfirmStatus = ConfirmStatus.COMPLETE; }
/// <summary> /// Sends to pub comp. /// </summary> /// <param name="channel">The channel.</param> /// <param name="messageId">The message identifier.</param> public async Task SendToPubComp(IChannel channel, int messageId) { var mqttPubAckMessage = new PubCompPacket { PacketId = messageId }; await channel.WriteAndFlushAsync(mqttPubAckMessage); }
async Task GetPart1SpecificSteps(IChannel channel, ReadListeningHandler readHandler) { int publishQoS1PacketId = GetRandomPacketId(); await channel.WriteAndFlushManyAsync( new PublishPacket(QualityOfService.AtMostOnce, false, false) { //TopicName = string.Format("devices/{0}/messages/log/verbose/", clientId), TopicName = $"devices/{this.clientId}/messages/events", Payload = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes("{\"test\": \"telemetry-QoS0\"}")) }, new PublishPacket(QualityOfService.AtLeastOnce, false, false) { PacketId = publishQoS1PacketId, TopicName = $"devices/{this.clientId}/messages/events", Payload = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes("{\"test\": \"telemetry\"}")) }); var packets = new Packet[5]; for (int i = packets.Length - 1; i >= 0; i--) { packets[i] = Assert.IsAssignableFrom<Packet>(await readHandler.ReceiveAsync()); } PubAckPacket pubAckPacket = Assert.Single(packets.OfType<PubAckPacket>()); Assert.Equal(publishQoS1PacketId, pubAckPacket.PacketId); PublishPacket publishQoS0Packet = Assert.Single(packets.OfType<PublishPacket>().Where(x => x.QualityOfService == QualityOfService.AtMostOnce)); this.AssertPacketCoreValue(publishQoS0Packet, NotificationQoS0Content); PublishPacket publishQoS1Packet = Assert.Single(packets.OfType<PublishPacket>().Where(x => x.QualityOfService == QualityOfService.AtLeastOnce)); this.AssertPacketCoreValue(publishQoS1Packet, NotificationQoS1Content); PublishPacket[] publishQoS2Packets = packets.OfType<PublishPacket>().Where(x => x.QualityOfService == QualityOfService.ExactlyOnce).Reverse().ToArray(); Assert.Equal(2, publishQoS2Packets.Length); PublishPacket publishQoS2Packet1 = publishQoS2Packets[0]; this.AssertPacketCoreValue(publishQoS2Packet1, NotificationQoS2Content); PublishPacket publishQoS2Packet2 = publishQoS2Packets[1]; this.AssertPacketCoreValue(publishQoS2Packet2, NotificationQoS2Content2); await channel.WriteAndFlushManyAsync( PubAckPacket.InResponseTo(publishQoS1Packet), PubRecPacket.InResponseTo(publishQoS2Packet1), PubRecPacket.InResponseTo(publishQoS2Packet2)); var pubRelQoS2Packet1 = Assert.IsAssignableFrom<PubRelPacket>(await readHandler.ReceiveAsync()); Assert.Equal(publishQoS2Packet1.PacketId, pubRelQoS2Packet1.PacketId); var pubRelQoS2Packet2 = Assert.IsAssignableFrom<PubRelPacket>(await readHandler.ReceiveAsync()); Assert.Equal(publishQoS2Packet2.PacketId, pubRelQoS2Packet2.PacketId); await channel.WriteAndFlushManyAsync( PubCompPacket.InResponseTo(pubRelQoS2Packet1), DisconnectPacket.Instance); // device queue still contains QoS 2 packet 2 which was PUBRECed but not PUBCOMPed. }
public void OnPubComp(IChannelHandlerContext context, PubCompPacket packet) { if (pendingPublishes.TryGetValue(packet.PacketId, out PendingPublish pendingPublish)) { pendingPublish.Promise.SetResult(null); pendingPublishes.TryRemove(packet.PacketId, out _); pendingPublish.Packet.Release(); pendingPublish.OnPubCompReceived(); } }
public void OnPubRel(IChannelHandlerContext context, PubRelPacket packet) { if (pendingIncomingQoS2Publishes.ContainsKey(packet.PacketId)) { var qos2Publish = pendingIncomingQoS2Publishes[packet.PacketId]; publishCallback(qos2Publish.PublishPacket); qos2Publish.OnPubRelReceived(); pendingIncomingQoS2Publishes.TryRemove(packet.PacketId, out _); } context.WriteAndFlushAsync(PubCompPacket.InResponseTo(packet)); }
/// <summary> /// Pubs the comp. /// </summary> /// <param name="context">The context.</param> /// <param name="packet">The packet.</param> public async Task PubComp(IChannelHandlerContext context, PubCompPacket packet) { var messageId = packet.PacketId; var mqttChannel = _channelService.GetMqttChannel(await _channelService.GetDeviceId(context.Channel)); var message = mqttChannel.GetMqttMessage(messageId); if (message != null) { message.ConfirmStatus = ConfirmStatus.COMPLETE; } await context.WriteAndFlushAsync(packet); }
async Task ReceiveAndCompleteCommandAsync(IChannel clientChannel, ReadListeningHandler readHandler, IotHubConnectionStringBuilder hubConnectionStringBuilder, Device device) { var packet = Assert.IsType <PublishPacket>(await readHandler.ReceiveAsync()); Assert.Equal($"devices/{this.deviceId}/messages/devicebound", packet.TopicName); Assert.Equal(MethodContent, Encoding.UTF8.GetString(packet.Payload.ToArray())); await clientChannel.WriteAndFlushManyAsync(PubAckPacket.InResponseTo(packet), PubRecPacket.InResponseTo(packet)); var pubRelQoS2Packet2 = Assert.IsAssignableFrom <PubRelPacket>(await readHandler.ReceiveAsync()); await clientChannel.WriteAndFlushManyAsync( PubCompPacket.InResponseTo(pubRelQoS2Packet2), DisconnectPacket.Instance); await this.EnsureDeviceQueueLengthAsync(hubConnectionStringBuilder.HostName, device, 0); }
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); }
async Task GetPart2SpecificSteps(IChannel channel, ReadListeningHandler readHandler) { var packets = new Packet[2]; for (int i = packets.Length - 1; i >= 0; i--) { packets[i] = Assert.IsAssignableFrom<Packet>(await readHandler.ReceiveAsync()); } PublishPacket qos1Packet = Assert.Single(packets.OfType<PublishPacket>()); Assert.Equal(QualityOfService.AtLeastOnce, qos1Packet.QualityOfService); this.AssertPacketCoreValue(qos1Packet, Encoding.ASCII.GetString(qos1Packet.Payload.ToArray())); PubRelPacket pubRelQos2Packet = Assert.Single(packets.OfType<PubRelPacket>()); await channel.WriteAndFlushManyAsync( PubAckPacket.InResponseTo(qos1Packet), PubCompPacket.InResponseTo(pubRelQos2Packet), DisconnectPacket.Instance); }
IEnumerable <TestScenarioStep> GetPart1SpecificSteps(Func <object> currentMessageFunc) { int publishQoS1PacketId = GetRandomPacketId(); yield return(TestScenarioStep.Write( new PublishPacket(QualityOfService.AtMostOnce, false, false) { //TopicName = string.Format("devices/{0}/messages/log/verbose/", clientId), TopicName = $"devices/{this.clientId}/messages/events", Payload = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes("{\"test\": \"telemetry-QoS0\"}")) }, new PublishPacket(QualityOfService.AtLeastOnce, false, false) { PacketId = publishQoS1PacketId, TopicName = $"devices/{this.clientId}/messages/events", Payload = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes("{\"test\": \"telemetry\"}")) })); var packets = new Packet[5]; for (int i = packets.Length - 1; i >= 0; i--) { packets[i] = Assert.IsAssignableFrom <Packet>(currentMessageFunc()); if (i > 0) { yield return(TestScenarioStep.ReadMore()); } } PubAckPacket pubAckPacket = Assert.Single(packets.OfType <PubAckPacket>()); Assert.Equal(publishQoS1PacketId, pubAckPacket.PacketId); PublishPacket publishQoS0Packet = Assert.Single(packets.OfType <PublishPacket>().Where(x => x.QualityOfService == QualityOfService.AtMostOnce)); this.AssertPacketCoreValue(publishQoS0Packet, NotificationQoS0Content); PublishPacket publishQoS1Packet = Assert.Single(packets.OfType <PublishPacket>().Where(x => x.QualityOfService == QualityOfService.AtLeastOnce)); this.AssertPacketCoreValue(publishQoS1Packet, NotificationQoS1Content); PublishPacket[] publishQoS2Packets = packets.OfType <PublishPacket>().Where(x => x.QualityOfService == QualityOfService.ExactlyOnce).Reverse().ToArray(); Assert.Equal(2, publishQoS2Packets.Length); PublishPacket publishQoS2Packet1 = publishQoS2Packets[0]; this.AssertPacketCoreValue(publishQoS2Packet1, NotificationQoS2Content); PublishPacket publishQoS2Packet2 = publishQoS2Packets[1]; this.AssertPacketCoreValue(publishQoS2Packet2, NotificationQoS2Content2); yield return(TestScenarioStep.Write( PubAckPacket.InResponseTo(publishQoS1Packet), PubRecPacket.InResponseTo(publishQoS2Packet1), PubRecPacket.InResponseTo(publishQoS2Packet2))); var pubRelQoS2Packet1 = Assert.IsAssignableFrom <PubRelPacket>(currentMessageFunc()); Assert.Equal(publishQoS2Packet1.PacketId, pubRelQoS2Packet1.PacketId); yield return(TestScenarioStep.ReadMore()); var pubRelQoS2Packet2 = Assert.IsAssignableFrom <PubRelPacket>(currentMessageFunc()); Assert.Equal(publishQoS2Packet2.PacketId, pubRelQoS2Packet2.PacketId); yield return(TestScenarioStep.Write( false, // it is a final step and we do not expect response PubCompPacket.InResponseTo(pubRelQoS2Packet1), DisconnectPacket.Instance)); // device queue still contains QoS 2 packet 2 which was PUBRECed but not PUBCOMPed. }
static IEnumerable <TestScenarioStep> GetClientScenario(Func <object> currentMessageFunc, string iotHubName, string clientId, string password) { yield return(TestScenarioStep.Write(new ConnectPacket { ClientId = clientId, HasUsername = true, Username = iotHubName + "/" + clientId, HasPassword = true, Password = password, KeepAliveInSeconds = 120, HasWill = true, WillTopicName = "last/word", WillMessage = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes("oops")) })); var connAckPacket = Assert.IsType <ConnAckPacket>(currentMessageFunc()); Assert.Equal(ConnectReturnCode.Accepted, connAckPacket.ReturnCode); int subscribePacketId = GetRandomPacketId(); yield return(TestScenarioStep.Write(new SubscribePacket { PacketId = subscribePacketId, Requests = new[] { new SubscriptionRequest(string.Format("devices/{0}/messages/devicebound/#", clientId), QualityOfService.ExactlyOnce) } })); var subAckPacket = Assert.IsType <SubAckPacket>(currentMessageFunc()); Assert.Equal(subscribePacketId, subAckPacket.PacketId); Assert.Equal(1, subAckPacket.ReturnCodes.Count); Assert.Equal(QualityOfService.ExactlyOnce, subAckPacket.ReturnCodes[0]); int publishQoS1PacketId = GetRandomPacketId(); yield return(TestScenarioStep.Write( new PublishPacket(QualityOfService.AtMostOnce, false, false) { //TopicName = string.Format("devices/{0}/messages/log/verbose/", clientId), TopicName = string.Format("devices/{0}/messages/events", clientId), Payload = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes("{\"test\": \"telemetry-QoS0\"}")) }, new PublishPacket(QualityOfService.AtLeastOnce, false, false) { PacketId = publishQoS1PacketId, TopicName = string.Format("devices/{0}/messages/events", clientId), Payload = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes("{\"test\": \"telemetry\"}")) })); var packets = new Packet[4]; for (int i = packets.Length - 1; i >= 0; i--) { packets[i] = Assert.IsAssignableFrom <Packet>(currentMessageFunc()); if (i > 0) { yield return(TestScenarioStep.ReadMore()); } } PubAckPacket pubAckPacket = Assert.Single(packets.OfType <PubAckPacket>()); Assert.Equal(publishQoS1PacketId, pubAckPacket.PacketId); PublishPacket publishQoS0Packet = Assert.Single(packets.OfType <PublishPacket>().Where(x => x.QualityOfService == QualityOfService.AtMostOnce)); //Assert.Equal(string.Format("devices/{0}/messages/devicebound/tips", clientId), publishQoS0Packet.TopicName); Assert.Equal(string.Format("devices/{0}/messages/devicebound", clientId), publishQoS0Packet.TopicName); Assert.Equal(NotificationQoS0Content, Encoding.UTF8.GetString(publishQoS0Packet.Payload.ToArray())); PublishPacket publishQoS1Packet = Assert.Single(packets.OfType <PublishPacket>().Where(x => x.QualityOfService == QualityOfService.AtLeastOnce)); //Assert.Equal(string.Format("devices/{0}/messages/devicebound/firmware-update", clientId), publishQoS1Packet.TopicName); Assert.Equal(string.Format("devices/{0}/messages/devicebound", clientId), publishQoS1Packet.TopicName); Assert.Equal(NotificationQoS1Content, Encoding.UTF8.GetString(publishQoS1Packet.Payload.ToArray())); PublishPacket publishQoS2Packet = Assert.Single(packets.OfType <PublishPacket>().Where(x => x.QualityOfService == QualityOfService.ExactlyOnce)); //Assert.Equal(string.Format("devices/{0}/messages/devicebound/critical-alert", clientId), publishQoS2Packet.TopicName); Assert.Equal(string.Format("devices/{0}/messages/devicebound", clientId), publishQoS2Packet.TopicName); Assert.Equal(NotificationQoS2Content, Encoding.UTF8.GetString(publishQoS2Packet.Payload.ToArray())); yield return(TestScenarioStep.Write( PubAckPacket.InResponseTo(publishQoS1Packet), PubRecPacket.InResponseTo(publishQoS2Packet))); var pubRelQoS2Packet = Assert.IsAssignableFrom <PubRelPacket>(currentMessageFunc()); Assert.Equal(publishQoS2Packet.PacketId, pubRelQoS2Packet.PacketId); yield return(TestScenarioStep.Write( false, // it is a final step and we do not expect response PubCompPacket.InResponseTo(pubRelQoS2Packet), DisconnectPacket.Instance)); }
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)); } }
public abstract void PubComp(IChannelHandlerContext context, PubCompPacket packet);
async Task GetPart1SpecificSteps(IChannel channel, ReadListeningHandler readHandler) { int publishQoS1PacketId = 1003; await channel.WriteAndFlushManyAsync( new PublishPacket(QualityOfService.AtMostOnce, false, false) { //TopicName = string.Format("devices/{0}/messages/log/verbose/", clientId), TopicName = $"devices/{this.clientId}/messages/events", Payload = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes("{\"test\": \"telemetry-QoS0\"}")) }, new PublishPacket(QualityOfService.AtLeastOnce, false, false) { PacketId = publishQoS1PacketId, TopicName = $"devices/{this.clientId}/messages/events", Payload = Unpooled.WrappedBuffer(Encoding.UTF8.GetBytes("{\"test\": \"telemetry\"}")) }); Packet[] packets = (await Task.WhenAll(Enumerable.Repeat(0, 6).Select(_ => readHandler.ReceiveAsync()))) .Select(Assert.IsAssignableFrom <Packet>) .ToArray(); PubAckPacket pubAckPacket = Assert.Single(packets.OfType <PubAckPacket>()); Assert.Equal(publishQoS1PacketId, pubAckPacket.PacketId); PublishPacket publishQoS0Packet = Assert.Single(packets.OfType <PublishPacket>().Where(x => x.QualityOfService == QualityOfService.AtMostOnce)); this.AssertPacketCoreValue(publishQoS0Packet, "tips", NotificationQoS0Content); PublishPacket[] publishQoS1Packets = packets.OfType <PublishPacket>().Where(x => x.QualityOfService == QualityOfService.AtLeastOnce).ToArray(); Assert.Equal(2, publishQoS1Packets.Length); var qos1Notification = Assert.Single(publishQoS1Packets, x => x.TopicName.EndsWith("firmware-update")); this.AssertPacketCoreValue(qos1Notification, "firmware-update", NotificationQoS1Content); var methodCall = Assert.Single(publishQoS1Packets, x => x.TopicName.EndsWith("commands")); this.AssertPacketCoreValue(methodCall, "commands", MethodCallContent); PublishPacket[] publishQoS2Packets = packets.OfType <PublishPacket>().Where(x => x.QualityOfService == QualityOfService.ExactlyOnce).ToArray(); Assert.Equal(2, publishQoS2Packets.Length); PublishPacket publishQoS2Packet1 = publishQoS2Packets[0]; this.AssertPacketCoreValue(publishQoS2Packet1, "critical-alert", NotificationQoS2Content); PublishPacket publishQoS2Packet2 = publishQoS2Packets[1]; this.AssertPacketCoreValue(publishQoS2Packet2, string.Empty, NotificationQoS2Content2); await channel.WriteAndFlushManyAsync( PubAckPacket.InResponseTo(qos1Notification), PubAckPacket.InResponseTo(methodCall), PubRecPacket.InResponseTo(publishQoS2Packet1), PubRecPacket.InResponseTo(publishQoS2Packet2)); var pubRelQoS2Packet1 = Assert.IsAssignableFrom <PubRelPacket>(await readHandler.ReceiveAsync()); Assert.Equal(publishQoS2Packet1.PacketId, pubRelQoS2Packet1.PacketId); var pubRelQoS2Packet2 = Assert.IsAssignableFrom <PubRelPacket>(await readHandler.ReceiveAsync()); Assert.Equal(publishQoS2Packet2.PacketId, pubRelQoS2Packet2.PacketId); await channel.WriteAndFlushManyAsync( PubCompPacket.InResponseTo(pubRelQoS2Packet1), DisconnectPacket.Instance); // device queue still contains QoS 2 packet 2 which was PUBRECed but not PUBCOMPed. }