private static byte EncodePubCompPacket(MqttPubCompPacket packet, IMqttPacketWriter packetWriter) { ThrowIfPacketIdentifierIsInvalid(packet); if (!packet.ReasonCode.HasValue) { ThrowReasonCodeNotSetException(); } packetWriter.Write(packet.PacketIdentifier.Value); var propertiesWriter = new MqttV500PropertiesWriter(); if (packet.Properties != null) { propertiesWriter.WriteReasonString(packet.Properties.ReasonString); propertiesWriter.WriteUserProperties(packet.Properties.UserProperties); } if (propertiesWriter.Length > 0 || packet.ReasonCode.Value != MqttPubCompReasonCode.Success) { packetWriter.Write((byte)packet.ReasonCode.Value); propertiesWriter.WriteTo(packetWriter); } return(MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.PubComp)); }
private Task HandleIncomingPubRelPacketAsync(IMqttChannelAdapter adapter, MqttPubRelPacket pubRelPacket, CancellationToken cancellationToken) { var response = new MqttPubCompPacket { PacketIdentifier = pubRelPacket.PacketIdentifier }; return(adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, response)); }
public void DeserializeV311_MqttPubCompPacket() { var p = new MqttPubCompPacket { PacketIdentifier = 123 }; DeserializeAndCompare(p, "cAIAew=="); }
private Task ProcessReceivedPubRelPacket(MqttPubRelPacket pubRelPacket) { var response = new MqttPubCompPacket { PacketIdentifier = pubRelPacket.PacketIdentifier }; return(SendAsync(response)); }
private Task ProcessReceivedPubRelPacket(MqttPubRelPacket pubRelPacket, CancellationToken cancellationToken) { var response = new MqttPubCompPacket { PacketIdentifier = pubRelPacket.PacketIdentifier }; return(SendAsync(response, cancellationToken)); }
private Task SerializeAsync(MqttPubCompPacket packet, IMqttCommunicationChannel destination) { using (var output = new MqttPacketWriter()) { output.Write(packet.PacketIdentifier); output.InjectFixedHeader(MqttControlPacketType.PubComp); return(output.WriteToAsync(destination)); } }
Task HandleIncomingPubRelPacketAsync(MqttPubRelPacket pubRelPacket, CancellationToken cancellationToken) { var pubCompPacket = new MqttPubCompPacket { PacketIdentifier = pubRelPacket.PacketIdentifier, ReasonCode = MqttPubCompReasonCode.Success }; return(SendAsync(pubCompPacket, cancellationToken)); }
Task HandleIncomingPubCompPacket(MqttPubCompPacket pubCompPacket) { var acknowledgedPublishPacket = Session.AcknowledgePublishPacket(pubCompPacket.PacketIdentifier); if (acknowledgedPublishPacket != null) { return(ClientAcknowledgedPublishPacket(acknowledgedPublishPacket, pubCompPacket)); } return(PlatformAbstractionLayer.CompletedTask); }
static byte EncodePubCompPacket(MqttPubCompPacket packet, IMqttPacketWriter packetWriter) { if (!packet.PacketIdentifier.HasValue) { throw new MqttProtocolViolationException("PubComp packet has no packet identifier."); } packetWriter.Write(packet.PacketIdentifier.Value); return(MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.PubComp)); }
static byte EncodePubCompPacket(MqttPubCompPacket packet, MqttBufferWriter bufferWriter) { if (packet.PacketIdentifier == 0) { throw new MqttProtocolViolationException("PubComp packet has no packet identifier."); } bufferWriter.WriteTwoByteInteger(packet.PacketIdentifier); return(MqttBufferWriter.BuildFixedHeader(MqttControlPacketType.PubComp)); }
private static MqttBasePacket DecodePubCompPacket(IMqttPacketBodyReader body) { ThrowIfBodyIsEmpty(body); var packet = new MqttPubCompPacket { PacketIdentifier = body.ReadTwoByteInteger() }; if (body.EndOfStream) { packet.ReasonCode = MqttPubCompReasonCode.Success; return(packet); } packet.ReasonCode = (MqttPubCompReasonCode)body.ReadByte(); var propertiesReader = new MqttV500PropertiesReader(body); while (propertiesReader.MoveNext()) { if (packet.Properties == null) { packet.Properties = new MqttPubCompPacketProperties(); } if (propertiesReader.CurrentPropertyId == MqttPropertyId.ReasonString) { packet.Properties.ReasonString = propertiesReader.ReadReasonString(); } else if (propertiesReader.CurrentPropertyId == MqttPropertyId.UserProperty) { if (packet.Properties.UserProperties == null) { packet.Properties.UserProperties = new List <MqttUserProperty>(); } propertiesReader.AddUserPropertyTo(packet.Properties.UserProperties); } else { propertiesReader.ThrowInvalidPropertyIdException(typeof(MqttPubCompPacket)); } } return(packet); }
byte EncodePubCompPacket(MqttPubCompPacket packet) { ThrowIfPacketIdentifierIsInvalid(packet.PacketIdentifier, packet); _bufferWriter.WriteTwoByteInteger(packet.PacketIdentifier); _propertiesWriter.WriteReasonString(packet.ReasonString); _propertiesWriter.WriteUserProperties(packet.UserProperties); if (_propertiesWriter.Length > 0 || packet.ReasonCode != MqttPubCompReasonCode.Success) { _bufferWriter.WriteByte((byte)packet.ReasonCode); _propertiesWriter.WriteTo(_bufferWriter); _propertiesWriter.Reset(); } return(MqttBufferWriter.BuildFixedHeader(MqttControlPacketType.PubComp)); }
public MqttClientPublishResult Create(MqttPubRecPacket pubRecPacket, MqttPubCompPacket pubCompPacket) { if (pubRecPacket == null || pubCompPacket == null) { return(new MqttClientPublishResult { ReasonCode = MqttClientPublishReasonCode.UnspecifiedError }); } MqttClientPublishResult result; // The PUBCOMP is the last packet in QoS 2. So we use the results from that instead of PUBREC. if (pubCompPacket.ReasonCode == MqttPubCompReasonCode.PacketIdentifierNotFound) { result = new MqttClientPublishResult { PacketIdentifier = pubCompPacket.PacketIdentifier, ReasonCode = MqttClientPublishReasonCode.UnspecifiedError, ReasonString = pubCompPacket.ReasonString, UserProperties = pubCompPacket.UserProperties ?? EmptyUserProperties }; return(result); } result = new MqttClientPublishResult { PacketIdentifier = pubCompPacket.PacketIdentifier, ReasonCode = MqttClientPublishReasonCode.Success, ReasonString = pubCompPacket.ReasonString, UserProperties = pubCompPacket.UserProperties ?? EmptyUserProperties }; if (pubRecPacket.ReasonCode != MqttPubRecReasonCode.Success) { // Both enums share the same values. result.ReasonCode = (MqttClientPublishReasonCode)pubRecPacket.ReasonCode; } return(result); }
public void Serialize_Full_MqttPubCompPacket_V500() { var pubCompPacket = new MqttPubCompPacket { PacketIdentifier = 123, ReasonCode = MqttPubCompReasonCode.PacketIdentifierNotFound, ReasonString = "ReasonString", UserProperties = new List <MqttUserProperty> { new MqttUserProperty("Foo", "Bar") } }; var deserialized = MqttPacketSerializationHelper.EncodeAndDecodePacket(pubCompPacket, MqttProtocolVersion.V500); Assert.AreEqual(pubCompPacket.PacketIdentifier, deserialized.PacketIdentifier); Assert.AreEqual(pubCompPacket.ReasonCode, deserialized.ReasonCode); Assert.AreEqual(pubCompPacket.ReasonString, deserialized.ReasonString); CollectionAssert.AreEqual(pubCompPacket.UserProperties, deserialized.UserProperties); }
public void Serialize_Full_MqttPubCompPacket_V311() { var pubCompPacket = new MqttPubCompPacket { PacketIdentifier = 123, ReasonCode = MqttPubCompReasonCode.PacketIdentifierNotFound, ReasonString = "ReasonString", UserProperties = new List <MqttUserProperty> { new MqttUserProperty("Foo", "Bar") } }; var deserialized = MqttPacketSerializationHelper.EncodeAndDecodePacket(pubCompPacket, MqttProtocolVersion.V311); Assert.AreEqual(pubCompPacket.PacketIdentifier, deserialized.PacketIdentifier); // ReasonCode not available in MQTTv3. // ReasonString not available in MQTTv3. // UserProperties not available in MQTTv3. Assert.IsNull(deserialized.UserProperties); }
MqttPacket DecodePubCompPacket(ArraySegment <byte> body) { ThrowIfBodyIsEmpty(body); _bufferReader.SetBuffer(body.Array, body.Offset, body.Count); var packet = new MqttPubCompPacket { PacketIdentifier = _bufferReader.ReadTwoByteInteger() }; if (_bufferReader.EndOfStream) { packet.ReasonCode = MqttPubCompReasonCode.Success; return(packet); } packet.ReasonCode = (MqttPubCompReasonCode)_bufferReader.ReadByte(); var propertiesReader = new MqttV5PropertiesReader(_bufferReader); while (propertiesReader.MoveNext()) { if (propertiesReader.CurrentPropertyId == MqttPropertyId.ReasonString) { packet.ReasonString = propertiesReader.ReadReasonString(); } else { propertiesReader.ThrowInvalidPropertyIdException(typeof(MqttPubCompPacket)); } } packet.UserProperties = propertiesReader.CollectedUserProperties; return(packet); }
private void ProcessReceivedPacket(IMqttChannelAdapter adapter, MqttBasePacket packet, CancellationToken cancellationToken) { if (packet is MqttPublishPacket publishPacket) { HandleIncomingPublishPacket(adapter, publishPacket, cancellationToken); return; } if (packet is MqttPingReqPacket) { adapter.SendPacketAsync(new MqttPingRespPacket(), cancellationToken).GetAwaiter().GetResult(); return; } if (packet is MqttPubRelPacket pubRelPacket) { var responsePacket = new MqttPubCompPacket { PacketIdentifier = pubRelPacket.PacketIdentifier }; adapter.SendPacketAsync(responsePacket, cancellationToken).GetAwaiter().GetResult(); return; } if (packet is MqttPubRecPacket pubRecPacket) { var responsePacket = new MqttPubRelPacket { PacketIdentifier = pubRecPacket.PacketIdentifier }; adapter.SendPacketAsync(responsePacket, cancellationToken).GetAwaiter().GetResult(); return; } if (packet is MqttPubAckPacket || packet is MqttPubCompPacket) { return; } if (packet is MqttSubscribePacket subscribePacket) { HandleIncomingSubscribePacket(adapter, subscribePacket, cancellationToken); return; } if (packet is MqttUnsubscribePacket unsubscribePacket) { HandleIncomingUnsubscribePacket(adapter, unsubscribePacket, cancellationToken); return; } if (packet is MqttDisconnectPacket) { Stop(MqttClientDisconnectType.Clean, true); return; } if (packet is MqttConnectPacket) { Stop(MqttClientDisconnectType.NotClean, true); return; } _logger.Warning(null, "Client '{0}': Received not supported packet ({1}). Closing connection.", ClientId, packet); Stop(MqttClientDisconnectType.NotClean, true); }
async Task RunInternalAsync() { var disconnectType = MqttClientDisconnectType.NotClean; try { _logger.Info("Client '{0}': Session started.", ClientId); _channelAdapter.ReadingPacketStartedCallback = OnAdapterReadingPacketStarted; _channelAdapter.ReadingPacketCompletedCallback = OnAdapterReadingPacketCompleted; Session.WillMessage = ConnectPacket.WillMessage; Task.Run(() => SendPendingPacketsAsync(_cancellationToken.Token), _cancellationToken.Token).Forget(_logger); // TODO: Change to single thread in SessionManager. Or use SessionManager and stats from KeepAliveMonitor. _keepAliveMonitor.Start(ConnectPacket.KeepAlivePeriod, _cancellationToken.Token); await SendAsync(_channelAdapter.PacketFormatterAdapter.DataConverter.CreateConnAckPacket(_connectionValidatorContext)).ConfigureAwait(false); Session.IsCleanSession = false; while (!_cancellationToken.IsCancellationRequested) { var packet = await _channelAdapter.ReceivePacketAsync(TimeSpan.Zero, _cancellationToken.Token).ConfigureAwait(false); if (packet == null) { // The client has closed the connection gracefully. break; } Interlocked.Increment(ref _sentPacketsCount); _lastPacketReceivedTimestamp = DateTime.UtcNow; if (!(packet is MqttPingReqPacket || packet is MqttPingRespPacket)) { _lastNonKeepAlivePacketReceivedTimestamp = _lastPacketReceivedTimestamp; } _keepAliveMonitor.PacketReceived(); if (packet is MqttPublishPacket publishPacket) { await HandleIncomingPublishPacketAsync(publishPacket).ConfigureAwait(false); continue; } if (packet is MqttPubRelPacket pubRelPacket) { var pubCompPacket = new MqttPubCompPacket { PacketIdentifier = pubRelPacket.PacketIdentifier, ReasonCode = MqttPubCompReasonCode.Success }; await SendAsync(pubCompPacket).ConfigureAwait(false); continue; } if (packet is MqttSubscribePacket subscribePacket) { await HandleIncomingSubscribePacketAsync(subscribePacket).ConfigureAwait(false); continue; } if (packet is MqttUnsubscribePacket unsubscribePacket) { await HandleIncomingUnsubscribePacketAsync(unsubscribePacket).ConfigureAwait(false); continue; } if (packet is MqttPingReqPacket) { await SendAsync(new MqttPingRespPacket()).ConfigureAwait(false); continue; } if (packet is MqttDisconnectPacket) { Session.WillMessage = null; disconnectType = MqttClientDisconnectType.Clean; StopInternal(); break; } _packetDispatcher.Dispatch(packet); } } catch (OperationCanceledException) { } catch (Exception exception) { if (exception is MqttCommunicationException) { _logger.Warning(exception, "Client '{0}': Communication exception while receiving client packets.", ClientId); } else { _logger.Error(exception, "Client '{0}': Error while receiving client packets.", ClientId); } StopInternal(); } finally { if (_isTakeover) { disconnectType = MqttClientDisconnectType.Takeover; } if (Session.WillMessage != null) { _sessionsManager.DispatchApplicationMessage(Session.WillMessage, this); Session.WillMessage = null; } _packetDispatcher.Reset(); _channelAdapter.ReadingPacketStartedCallback = null; _channelAdapter.ReadingPacketCompletedCallback = null; _packageReceiverTask = null; if (_isTakeover) { try { // Don't use SendAsync here _cancellationToken is already cancelled. await _channelAdapter.SendPacketAsync(new MqttDisconnectPacket { ReasonCode = MqttDisconnectReasonCode.SessionTakenOver }, TimeSpan.Zero, CancellationToken.None).ConfigureAwait(false); } catch (Exception exception) { _logger.Error(exception, "Client '{0}': Error while sending DISCONNECT packet after takeover.", ClientId); } } _logger.Info("Client '{0}': Connection stopped.", ClientId); try { await _sessionsManager.CleanUpClient(ClientId, _channelAdapter, disconnectType); } catch (Exception e) { _logger.Error(e, "Client '{0}': Error while cleaning up", ClientId); } } }
private async Task <MqttClientDisconnectType> RunInternalAsync() { var disconnectType = MqttClientDisconnectType.NotClean; try { _logger.Info("Client '{0}': Session started.", ClientId); _channelAdapter.ReadingPacketStartedCallback = OnAdapterReadingPacketStarted; _channelAdapter.ReadingPacketCompletedCallback = OnAdapterReadingPacketCompleted; Session.WillMessage = _connectPacket.WillMessage; #pragma warning disable 4014 Task.Run(() => SendPendingPacketsAsync(_cancellationToken.Token), _cancellationToken.Token); #pragma warning restore 4014 // TODO: Change to single thread in SessionManager. Or use SessionManager and stats from KeepAliveMonitor. _keepAliveMonitor.Start(_connectPacket.KeepAlivePeriod, _cancellationToken.Token); await SendAsync( new MqttConnAckPacket { ReturnCode = MqttConnectReturnCode.ConnectionAccepted, ReasonCode = MqttConnectReasonCode.Success, IsSessionPresent = !Session.IsCleanSession }).ConfigureAwait(false); Session.IsCleanSession = false; while (!_cancellationToken.IsCancellationRequested) { var packet = await _channelAdapter.ReceivePacketAsync(TimeSpan.Zero, _cancellationToken.Token).ConfigureAwait(false); if (packet == null) { // The client has closed the connection gracefully. break; } Interlocked.Increment(ref _sentPacketsCount); _lastPacketReceivedTimestamp = DateTime.UtcNow; if (!(packet is MqttPingReqPacket || packet is MqttPingRespPacket)) { _lastNonKeepAlivePacketReceivedTimestamp = _lastPacketReceivedTimestamp; } _keepAliveMonitor.PacketReceived(); if (packet is MqttPublishPacket publishPacket) { await HandleIncomingPublishPacketAsync(publishPacket).ConfigureAwait(false); continue; } if (packet is MqttPubRelPacket pubRelPacket) { var pubCompPacket = new MqttPubCompPacket { PacketIdentifier = pubRelPacket.PacketIdentifier, ReasonCode = MqttPubCompReasonCode.Success }; await SendAsync(pubCompPacket).ConfigureAwait(false); continue; } if (packet is MqttSubscribePacket subscribePacket) { await HandleIncomingSubscribePacketAsync(subscribePacket).ConfigureAwait(false); continue; } if (packet is MqttUnsubscribePacket unsubscribePacket) { await HandleIncomingUnsubscribePacketAsync(unsubscribePacket).ConfigureAwait(false); continue; } if (packet is MqttPingReqPacket) { await SendAsync(new MqttPingRespPacket()).ConfigureAwait(false); continue; } if (packet is MqttDisconnectPacket) { Session.WillMessage = null; disconnectType = MqttClientDisconnectType.Clean; StopInternal(); break; } _packetDispatcher.Dispatch(packet); } } catch (OperationCanceledException) { } catch (Exception exception) { if (exception is MqttCommunicationException) { _logger.Warning(exception, "Client '{0}': Communication exception while receiving client packets.", ClientId); } else { _logger.Error(exception, "Client '{0}': Unhandled exception while receiving client packets.", ClientId); } StopInternal(); } finally { if (Session.WillMessage != null) { _sessionsManager.DispatchApplicationMessage(Session.WillMessage, this); Session.WillMessage = null; } _packetDispatcher.Reset(); _channelAdapter.ReadingPacketStartedCallback = null; _channelAdapter.ReadingPacketCompletedCallback = null; _logger.Info("Client '{0}': Session stopped.", ClientId); _packageReceiverTask = null; } return(disconnectType); }
public MqttClientPublishResult CreatePublishResult(MqttPubRecPacket pubRecPacket, MqttPubCompPacket pubCompPacket) { if (pubRecPacket == null || pubCompPacket == null) { return(new MqttClientPublishResult { ReasonCode = MqttClientPublishReasonCode.UnspecifiedError }); } return(new MqttClientPublishResult { PacketIdentifier = pubCompPacket.PacketIdentifier, ReasonCode = MqttClientPublishReasonCode.Success }); }
private static byte Serialize(MqttPubCompPacket packet, MqttPacketWriter writer) { writer.Write(packet.PacketIdentifier); return(MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.PubComp)); }