예제 #1
0
 public MqttPacketSerializer CreateSerializer(MqttProtocolVersion protocolVersion)
 {
     return(new MqttPacketSerializer
     {
         ProtocolVersion = protocolVersion
     });
 }
예제 #2
0
        void DeserializeAndCompare(MqttPacket packet, string expectedBase64Value, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
        {
            var writer = WriterFactory();

            var serializer = MqttPacketFormatterAdapter.GetMqttPacketFormatter(protocolVersion, writer);
            var buffer1    = serializer.Encode(packet);

            using (var headerStream = new MemoryStream(buffer1.Join().ToArray()))
            {
                using (var channel = new TestMqttChannel(headerStream))
                {
                    using (var adapter = new MqttChannelAdapter(
                               channel,
                               new MqttPacketFormatterAdapter(protocolVersion, new MqttBufferWriter(4096, 65535)),
                               null,
                               new MqttNetEventLogger()))
                    {
                        var receivedPacket = adapter.ReceivePacketAsync(CancellationToken.None).GetAwaiter().GetResult();

                        var buffer2 = serializer.Encode(receivedPacket);

                        Assert.AreEqual(expectedBase64Value, Convert.ToBase64String(buffer2.Join().ToArray()));
                    }
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Writes the Connect packet to the given stream and using the given
        /// protocol version.
        /// </summary>
        /// <param name="stream">The stream to write to</param>
        /// <param name="protocolVersion">Protocol to be used to write</param>
        internal override void Serialize(PacketWriter writer, MqttProtocolVersion protocolVersion)
        {
            if (protocolVersion == MqttProtocolVersion.V3_1_1)
            {
                // will flag set, will topic and will message MUST be present
                if (this.WillFlag && (WillMessage == null || String.IsNullOrEmpty(WillTopic)))
                {
                    throw new MqttProtocolException("Last will message is invalid");
                }
                // willflag not set, retain must be 0 and will topic and message MUST NOT be present
                else if (!this.WillFlag && (this.WillRetain || WillMessage != null || !String.IsNullOrEmpty(WillTopic)))
                {
                    throw new MqttProtocolException("Last will message is invalid");
                }
            }

            if (this.WillFlag && ((this.WillTopic.Length < Packet.MinTopicLength) || (this.WillTopic.Length > Packet.MaxTopicLength)))
            {
                throw new MqttProtocolException("Invalid last will topic length");
            }

            writer.SetFixedHeader(PacketType);

            MakeVariableHeader(writer);
            MakePayload(writer);
        }
        internal override void Serialize(PacketWriter writer, MqttProtocolVersion protocolVersion)
        {
            if (Topics.Length != QosLevels.Length)
            {
                throw new InvalidOperationException("The length of Topics should match the length of QosLevels");
            }

            if (protocolVersion == MqttProtocolVersion.V3_1_1)
            {
                writer.SetFixedHeader(PacketType, MqttQos.AtLeastOnce);
            }
            else
            {
                writer.SetFixedHeader(PacketType);
            }

            writer.AppendIntegerField(PacketId);

            for (int i = 0; i < Topics.Length; i++)
            {
                if (String.IsNullOrEmpty(this.Topics[i]) || this.Topics[i].Length > Packet.MaxTopicLength)
                {
                    throw new InvalidOperationException("Invalid topic length");
                }

                writer.AppendTextField(this.Topics[i]);
                writer.Append((byte)(((byte)this.QosLevels[i]) & QosPartMask));
            }
        }
예제 #5
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="clientId">Client identifier</param>
        /// <param name="username">Username</param>
        /// <param name="password">Password</param>
        /// <param name="willRetain">Will retain flag</param>
        /// <param name="willQosLevel">Will QOS level</param>
        /// <param name="willFlag">Will flag</param>
        /// <param name="willTopic">Will topic</param>
        /// <param name="willMessage">Will message</param>
        /// <param name="cleanSession">Clean sessione flag</param>
        /// <param name="keepAlivePeriod">Keep alive period</param>
        /// <param name="protocolVersion">MQTT Protocol version</param>
        public MqttMsgConnect(string clientId,
                              string username,
                              string password,
                              bool willRetain,
                              MqttQoSLevel willQosLevel,
                              bool willFlag,
                              string willTopic,
                              string willMessage,
                              bool cleanSession,
                              ushort keepAlivePeriod,
                              MqttProtocolVersion protocolVersion
                              )
        {
            Type = MqttMessageType.Connect;

            ClientId        = clientId;
            Username        = username;
            Password        = password;
            WillRetain      = willRetain;
            WillQosLevel    = (byte)willQosLevel;
            WillFlag        = willFlag;
            WillTopic       = willTopic;
            WillMessage     = willMessage;
            CleanSession    = cleanSession;
            KeepAlivePeriod = keepAlivePeriod;
            // [v.3.1.1] added new protocol name and version valid for 5.0
            ProtocolVersion = protocolVersion;
            ProtocolName    = (ProtocolVersion == MqttProtocolVersion.Version_3_1_1 || ProtocolVersion == MqttProtocolVersion.Version_5) ? PROTOCOL_NAME_V3_1_1 : PROTOCOL_NAME_V3_1;
        }
예제 #6
0
        TPacket Roundtrip <TPacket>(TPacket packet, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
            where TPacket : MqttBasePacket
        {
            var writer     = WriterFactory();
            var serializer = MqttPacketFormatterAdapter.GetMqttPacketFormatter(protocolVersion, writer);
            var buffer     = serializer.Encode(packet);

            var channel = new TestMqttChannel(buffer.ToArray());
            var adapter = new MqttChannelAdapter(channel, new MqttPacketFormatterAdapter(protocolVersion, writer), null, new MqttNetLogger());

            return((TPacket)adapter.ReceivePacketAsync(CancellationToken.None).GetAwaiter().GetResult());

            //using (var headerStream = new MemoryStream(buffer1.ToArray()))
            //{



            //    //var fixedHeader = new byte[2];

            //    //var header = new MqttPacketReader(channel).ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult().FixedHeader;

            //    //using (var bodyStream = new MemoryStream(Join(buffer1), (int)headerStream.Position, (int)header.RemainingLength))
            //    //{
            //    //    var reader = ReaderFactory(bodyStream.ToArray());
            //    //    return (T)serializer.Decode(new ReceivedMqttPacket(header.Flags, reader, 0));
            //    //}
            //}
        }
        internal override void Deserialize(PacketReader reader, MqttProtocolVersion protocolVersion)
        {
            if (protocolVersion == MqttProtocolVersion.V3_1_1)
            {
                if ((reader.FixedHeaderFirstByte & Packet.PacketFlagsBitMask) != Packet.ZeroedHeaderFlagBits)
                {
                    throw new MqttProtocolException("Unsuback packet received with invalid header flags");
                }
            }

            this.PacketId = reader.ReadIntegerField();

            var bytes = reader.ReadToEnd();

            this.GrantedQosLevels = new SubackReturnCode[bytes.Length];

            for (int i = 0; i < bytes.Length; i++)
            {
                if (bytes[i] > (byte)SubackReturnCode.ExactlyOnceGranted && bytes[i] != (byte)SubackReturnCode.SubscriptionFailed)
                {
                    throw new MqttProtocolException(String.Format("Invalid qos level '{0}' received from broker", bytes[i]));
                }

                this.GrantedQosLevels[i] = (SubackReturnCode)bytes[i];
            }
        }
예제 #8
0
    /// <summary>
    /// Start is called before the first frame update.
    /// </summary>
    private void Start()
    {
        //Set up default Mqtt properties for https://github.com/khilscher/MqttClient
        broker          = "mqtt.eclipse.org";
        port            = 1883;
        secure          = false;
        sslprotocol     = MqttSslProtocols.None;
        protocolversion = MqttProtocolVersion.Version_3_1_1;
        username        = "";
        password        = "";
        clientId        = "client123abcd";
        topic           = "vehicle/telemetry";
        publish         = false;
        qos             = (byte)2;
        retain          = false;
        cleansession    = false;
        keepalive       = 60;

        //Update the settings menu with default values
        settings.MQTTBrokerTextInputButton.TextObject.text = broker;
        settings.DeviceIDTextInputButton.TextObject.text   = clientId;
        settings.TopicTextInputButton.TextObject.text      = topic;

        //Default data properties
        data = null;
        dataHasBeenUpdated = false;

        //Add callback methods for setting ui
        settings.ConnectButton.OnClick.AddListener(() => MqttConnect());
        settings.DisconnectButton.OnClick.AddListener(() => MqttDisconnect());
        settings.SubscribeButton.OnClick.AddListener(() => MqttSubscribe());
        settings.UnsubscribeButton.OnClick.AddListener(() => MqttUnsubscribe());
    }
예제 #9
0
        public static IMqttPacketFormatter GetMqttPacketFormatter(MqttProtocolVersion protocolVersion, IMqttPacketWriter writer)
        {
            if (protocolVersion == MqttProtocolVersion.Unknown)
            {
                throw new InvalidOperationException("MQTT protocol version is invalid.");
            }

            switch (protocolVersion)
            {
            case MqttProtocolVersion.V500:
            {
                return(new MqttV500PacketFormatter(writer));
            }

            case MqttProtocolVersion.V311:
            {
                return(new MqttV311PacketFormatter(writer));
            }

            case MqttProtocolVersion.V310:
            {
                return(new MqttV310PacketFormatter(writer));
            }

            default:
            {
                throw new NotSupportedException();
            }
            }
        }
예제 #10
0
        async Task Execute_Success(MqttQualityOfServiceLevel qosLevel, MqttProtocolVersion protocolVersion)
        {
            using (var testEnvironment = new TestEnvironment(TestContext))
            {
                await testEnvironment.StartServer();

                var responseSender = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithProtocolVersion(protocolVersion));

                await responseSender.SubscribeAsync("MQTTnet.RPC/+/ping", qosLevel);

                responseSender.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(async e =>
                {
                    await responseSender.PublishAsync(e.ApplicationMessage.Topic + "/response", "pong");
                });

                var requestSender = await testEnvironment.ConnectClient();

                using (var rpcClient = new MqttRpcClient(requestSender, new MqttRpcClientOptionsBuilder().Build()))
                {
                    var response = await rpcClient.ExecuteAsync(TimeSpan.FromSeconds(5), "ping", "", qosLevel);

                    Assert.AreEqual("pong", Encoding.UTF8.GetString(response));
                }
            }
        }
 public static TPacket EncodeAndDecodePacket<TPacket>(TPacket packet, MqttProtocolVersion protocolVersion) where TPacket : MqttPacket
 {
     using (var helper = new MqttPacketSerializationHelper(protocolVersion))
     {
         var buffer = helper.Encode(packet);
         return (TPacket)helper.Decode(buffer);
     }
 }
예제 #12
0
 /// <summary>
 /// Creates a new context.
 /// </summary>
 /// <param name="version">The version of MQTT.</param>
 /// <param name="isEmitter">Whether this is our special implementation.</param>
 /// <param name="id">The client id specified in the MQTT connect packet.</param>
 public MqttContext(MqttProtocolVersion version, QoS qos, bool isEmitter, string id, string username)
 {
     this.Version   = version;
     this.QoS       = qos;
     this.IsEmitter = isEmitter;
     this.ClientId  = id;
     this.Username  = username;
 }
예제 #13
0
 /// <summary>
 /// Recycles the packet.
 /// </summary>
 public override void Recycle()
 {
     this.Origin          = null;
     this.Lifetime        = PacketLifetime.Automatic;
     this.ProtocolVersion = MqttProtocolVersion.Unknown;
     this.DupFlag         = false;
     this.QoS             = QoS.AtMostOnce;
     this.Retain          = false;
 }
예제 #14
0
        void UseProtocolVersion(MqttProtocolVersion protocolVersion)
        {
            if (protocolVersion == MqttProtocolVersion.Unknown)
            {
                throw new InvalidOperationException("MQTT protocol version is invalid.");
            }

            ProtocolVersion = protocolVersion;
            _formatter      = GetMqttPacketFormatter(protocolVersion, Writer);
        }
예제 #15
0
        public MqttClientOptionsBuilder WithProtocolVersion(MqttProtocolVersion value)
        {
            if (value == MqttProtocolVersion.Unknown)
            {
                throw new ArgumentException("Protocol version is invalid.");
            }

            _options.ProtocolVersion = value;
            return(this);
        }
예제 #16
0
        /// <summary>
        /// Returns the bytes that represents the current object.
        /// </summary>
        /// <param name="protocolVersion">MQTT protocol version</param>
        /// <returns>An array of bytes that represents the current object.</returns>
        public override byte[] GetBytes(MqttProtocolVersion protocolVersion)
        {
            byte[] buffer = new byte[2];
            int    index  = 0;

            // first fixed header byte
            buffer[index++] = (byte)MqttMessageType.PingRequest << MSG_TYPE_OFFSET;
            buffer[index++] = 0x00;

            return(buffer);
        }
        public MqttPacketSerializationHelper(MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311, MqttBufferWriter bufferWriter = null)
        {
            _protocolVersion = protocolVersion;

            if (bufferWriter == null)
            {
                bufferWriter = new MqttBufferWriter(4096, 65535);
            }

            _packetFormatter = MqttPacketFormatterAdapter.GetMqttPacketFormatter(_protocolVersion, bufferWriter);
        }
예제 #18
0
        TPacket Roundtrip <TPacket>(TPacket packet, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311, MqttBufferWriter bufferWriter = null) where TPacket : MqttPacket
        {
            var writer     = bufferWriter ?? WriterFactory();
            var serializer = MqttPacketFormatterAdapter.GetMqttPacketFormatter(protocolVersion, writer);
            var buffer     = serializer.Encode(packet);

            using (var channel = new TestMqttChannel(buffer.Join().ToArray()))
            {
                var adapter = new MqttChannelAdapter(channel, new MqttPacketFormatterAdapter(protocolVersion, new MqttBufferWriter(4096, 65535)), null, new MqttNetEventLogger());
                return((TPacket)adapter.ReceivePacketAsync(CancellationToken.None).GetAwaiter().GetResult());
            }
        }
예제 #19
0
        public MqttBroker(string host, int port, bool secure, MqttSslProtocols sslprotocol, MqttProtocolVersion protocolversion, string username, string password)
        {
            this.host            = host;
            this.port            = port;
            this.secure          = secure;
            this.sslprotocol     = sslprotocol;
            this.protocolversion = protocolversion;
            this.username        = username;
            this.password        = password;

            Initialize();
        }
예제 #20
0
        public MqttMsgConnack CreateConnack(MqttProtocolVersion proctocolVersion, byte returnCode, bool sessionPresent)
        {
            var connack = new MqttMsgConnack {
                ReturnCode = returnCode
            };

            if (proctocolVersion == MqttProtocolVersion.Version_3_1_1)
            {
                connack.SessionPresent = sessionPresent;
            }

            return(connack);
        }
예제 #21
0
        internal override void Serialize(PacketWriter writer, MqttProtocolVersion protocolVersion)
        {
            if (protocolVersion == MqttProtocolVersion.V3_1_1)
            {
                writer.SetFixedHeader(PacketType, MqttQos.AtLeastOnce);
            }
            else
            {
                writer.SetFixedHeader(PacketType);
            }

            writer.AppendIntegerField(PacketId);
        }
        public MqttClientConnectResult Create(MqttConnAckPacket connAckPacket, MqttProtocolVersion protocolVersion)
        {
            if (connAckPacket == null)
            {
                throw new ArgumentNullException(nameof(connAckPacket));
            }

            if (protocolVersion == MqttProtocolVersion.V500)
            {
                return(CreateForMqtt500(connAckPacket));
            }

            return(CreateForMqtt311(connAckPacket));
        }
예제 #23
0
        internal override void Deserialize(PacketReader reader, MqttProtocolVersion protocolVersion)
        {
            if (protocolVersion == MqttProtocolVersion.V3_1_1)
            {
                if ((reader.FixedHeaderFirstByte & Packet.PacketFlagsBitMask) != Packet.ZeroedHeaderFlagBits)
                {
                    throw new MqttProtocolException("Pingresp packet received with invalid header flags");
                }
            }

            if (reader.RemainingLength != 0)
            {
                throw new MqttProtocolException("Pingresp packet received with invalid remaining length");
            }
        }
예제 #24
0
        internal override void Deserialize(PacketReader reader, MqttProtocolVersion protocolVersion)
        {
            this.DupFlag  = reader.Dup;
            this.QosLevel = reader.QosLevel;
            this.Retain   = reader.Retain;

            this.Topic = reader.ReadTextField();

            if (QosLevel > MqttQos.AtMostOnce)
            {
                this.PacketId = reader.ReadIntegerField();
            }

            this.Message = reader.ReadToEnd();
        }
예제 #25
0
        internal override void Deserialize(PacketReader reader, MqttProtocolVersion protocolVersion)
        {
            if (protocolVersion == MqttProtocolVersion.V3_1_1)
            {
                if ((reader.FixedHeaderFirstByte & Packet.PacketFlagsBitMask) != Packet.ZeroedHeaderFlagBits)
                {
                    throw new MqttProtocolException("Pubcomp packet received with invalid header flags");
                }
            }

            if (reader.RemainingLength != 2)
            {
                throw new MqttProtocolException("Remaining length of the incoming pubcomp packet is invalid");
            }

            this.PacketId = reader.ReadIntegerField();
        }
예제 #26
0
        internal override void Deserialize(PacketReader reader, MqttProtocolVersion protocolVersion)
        {
            if (protocolVersion == MqttProtocolVersion.V3_1_1)
            {
                if ((reader.FixedHeaderFirstByte & Packet.PacketFlagsBitMask) != Packet.ZeroedHeaderFlagBits)
                {
                    throw new MqttProtocolException("Connack packet received with invalid header flags");
                }
            }

            if (reader.RemainingLength != 2)
            {
                throw new MqttProtocolException("Connack packet received with invalid remaining length");
            }

            this.SessionPresent = (reader.ReadByte() & SessionPresentFlag) > 0;
            this.ReturnCode     = (ConnackReturnCode)reader.ReadByte();
        }
        internal override void Serialize(PacketWriter writer, MqttProtocolVersion protocolVersion)
        {
            if (protocolVersion == MqttProtocolVersion.V3_1_1)
            {
                writer.SetFixedHeader(PacketType, MqttQos.AtLeastOnce);
            }
            else
            {
                writer.SetFixedHeader(PacketType);
            }

            writer.AppendIntegerField(PacketId);

            foreach (string topic in this.Topics)
            {
                writer.AppendTextField(topic);
            }
        }
        /// <summary>
        /// Returns the bytes that represents the current object.
        /// </summary>
        /// <param name="protocolVersion">MQTT protocol version</param>
        /// <returns>An array of bytes that represents the current object.</returns>
        public override byte[] GetBytes(MqttProtocolVersion protocolVersion)
        {
            byte[] buffer = new byte[2];
            int    index  = 0;

            // first fixed header byte
            if ((protocolVersion == MqttProtocolVersion.Version_3_1_1) || (protocolVersion == MqttProtocolVersion.Version_5))
            {
                buffer[index++] = ((byte)MqttMessageType.PingResponse << MSG_TYPE_OFFSET) | MQTT_MSG_PINGRESP_FLAG_BITS; // [v.3.1.1]
            }
            else
            {
                buffer[index++] = (byte)MqttMessageType.PingResponse << MSG_TYPE_OFFSET;
            }

            buffer[index] = 0x00;

            return(buffer);
        }
        /// <summary>
        /// Parse bytes for a PINGRESP message
        /// </summary>
        /// <param name="fixedHeaderFirstByte">First fixed header byte</param>
        /// <param name="protocolVersion">MQTT Protocol Version</param>
        /// <param name="channel">Channel connected to the broker</param>
        /// <returns>PINGRESP message instance</returns>
        public static MqttMsgPingResp Parse(byte fixedHeaderFirstByte, MqttProtocolVersion protocolVersion, IMqttNetworkChannel channel)
        {
            MqttMsgPingResp msg = new MqttMsgPingResp();

            if ((protocolVersion == MqttProtocolVersion.Version_3_1_1) || (protocolVersion == MqttProtocolVersion.Version_5))
            {
                // [v3.1.1] check flag bits
                if ((fixedHeaderFirstByte & MSG_FLAG_BITS_MASK) != MQTT_MSG_PINGRESP_FLAG_BITS)
                {
                    throw new MqttClientException(MqttClientErrorCode.InvalidFlagBits);
                }
            }

            // already know remaininglength is zero (MQTT specification),
            // so it isn't necessary to read other data from socket
            DecodeVariableByte(channel);

            return(msg);
        }
예제 #30
0
        internal override void Serialize(PacketWriter writer, MqttProtocolVersion protocolVersion)
        {
            Validate();

            if (protocolVersion == MqttProtocolVersion.V3_1_1)
            {
                writer.SetFixedHeader(PacketType, MqttQos.AtLeastOnce);
            }
            else
            {
                writer.SetFixedHeader(PacketType);
            }

            writer.AppendIntegerField(PacketId);

            for (int i = 0; i < Topics.Length; i++)
            {
                writer.AppendTextField(this.Topics[i]);
                writer.Append((byte)(((byte)this.QosLevels[i]) & QosPartMask));
            }
        }