byte EncodeConnAckPacket(MqttConnAckPacket packet, MqttBufferWriter bufferWriter) { bufferWriter.WriteByte(0); // Reserved. bufferWriter.WriteByte((byte)packet.ReturnCode); return(MqttBufferWriter.BuildFixedHeader(MqttControlPacketType.ConnAck)); }
public static byte[] AddMqttHeader(this MqttBufferWriter writer, MqttControlPacketType header, byte[] body) { writer.WriteByte(MqttBufferWriter.BuildFixedHeader(header)); writer.WriteVariableByteInteger((uint)body.Length); writer.WriteBinary(body, 0, body.Length); return(writer.GetBuffer()); }
static byte EncodeSubAckPacket(MqttSubAckPacket packet, MqttBufferWriter bufferWriter) { if (packet.PacketIdentifier == 0) { throw new MqttProtocolViolationException("SubAck packet has no packet identifier."); } bufferWriter.WriteTwoByteInteger(packet.PacketIdentifier); if (packet.ReasonCodes.Any()) { foreach (var packetSubscribeReturnCode in packet.ReasonCodes) { if (packetSubscribeReturnCode == MqttSubscribeReasonCode.GrantedQoS0) { bufferWriter.WriteByte((byte)MqttSubscribeReturnCode.SuccessMaximumQoS0); } else if (packetSubscribeReturnCode == MqttSubscribeReasonCode.GrantedQoS1) { bufferWriter.WriteByte((byte)MqttSubscribeReturnCode.SuccessMaximumQoS1); } else if (packetSubscribeReturnCode == MqttSubscribeReasonCode.GrantedQoS2) { bufferWriter.WriteByte((byte)MqttSubscribeReturnCode.SuccessMaximumQoS2); } else { bufferWriter.WriteByte((byte)MqttSubscribeReturnCode.Failure); } } } return(MqttBufferWriter.BuildFixedHeader(MqttControlPacketType.SubAck)); }
static byte EncodeSubscribePacket(MqttSubscribePacket packet, MqttBufferWriter bufferWriter) { if (!packet.TopicFilters.Any()) { throw new MqttProtocolViolationException("At least one topic filter must be set [MQTT-3.8.3-3]."); } if (packet.PacketIdentifier == 0) { throw new MqttProtocolViolationException("Subscribe packet has no packet identifier."); } bufferWriter.WriteTwoByteInteger(packet.PacketIdentifier); if (packet.TopicFilters?.Count > 0) { foreach (var topicFilter in packet.TopicFilters) { bufferWriter.WriteString(topicFilter.Topic); bufferWriter.WriteByte((byte)topicFilter.QualityOfServiceLevel); } } return(MqttBufferWriter.BuildFixedHeader(MqttControlPacketType.Subscribe, 0x02)); }
byte EncodeConnAckPacket(MqttConnAckPacket packet) { byte connectAcknowledgeFlags = 0x0; if (packet.IsSessionPresent) { connectAcknowledgeFlags |= 0x1; } _bufferWriter.WriteByte(connectAcknowledgeFlags); _bufferWriter.WriteByte((byte)packet.ReasonCode); _propertiesWriter.WriteSessionExpiryInterval(packet.SessionExpiryInterval); _propertiesWriter.WriteAuthenticationMethod(packet.AuthenticationMethod); _propertiesWriter.WriteAuthenticationData(packet.AuthenticationData); _propertiesWriter.WriteRetainAvailable(packet.RetainAvailable); _propertiesWriter.WriteReceiveMaximum(packet.ReceiveMaximum); _propertiesWriter.WriteMaximumQoS(packet.MaximumQoS); _propertiesWriter.WriteAssignedClientIdentifier(packet.AssignedClientIdentifier); _propertiesWriter.WriteTopicAliasMaximum(packet.TopicAliasMaximum); _propertiesWriter.WriteReasonString(packet.ReasonString); _propertiesWriter.WriteMaximumPacketSize(packet.MaximumPacketSize); _propertiesWriter.WriteWildcardSubscriptionAvailable(packet.WildcardSubscriptionAvailable); _propertiesWriter.WriteSubscriptionIdentifiersAvailable(packet.SubscriptionIdentifiersAvailable); _propertiesWriter.WriteSharedSubscriptionAvailable(packet.SharedSubscriptionAvailable); _propertiesWriter.WriteServerKeepAlive(packet.ServerKeepAlive); _propertiesWriter.WriteResponseInformation(packet.ResponseInformation); _propertiesWriter.WriteServerReference(packet.ServerReference); _propertiesWriter.WriteUserProperties(packet.UserProperties); _propertiesWriter.WriteTo(_bufferWriter); _propertiesWriter.Reset(); return(MqttBufferWriter.BuildFixedHeader(MqttControlPacketType.ConnAck)); }
public IMqttChannelAdapter CreateClientAdapter(MqttClientOptions options, MqttPacketInspector packetInspector, IMqttNetLogger logger) { if (options == null) { throw new ArgumentNullException(nameof(options)); } IMqttChannel channel; switch (options.ChannelOptions) { case MqttClientTcpOptions _: { channel = new MqttTcpChannel(options); break; } case MqttClientWebSocketOptions webSocketOptions: { channel = new MqttWebSocketChannel(webSocketOptions); break; } default: { throw new NotSupportedException(); } } var bufferWriter = new MqttBufferWriter(options.WriterBufferSize, options.WriterBufferSizeMax); var packetFormatterAdapter = new MqttPacketFormatterAdapter(options.ProtocolVersion, bufferWriter); return(new MqttChannelAdapter(channel, packetFormatterAdapter, packetInspector, logger)); }
byte EncodePublishPacket(MqttPublishPacket packet) { if (packet.QualityOfServiceLevel == 0 && packet.Dup) { throw new MqttProtocolViolationException("Dup flag must be false for QoS 0 packets [MQTT-3.3.1-2]."); } _bufferWriter.WriteString(packet.Topic); if (packet.QualityOfServiceLevel > MqttQualityOfServiceLevel.AtMostOnce) { if (packet.PacketIdentifier == 0) { throw new MqttProtocolViolationException("Publish packet has no packet identifier."); } _bufferWriter.WriteTwoByteInteger(packet.PacketIdentifier); } else { if (packet.PacketIdentifier > 0) { throw new MqttProtocolViolationException("Packet identifier must be 0 if QoS == 0 [MQTT-2.3.1-5]."); } } _propertiesWriter.WriteContentType(packet.ContentType); _propertiesWriter.WriteCorrelationData(packet.CorrelationData); _propertiesWriter.WriteMessageExpiryInterval(packet.MessageExpiryInterval); _propertiesWriter.WritePayloadFormatIndicator(packet.PayloadFormatIndicator); _propertiesWriter.WriteResponseTopic(packet.ResponseTopic); _propertiesWriter.WriteSubscriptionIdentifiers(packet.SubscriptionIdentifiers); _propertiesWriter.WriteUserProperties(packet.UserProperties); _propertiesWriter.WriteTopicAlias(packet.TopicAlias); _propertiesWriter.WriteTo(_bufferWriter); _propertiesWriter.Reset(); // The payload is the past part of the packet. But it is not added here in order to keep // memory allocation low. byte fixedHeader = 0; if (packet.Retain) { fixedHeader |= 0x01; } fixedHeader |= (byte)((byte)packet.QualityOfServiceLevel << 1); if (packet.Dup) { fixedHeader |= 0x08; } return(MqttBufferWriter.BuildFixedHeader(MqttControlPacketType.Publish, fixedHeader)); }
public void WriteTo(MqttBufferWriter target) { if (target == null) { throw new ArgumentNullException(nameof(target)); } target.WriteVariableByteInteger((uint)_bufferWriter.Length); target.Write(_bufferWriter); }
static byte EncodeUnsubAckPacket(MqttUnsubAckPacket packet, MqttBufferWriter bufferWriter) { if (packet.PacketIdentifier == 0) { throw new MqttProtocolViolationException("UnsubAck packet has no packet identifier."); } bufferWriter.WriteTwoByteInteger(packet.PacketIdentifier); return(MqttBufferWriter.BuildFixedHeader(MqttControlPacketType.UnsubAck)); }
public MqttPacketSerializationHelper(MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311, MqttBufferWriter bufferWriter = null) { _protocolVersion = protocolVersion; if (bufferWriter == null) { bufferWriter = new MqttBufferWriter(4096, 65535); } _packetFormatter = MqttPacketFormatterAdapter.GetMqttPacketFormatter(_protocolVersion, bufferWriter); }
public void GlobalSetup() { _packet = new MqttPublishPacket { Topic = "A" }; _bufferWriter = new MqttBufferWriter(4096, 65535); _serializer = new MqttV3PacketFormatter(_bufferWriter, MqttProtocolVersion.V311); _serializedPacket = _serializer.Encode(_packet).Join(); }
async void OnConnectionReceivedAsync(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args) { try { var clientHandler = ClientHandler; if (clientHandler != null) { X509Certificate2 clientCertificate = null; if (args.Socket.Control.ClientCertificate != null) { try { clientCertificate = new X509Certificate2(args.Socket.Control.ClientCertificate.GetCertificateBlob().ToArray()); } catch (Exception exception) { _logger.Warning(exception, "Unable to convert UWP certificate to X509Certificate2."); } } var bufferWriter = new MqttBufferWriter(4096, 65535); var packetFormatterAdapter = new MqttPacketFormatterAdapter(bufferWriter); var tcpChannel = new MqttTcpChannel(args.Socket, clientCertificate, _options); using (var clientAdapter = new MqttChannelAdapter(tcpChannel, packetFormatterAdapter, null, _rootLogger)) { await clientHandler(clientAdapter).ConfigureAwait(false); } } } catch (Exception exception) { if (exception is ObjectDisposedException) { // It can happen that the listener socket is accessed after the cancellation token is already set and the listener socket is disposed. return; } _logger.Error(exception, "Error while handling client connection."); } finally { try { args.Socket.Dispose(); } catch (Exception exception) { _logger.Error(exception, "Error while cleaning up client connection."); } } }
byte EncodeDisconnectPacket(MqttDisconnectPacket packet) { _bufferWriter.WriteByte((byte)packet.ReasonCode); _propertiesWriter.WriteServerReference(packet.ServerReference); _propertiesWriter.WriteReasonString(packet.ReasonString); _propertiesWriter.WriteSessionExpiryInterval(packet.SessionExpiryInterval); _propertiesWriter.WriteUserProperties(packet.UserProperties); _propertiesWriter.WriteTo(_bufferWriter); _propertiesWriter.Reset(); return(MqttBufferWriter.BuildFixedHeader(MqttControlPacketType.Disconnect)); }
byte EncodeSubscribePacket(MqttSubscribePacket packet) { if (packet.TopicFilters?.Any() != true) { throw new MqttProtocolViolationException("At least one topic filter must be set [MQTT-3.8.3-3]."); } ThrowIfPacketIdentifierIsInvalid(packet.PacketIdentifier, packet); _bufferWriter.WriteTwoByteInteger(packet.PacketIdentifier); if (packet.SubscriptionIdentifier > 0) { _propertiesWriter.WriteSubscriptionIdentifier(packet.SubscriptionIdentifier); } _propertiesWriter.WriteUserProperties(packet.UserProperties); _propertiesWriter.WriteTo(_bufferWriter); _propertiesWriter.Reset(); if (packet.TopicFilters?.Count > 0) { foreach (var topicFilter in packet.TopicFilters) { _bufferWriter.WriteString(topicFilter.Topic); var options = (byte)topicFilter.QualityOfServiceLevel; if (topicFilter.NoLocal) { options |= 1 << 2; } if (topicFilter.RetainAsPublished) { options |= 1 << 3; } if (topicFilter.RetainHandling != MqttRetainHandling.SendAtSubscribe) { options |= (byte)((byte)topicFilter.RetainHandling << 4); } _bufferWriter.WriteByte(options); } } return(MqttBufferWriter.BuildFixedHeader(MqttControlPacketType.Subscribe, 0x02)); }
byte EncodeAuthPacket(MqttAuthPacket packet) { _bufferWriter.WriteByte((byte)packet.ReasonCode); _propertiesWriter.WriteAuthenticationMethod(packet.AuthenticationMethod); _propertiesWriter.WriteAuthenticationData(packet.AuthenticationData); _propertiesWriter.WriteReasonString(packet.ReasonString); _propertiesWriter.WriteUserProperties(packet.UserProperties); _propertiesWriter.WriteTo(_bufferWriter); _propertiesWriter.Reset(); return(MqttBufferWriter.BuildFixedHeader(MqttControlPacketType.Auth)); }
byte EncodeConnAckPacketV311(MqttConnAckPacket packet, MqttBufferWriter bufferWriter) { byte connectAcknowledgeFlags = 0x0; if (packet.IsSessionPresent) { connectAcknowledgeFlags |= 0x1; } bufferWriter.WriteByte(connectAcknowledgeFlags); bufferWriter.WriteByte((byte)packet.ReturnCode); return(MqttBufferWriter.BuildFixedHeader(MqttControlPacketType.ConnAck)); }
public void Reset_After_Usage() { var writer = new MqttBufferWriter(4096, 65535); writer.WriteString("AString"); writer.WriteByte(0x1); writer.WriteByte(0x0); writer.WriteByte(0x1); writer.WriteVariableByteInteger(1234U); writer.WriteVariableByteInteger(9876U); writer.Reset(0); Assert.AreEqual(0, writer.Length); }
public async Task TestCorruptedConnectPacket() { var writer = new MqttBufferWriter(4096, 65535); var serializer = new MqttPacketFormatterAdapter(writer); var pipe = new DuplexPipeMockup(); var connection = new DefaultConnectionContext(); connection.Transport = pipe; var ctx = new MqttConnectionContext(serializer, connection); await pipe.Receive.Writer.WriteAsync(writer.AddMqttHeader(MqttControlPacketType.Connect, new byte[0])); await Assert.ThrowsExceptionAsync <MqttProtocolViolationException>(() => ctx.ReceivePacketAsync(CancellationToken.None)); // the first exception should complete the pipes so if someone tries to use the connection after that it should throw immidiatly await Assert.ThrowsExceptionAsync <InvalidOperationException>(() => ctx.ReceivePacketAsync(CancellationToken.None)); }
byte EncodePubRelPacket(MqttPubRelPacket packet) { ThrowIfPacketIdentifierIsInvalid(packet.PacketIdentifier, packet); _propertiesWriter.WriteReasonString(packet.ReasonString); _propertiesWriter.WriteUserProperties(packet.UserProperties); _bufferWriter.WriteTwoByteInteger(packet.PacketIdentifier); if (_propertiesWriter.Length > 0 || packet.ReasonCode != MqttPubRelReasonCode.Success) { _bufferWriter.WriteByte((byte)packet.ReasonCode); _propertiesWriter.WriteTo(_bufferWriter); _propertiesWriter.Reset(); } return(MqttBufferWriter.BuildFixedHeader(MqttControlPacketType.PubRel, 0x02)); }
public MqttPacketBuffer Encode(MqttPacket packet) { if (packet == null) { throw new ArgumentNullException(nameof(packet)); } // Leave enough head space for max header size (fixed + 4 variable remaining length = 5 bytes) _bufferWriter.Reset(5); _bufferWriter.Seek(5); var fixedHeader = EncodePacket(packet, _bufferWriter); var remainingLength = (uint)(_bufferWriter.Length - 5); var publishPacket = packet as MqttPublishPacket; if (publishPacket?.Payload != null) { remainingLength += (uint)publishPacket.Payload.Length; } var remainingLengthSize = MqttBufferWriter.GetLengthOfVariableInteger(remainingLength); var headerSize = FixedHeaderSize + remainingLengthSize; var headerOffset = 5 - headerSize; // Position cursor on correct offset on beginning of array (has leading 0x0) _bufferWriter.Seek(headerOffset); _bufferWriter.WriteByte(fixedHeader); _bufferWriter.WriteVariableByteInteger(remainingLength); var buffer = _bufferWriter.GetBuffer(); var firstSegment = new ArraySegment <byte>(buffer, headerOffset, _bufferWriter.Length - headerOffset); if (publishPacket?.Payload != null) { var payloadSegment = new ArraySegment <byte>(publishPacket.Payload, 0, publishPacket.Payload.Length); return(new MqttPacketBuffer(firstSegment, payloadSegment)); } return(new MqttPacketBuffer(firstSegment)); }
byte EncodeUnsubAckPacket(MqttUnsubAckPacket packet) { ThrowIfPacketIdentifierIsInvalid(packet.PacketIdentifier, packet); _bufferWriter.WriteTwoByteInteger(packet.PacketIdentifier); _propertiesWriter.WriteReasonString(packet.ReasonString); _propertiesWriter.WriteUserProperties(packet.UserProperties); _propertiesWriter.WriteTo(_bufferWriter); _propertiesWriter.Reset(); foreach (var reasonCode in packet.ReasonCodes) { _bufferWriter.WriteByte((byte)reasonCode); } return(MqttBufferWriter.BuildFixedHeader(MqttControlPacketType.UnsubAck)); }
public void Encode_Four_Byte_Integer() { var writer = new MqttBufferWriter(4, 4); for (uint value = 0; value < 268435455; value++) { writer.WriteVariableByteInteger(value); var buffer = writer.GetBuffer(); var reader = new MqttBufferReader(); reader.SetBuffer(buffer, 0, writer.Length); var checkValue = reader.ReadVariableByteInteger(); Assert.AreEqual(value, checkValue); writer.Reset(0); } }
static byte EncodePublishPacket(MqttPublishPacket packet, MqttBufferWriter bufferWriter) { ValidatePublishPacket(packet); bufferWriter.WriteString(packet.Topic); if (packet.QualityOfServiceLevel > MqttQualityOfServiceLevel.AtMostOnce) { if (packet.PacketIdentifier == 0) { throw new MqttProtocolViolationException("Publish packet has no packet identifier."); } bufferWriter.WriteTwoByteInteger(packet.PacketIdentifier); } else { if (packet.PacketIdentifier > 0) { throw new MqttProtocolViolationException("Packet identifier must be empty if QoS == 0 [MQTT-2.3.1-5]."); } } // The payload is the past part of the packet. But it is not added here in order to keep // memory allocation low. byte fixedHeader = 0; if (packet.Retain) { fixedHeader |= 0x01; } fixedHeader |= (byte)((byte)packet.QualityOfServiceLevel << 1); if (packet.Dup) { fixedHeader |= 0x08; } return(MqttBufferWriter.BuildFixedHeader(MqttControlPacketType.Publish, fixedHeader)); }
public void Write_And_Read_Multiple_Times() { var writer = new MqttBufferWriter(4096, 65535); writer.WriteString("A relative short string."); writer.WriteBinaryData(new byte[1234]); writer.WriteByte(0x01); writer.WriteByte(0x02); writer.WriteVariableByteInteger(5647382); writer.WriteString("A relative short string."); writer.WriteVariableByteInteger(8574489); writer.WriteBinaryData(new byte[48]); writer.WriteByte(2); writer.WriteByte(0x02); writer.WriteString("fjgffiogfhgfhoihgoireghreghreguhreguireoghreouighreouighreughreguiorehreuiohruiorehreuioghreug"); writer.WriteBinaryData(new byte[3]); var readPayload = new ArraySegment <byte>(writer.GetBuffer(), 0, writer.Length).ToArray(); var reader = new MqttBufferReader(); reader.SetBuffer(readPayload, 0, readPayload.Length); for (var i = 0; i < 100000; i++) { reader.Seek(0); reader.ReadString(); reader.ReadBinaryData(); reader.ReadByte(); reader.ReadByte(); reader.ReadVariableByteInteger(); reader.ReadString(); reader.ReadVariableByteInteger(); reader.ReadBinaryData(); reader.ReadByte(); reader.ReadByte(); reader.ReadString(); reader.ReadBinaryData(); } }
byte EncodePubAckPacket(MqttPubAckPacket packet) { if (packet.PacketIdentifier == 0) { throw new MqttProtocolViolationException("PubAck packet has no packet identifier."); } _bufferWriter.WriteTwoByteInteger(packet.PacketIdentifier); _propertiesWriter.WriteReasonString(packet.ReasonString); _propertiesWriter.WriteUserProperties(packet.UserProperties); if (_bufferWriter.Length > 0 || packet.ReasonCode != MqttPubAckReasonCode.Success) { _bufferWriter.WriteByte((byte)packet.ReasonCode); _propertiesWriter.WriteTo(_bufferWriter); _propertiesWriter.Reset(); } return(MqttBufferWriter.BuildFixedHeader(MqttControlPacketType.PubAck)); }
public void Write_100_000_Messages() { var writer = new MqttBufferWriter(4096, 65535); for (var i = 0; i < 100000; i++) { writer.WriteString("A relative short string."); writer.WriteByte(0x01); writer.WriteByte(0x02); writer.WriteVariableByteInteger(5647382); writer.WriteString("A relative short string."); writer.WriteVariableByteInteger(8574589); writer.WriteBinaryData(_demoPayload); writer.WriteByte(2); writer.WriteByte(0x02); writer.WriteString("fjgffiogfhgfhoihgoireghreghreguhreguireoghreouighreouighreughreguiorehreuiohruiorehreuioghreug"); writer.WriteBinaryData(_demoPayload); writer.Reset(0); } }
public void GlobalSetup() { TestEnvironment.EnableLogger = false; var writer = new MqttBufferWriter(4096, 65535); writer.WriteString("A relative short string."); writer.WriteBinaryData(_demoPayload); writer.WriteByte(0x01); writer.WriteByte(0x02); writer.WriteVariableByteInteger(5647382); writer.WriteString("A relative short string."); writer.WriteVariableByteInteger(8574489); writer.WriteBinaryData(_demoPayload); writer.WriteByte(2); writer.WriteByte(0x02); writer.WriteString("fjgffiogfhgfhoihgoireghreghreguhreguireoghreouighreouighreughreguiorehreuiohruiorehreuioghreug"); writer.WriteBinaryData(_demoPayload); _readPayload = new ArraySegment <byte>(writer.GetBuffer(), 0, writer.Length).ToArray(); }
byte EncodeUnsubscribePacket(MqttUnsubscribePacket packet) { if (packet.TopicFilters?.Any() != true) { throw new MqttProtocolViolationException("At least one topic filter must be set [MQTT-3.10.3-2]."); } ThrowIfPacketIdentifierIsInvalid(packet.PacketIdentifier, packet); _bufferWriter.WriteTwoByteInteger(packet.PacketIdentifier); _propertiesWriter.WriteUserProperties(packet.UserProperties); _propertiesWriter.WriteTo(_bufferWriter); _propertiesWriter.Reset(); foreach (var topicFilter in packet.TopicFilters) { _bufferWriter.WriteString(topicFilter); } return(MqttBufferWriter.BuildFixedHeader(MqttControlPacketType.Unsubscibe, 0x02)); }
static byte EncodeUnsubscribePacket(MqttUnsubscribePacket packet, MqttBufferWriter bufferWriter) { if (!packet.TopicFilters.Any()) { throw new MqttProtocolViolationException("At least one topic filter must be set [MQTT-3.10.3-2]."); } if (packet.PacketIdentifier == 0) { throw new MqttProtocolViolationException("Unsubscribe packet has no packet identifier."); } bufferWriter.WriteTwoByteInteger(packet.PacketIdentifier); if (packet.TopicFilters?.Any() == true) { foreach (var topicFilter in packet.TopicFilters) { bufferWriter.WriteString(topicFilter); } } return(MqttBufferWriter.BuildFixedHeader(MqttControlPacketType.Unsubscibe, 0x02)); }
public void Use_All_Data_Types() { var writer = new MqttBufferWriter(4096, 65535); writer.WriteString("AString"); writer.WriteByte(0x1); writer.WriteByte(0x0); writer.WriteByte(0x1); writer.WriteVariableByteInteger(1234U); writer.WriteVariableByteInteger(9876U); var buffer = writer.GetBuffer(); var reader = new MqttBufferReader(); reader.SetBuffer(buffer, 0, writer.Length); Assert.AreEqual("AString", reader.ReadString()); Assert.IsTrue(reader.ReadByte() == 1); Assert.IsTrue(reader.ReadByte() == 0); Assert.IsTrue(reader.ReadByte() == 1); Assert.AreEqual(1234U, reader.ReadVariableByteInteger()); Assert.AreEqual(9876U, reader.ReadVariableByteInteger()); }