示例#1
0
        private byte Serialize(MqttConnAckPacket packet, MqttPacketWriter packetWriter)
        {
            if (ProtocolVersion == MqttProtocolVersion.V310)
            {
                packetWriter.Write(0);
            }
            else if (ProtocolVersion == MqttProtocolVersion.V311)
            {
                byte connectAcknowledgeFlags = 0x0;
                if (packet.IsSessionPresent)
                {
                    connectAcknowledgeFlags |= 0x1;
                }

                packetWriter.Write(connectAcknowledgeFlags);
            }
            else
            {
                throw new MqttProtocolViolationException("Protocol version not supported.");
            }

            packetWriter.Write((byte)packet.ConnectReturnCode);

            return(MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.ConnAck));
        }
示例#2
0
        byte EncodeConnAckPacket(MqttConnAckPacket packet, MqttBufferWriter bufferWriter)
        {
            bufferWriter.WriteByte(0); // Reserved.
            bufferWriter.WriteByte((byte)packet.ReturnCode);

            return(MqttBufferWriter.BuildFixedHeader(MqttControlPacketType.ConnAck));
        }
示例#3
0
        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));
        }
示例#4
0
        protected virtual byte EncodeConnAckPacket(MqttConnAckPacket packet, IMqttPacketWriter packetWriter)
        {
            packetWriter.Write(0); // Reserved.
            packetWriter.Write((byte)packet.ReturnCode.Value);

            return(MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.ConnAck));
        }
        public MqttConnAckPacket Create(ValidatingConnectionEventArgs validatingConnectionEventArgs)
        {
            if (validatingConnectionEventArgs == null)
            {
                throw new ArgumentNullException(nameof(validatingConnectionEventArgs));
            }

            var connAckPacket = new MqttConnAckPacket
            {
                ReturnCode      = MqttConnectReasonCodeConverter.ToConnectReturnCode(validatingConnectionEventArgs.ReasonCode),
                ReasonCode      = validatingConnectionEventArgs.ReasonCode,
                RetainAvailable = true,
                SubscriptionIdentifiersAvailable = true,
                SharedSubscriptionAvailable      = false,
                TopicAliasMaximum             = ushort.MaxValue,
                MaximumQoS                    = MqttQualityOfServiceLevel.ExactlyOnce,
                WildcardSubscriptionAvailable = true,

                AuthenticationMethod     = validatingConnectionEventArgs.AuthenticationMethod,
                AuthenticationData       = validatingConnectionEventArgs.ResponseAuthenticationData,
                AssignedClientIdentifier = validatingConnectionEventArgs.AssignedClientIdentifier,
                ReasonString             = validatingConnectionEventArgs.ReasonString,
                ServerReference          = validatingConnectionEventArgs.ServerReference,
                UserProperties           = validatingConnectionEventArgs.ResponseUserProperties,

                ResponseInformation = null,
                MaximumPacketSize   = 0, // Unlimited,
                ReceiveMaximum      = 0  // Unlimited
            };

            return(connAckPacket);
        }
示例#6
0
        public MqttClientAuthenticateResult CreateClientConnectResult(MqttConnAckPacket connAckPacket)
        {
            if (connAckPacket == null)
            {
                throw new ArgumentNullException(nameof(connAckPacket));
            }

            return(new MqttClientAuthenticateResult
            {
                IsSessionPresent = connAckPacket.IsSessionPresent,
                ResultCode = (MqttClientConnectResultCode)connAckPacket.ReasonCode.Value,
                WildcardSubscriptionAvailable = connAckPacket.Properties?.WildcardSubscriptionAvailable,
                RetainAvailable = connAckPacket.Properties?.RetainAvailable,
                AssignedClientIdentifier = connAckPacket.Properties?.AssignedClientIdentifier,
                AuthenticationMethod = connAckPacket.Properties?.AuthenticationMethod,
                AuthenticationData = connAckPacket.Properties?.AuthenticationData,
                MaximumPacketSize = connAckPacket.Properties?.MaximumPacketSize,
                ReasonString = connAckPacket.Properties?.ReasonString,
                ReceiveMaximum = connAckPacket.Properties?.ReceiveMaximum,
                MaximumQoS = connAckPacket.Properties?.MaximumQoS ?? MqttQualityOfServiceLevel.ExactlyOnce,
                ResponseInformation = connAckPacket.Properties?.ResponseInformation,
                TopicAliasMaximum = connAckPacket.Properties?.TopicAliasMaximum,
                ServerReference = connAckPacket.Properties?.ServerReference,
                ServerKeepAlive = connAckPacket.Properties?.ServerKeepAlive,
                SessionExpiryInterval = connAckPacket.Properties?.SessionExpiryInterval,
                SubscriptionIdentifiersAvailable = connAckPacket.Properties?.SubscriptionIdentifiersAvailable,
                SharedSubscriptionAvailable = connAckPacket.Properties?.SharedSubscriptionAvailable,
                UserProperties = connAckPacket.Properties?.UserProperties
            });
        }
示例#7
0
        public MqttClientConnectResult CreateClientConnectResult(MqttConnAckPacket connAckPacket)
        {
            if (connAckPacket == null)
            {
                throw new ArgumentNullException(nameof(connAckPacket));
            }

            MqttClientConnectResultCode resultCode;

            switch (connAckPacket.ReturnCode)
            {
            case MqttConnectReturnCode.ConnectionAccepted:
            {
                resultCode = MqttClientConnectResultCode.Success;
                break;
            }

            case MqttConnectReturnCode.ConnectionRefusedUnacceptableProtocolVersion:
            {
                resultCode = MqttClientConnectResultCode.UnsupportedProtocolVersion;
                break;
            }

            case MqttConnectReturnCode.ConnectionRefusedNotAuthorized:
            {
                resultCode = MqttClientConnectResultCode.NotAuthorized;
                break;
            }

            case MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword:
            {
                resultCode = MqttClientConnectResultCode.BadUserNameOrPassword;
                break;
            }

            case MqttConnectReturnCode.ConnectionRefusedIdentifierRejected:
            {
                resultCode = MqttClientConnectResultCode.ClientIdentifierNotValid;
                break;
            }

            case MqttConnectReturnCode.ConnectionRefusedServerUnavailable:
            {
                resultCode = MqttClientConnectResultCode.ServerUnavailable;
                break;
            }

            default:
                throw new MqttProtocolViolationException("Received unexpected return code.");
            }

            return(new MqttClientConnectResult
            {
                RetainAvailable = true,               // Always true because v3.1.1 does not have a way to "disable" that feature.
                WildcardSubscriptionAvailable = true, // Always true because v3.1.1 does not have a way to "disable" that feature.
                IsSessionPresent = connAckPacket.IsSessionPresent,
                ResultCode = resultCode
            });
        }
        async Task <MqttClientConnection> CreateClientConnection(
            MqttConnectPacket connectPacket,
            MqttConnAckPacket connAckPacket,
            IMqttChannelAdapter channelAdapter,
            IDictionary <object, object> sessionItems)
        {
            MqttClientConnection connection;

            using (await _createConnectionSyncRoot.WaitAsync(CancellationToken.None).ConfigureAwait(false))
            {
                MqttClientSession session;
                lock (_clientSessions)
                {
                    if (!_clientSessions.TryGetValue(connectPacket.ClientId, out session))
                    {
                        _logger.Verbose("Created a new session for client '{0}'.", connectPacket.ClientId);
                        session = CreateSession(connectPacket.ClientId, sessionItems);
                    }
                    else
                    {
                        if (connectPacket.CleanSession)
                        {
                            _logger.Verbose("Deleting existing session of client '{0}'.", connectPacket.ClientId);
                            session = CreateSession(connectPacket.ClientId, sessionItems);
                        }
                        else
                        {
                            _logger.Verbose("Reusing existing session of client '{0}'.", connectPacket.ClientId);
                            connAckPacket.IsSessionPresent = true;
                        }
                    }

                    _clientSessions[connectPacket.ClientId] = session;
                }

                MqttClientConnection existingConnection;

                lock (_clientConnections)
                {
                    _clientConnections.TryGetValue(connectPacket.ClientId, out existingConnection);
                    connection = CreateConnection(connectPacket, channelAdapter, session);

                    _clientConnections[connectPacket.ClientId] = connection;
                }

                if (existingConnection != null)
                {
                    await _eventDispatcher.SafeNotifyClientDisconnectedAsync(existingConnection.ClientId,
                                                                             MqttClientDisconnectType.Takeover, existingConnection.Endpoint);

                    existingConnection.IsTakenOver = true;
                    await existingConnection.StopAsync(MqttClientDisconnectReason.SessionTakenOver)
                    .ConfigureAwait(false);
                }
            }

            return(connection);
        }
示例#9
0
        public MqttClientAuthenticateResult CreateClientConnectResult(MqttConnAckPacket connAckPacket)
        {
            if (connAckPacket == null)
            {
                throw new ArgumentNullException(nameof(connAckPacket));
            }

            MqttClientConnectResultCode resultCode;

            switch (connAckPacket.ReturnCode.Value)
            {
            case MqttConnectReturnCode.ConnectionAccepted:
            {
                resultCode = MqttClientConnectResultCode.Success;
                break;
            }

            case MqttConnectReturnCode.ConnectionRefusedUnacceptableProtocolVersion:
            {
                resultCode = MqttClientConnectResultCode.UnsupportedProtocolVersion;
                break;
            }

            case MqttConnectReturnCode.ConnectionRefusedNotAuthorized:
            {
                resultCode = MqttClientConnectResultCode.NotAuthorized;
                break;
            }

            case MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword:
            {
                resultCode = MqttClientConnectResultCode.BadUserNameOrPassword;
                break;
            }

            case MqttConnectReturnCode.ConnectionRefusedIdentifierRejected:
            {
                resultCode = MqttClientConnectResultCode.ClientIdentifierNotValid;
                break;
            }

            case MqttConnectReturnCode.ConnectionRefusedServerUnavailable:
            {
                resultCode = MqttClientConnectResultCode.ServerUnavailable;
                break;
            }

            default:
                throw new MqttProtocolViolationException("Received unexpected return code.");
            }

            return(new MqttClientAuthenticateResult
            {
                IsSessionPresent = connAckPacket.IsSessionPresent,
                ResultCode = resultCode
            });
        }
示例#10
0
        public void DeserializeV310_MqttConnAckPacket()
        {
            var p = new MqttConnAckPacket
            {
                ReturnCode = MqttConnectReturnCode.ConnectionRefusedNotAuthorized
            };

            DeserializeAndCompare(p, "IAIABQ==", MqttProtocolVersion.V310);
        }
        public void SerializeV310_MqttConnAckPacket()
        {
            var p = new MqttConnAckPacket
            {
                ConnectReturnCode = MqttConnectReturnCode.ConnectionAccepted
            };

            SerializeAndCompare(p, "IAIAAA==", MqttProtocolVersion.V310);
        }
示例#12
0
        public void DeserializeV311_MqttConnAckPacket()
        {
            var p = new MqttConnAckPacket
            {
                IsSessionPresent = true,
                ReturnCode       = MqttConnectReturnCode.ConnectionRefusedNotAuthorized
            };

            DeserializeAndCompare(p, "IAIBBQ==");
        }
示例#13
0
        protected virtual MqttBasePacket DecodeConnAckPacket(IMqttPacketBodyReader body)
        {
            ThrowIfBodyIsEmpty(body);

            var packet = new MqttConnAckPacket();

            body.ReadByte(); // Reserved.
            packet.ReturnCode = (MqttConnectReturnCode)body.ReadByte();

            return(packet);
        }
示例#14
0
        private static byte EncodeConnAckPacket(MqttConnAckPacket packet, IMqttPacketWriter packetWriter)
        {
            if (packet == null)
            {
                throw new ArgumentNullException(nameof(packet));
            }
            if (packetWriter == null)
            {
                throw new ArgumentNullException(nameof(packetWriter));
            }

            if (!packet.ReasonCode.HasValue)
            {
                ThrowReasonCodeNotSetException();
            }

            byte connectAcknowledgeFlags = 0x0;

            if (packet.IsSessionPresent)
            {
                connectAcknowledgeFlags |= 0x1;
            }

            packetWriter.Write(connectAcknowledgeFlags);
            packetWriter.Write((byte)packet.ReasonCode.Value);

            var propertiesWriter = new MqttV500PropertiesWriter();

            if (packet.Properties != null)
            {
                propertiesWriter.WriteSessionExpiryInterval(packet.Properties.SessionExpiryInterval);
                propertiesWriter.WriteAuthenticationMethod(packet.Properties.AuthenticationMethod);
                propertiesWriter.WriteAuthenticationData(packet.Properties.AuthenticationData);
                propertiesWriter.WriteRetainAvailable(packet.Properties.RetainAvailable);
                propertiesWriter.WriteReceiveMaximum(packet.Properties.ReceiveMaximum);
                propertiesWriter.WriteMaximumQoS(packet.Properties.MaximumQoS);
                propertiesWriter.WriteAssignedClientIdentifier(packet.Properties.AssignedClientIdentifier);
                propertiesWriter.WriteTopicAliasMaximum(packet.Properties.TopicAliasMaximum);
                propertiesWriter.WriteReasonString(packet.Properties.ReasonString);
                propertiesWriter.WriteMaximumPacketSize(packet.Properties.MaximumPacketSize);
                propertiesWriter.WriteWildcardSubscriptionAvailable(packet.Properties.WildcardSubscriptionAvailable);
                propertiesWriter.WriteSubscriptionIdentifiersAvailable(packet.Properties.SubscriptionIdentifiersAvailable);
                propertiesWriter.WriteSharedSubscriptionAvailable(packet.Properties.SharedSubscriptionAvailable);
                propertiesWriter.WriteServerKeepAlive(packet.Properties.ServerKeepAlive);
                propertiesWriter.WriteResponseInformation(packet.Properties.ResponseInformation);
                propertiesWriter.WriteServerReference(packet.Properties.ServerReference);
                propertiesWriter.WriteUserProperties(packet.Properties.UserProperties);
            }

            propertiesWriter.WriteTo(packetWriter);

            return(MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.ConnAck));
        }
        public void Serialize_Full_MqttConnAckPacket_V310()
        {
            var connAckPacket = new MqttConnAckPacket
            {
                AuthenticationData               = Encoding.UTF8.GetBytes("AuthenticationData"),
                AuthenticationMethod             = "AuthenticationMethod",
                ReasonCode                       = MqttConnectReasonCode.ServerUnavailable,
                ReasonString                     = "ReasonString",
                ReceiveMaximum                   = 123,
                ResponseInformation              = "ResponseInformation",
                RetainAvailable                  = true,
                ReturnCode                       = MqttConnectReturnCode.ConnectionRefusedNotAuthorized,
                ServerReference                  = "ServerReference",
                AssignedClientIdentifier         = "AssignedClientIdentifier",
                IsSessionPresent                 = true,
                MaximumPacketSize                = 456,
                MaximumQoS                       = MqttQualityOfServiceLevel.ExactlyOnce,
                ServerKeepAlive                  = 789,
                SessionExpiryInterval            = 852,
                SharedSubscriptionAvailable      = true,
                SubscriptionIdentifiersAvailable = true,
                TopicAliasMaximum                = 963,
                WildcardSubscriptionAvailable    = true,
                UserProperties                   = new List <MqttUserProperty>
                {
                    new MqttUserProperty("Foo", "Bar")
                }
            };

            var deserialized = MqttPacketSerializationHelper.EncodeAndDecodePacket(connAckPacket, MqttProtocolVersion.V310);

            CollectionAssert.AreEqual(null, deserialized.AuthenticationData);               // Not supported in v3.1.1
            Assert.AreEqual(null, deserialized.AuthenticationMethod);                       // Not supported in v3.1.1
            //Assert.AreEqual(connAckPacket.ReasonCode, deserialized.ReasonCode);
            Assert.AreEqual(null, deserialized.ReasonString);                               // Not supported in v3.1.1
            Assert.AreEqual(0U, deserialized.ReceiveMaximum);                               // Not supported in v3.1.1
            Assert.AreEqual(null, deserialized.ResponseInformation);                        // Not supported in v3.1.1
            Assert.AreEqual(false, deserialized.RetainAvailable);                           // Not supported in v3.1.1
            Assert.AreEqual(MqttConnectReturnCode.ConnectionRefusedNotAuthorized, deserialized.ReturnCode);
            Assert.AreEqual(null, deserialized.ServerReference);                            // Not supported in v3.1.1
            Assert.AreEqual(null, deserialized.AssignedClientIdentifier);                   // Not supported in v3.1.1
            Assert.AreEqual(false, deserialized.IsSessionPresent);                          // Not supported in v3.1.0 <- !
            Assert.AreEqual(0U, deserialized.MaximumPacketSize);                            // Not supported in v3.1.1
            Assert.AreEqual(MqttQualityOfServiceLevel.AtMostOnce, deserialized.MaximumQoS); // Not supported in v3.1.1
            Assert.AreEqual(0U, deserialized.ServerKeepAlive);                              // Not supported in v3.1.1
            Assert.AreEqual(0U, deserialized.SessionExpiryInterval);                        // Not supported in v3.1.1
            Assert.AreEqual(false, deserialized.SharedSubscriptionAvailable);               // Not supported in v3.1.1
            Assert.AreEqual(false, deserialized.SubscriptionIdentifiersAvailable);          // Not supported in v3.1.1
            Assert.AreEqual(0U, deserialized.TopicAliasMaximum);                            // Not supported in v3.1.1
            Assert.AreEqual(false, deserialized.WildcardSubscriptionAvailable);
            Assert.IsNull(deserialized.UserProperties);                                     // Not supported in v3.1.1
        }
示例#16
0
        private static MqttBasePacket DeserializeConnAck(MqttPacketReader reader)
        {
            var variableHeader1 = reader.ReadByte();
            var variableHeader2 = reader.ReadByte();

            var packet = new MqttConnAckPacket
            {
                IsSessionPresent  = new ByteReader(variableHeader1).Read(),
                ConnectReturnCode = (MqttConnectReturnCode)variableHeader2
            };

            return(packet);
        }
示例#17
0
        MqttPacket DecodeConnAckPacket(ArraySegment <byte> body)
        {
            ThrowIfBodyIsEmpty(body);

            _bufferReader.SetBuffer(body.Array, body.Offset, body.Count);

            var packet = new MqttConnAckPacket();

            _bufferReader.ReadByte(); // Reserved.
            packet.ReturnCode = (MqttConnectReturnCode)_bufferReader.ReadByte();

            return(packet);
        }
示例#18
0
        public MqttClientAuthenticateResult CreateClientConnectResult(MqttConnAckPacket connAckPacket)
        {
            if (connAckPacket == null)
            {
                throw new ArgumentNullException(nameof(connAckPacket));
            }

            return(new MqttClientAuthenticateResult
            {
                IsSessionPresent = connAckPacket.IsSessionPresent,
                ResultCode = (MqttClientConnectResultCode)connAckPacket.ReasonCode.Value
            });
        }
        protected override MqttBasePacket DecodeConnAckPacket(IMqttPacketBodyReader body)
        {
            ThrowIfBodyIsEmpty(body);

            var packet = new MqttConnAckPacket();

            var acknowledgeFlags = body.ReadByte();

            packet.IsSessionPresent = (acknowledgeFlags & 0x1) > 0;
            packet.ReturnCode       = (MqttConnectReturnCode)body.ReadByte();

            return(packet);
        }
        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));
        }
示例#21
0
        private byte Serialize(MqttConnAckPacket packet, MqttPacketWriter writer)
        {
            var connectAcknowledgeFlags = new ByteWriter();

            if (ProtocolVersion == MqttProtocolVersion.V311)
            {
                connectAcknowledgeFlags.Write(packet.IsSessionPresent);
            }

            writer.Write(connectAcknowledgeFlags);
            writer.Write((byte)packet.ConnectReturnCode);

            return(MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.ConnAck));
        }
示例#22
0
        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));
        }
        private async Task <MqttBasePacket> DeserializeConnAck(MqttPacketReader reader)
        {
            var variableHeader1 = await reader.ReadRemainingDataByteAsync();

            var variableHeader2 = await reader.ReadRemainingDataByteAsync();

            var packet = new MqttConnAckPacket
            {
                IsSessionPresent  = new ByteReader(variableHeader1).Read(),
                ConnectReturnCode = (MqttConnectReturnCode)variableHeader2
            };

            return(packet);
        }
        protected override byte EncodeConnAckPacket(MqttConnAckPacket packet, IMqttPacketWriter packetWriter)
        {
            byte connectAcknowledgeFlags = 0x0;

            if (packet.IsSessionPresent)
            {
                connectAcknowledgeFlags |= 0x1;
            }

            packetWriter.Write(connectAcknowledgeFlags);
            packetWriter.Write((byte)packet.ReturnCode);

            return(MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.ConnAck));
        }
        private Task SerializeAsync(MqttConnAckPacket packet, IMqttCommunicationChannel destination)
        {
            using (var output = new MqttPacketWriter())
            {
                var connectAcknowledgeFlags = new ByteWriter();
                connectAcknowledgeFlags.Write(packet.IsSessionPresent);

                output.Write(connectAcknowledgeFlags);
                output.Write((byte)packet.ConnectReturnCode);

                output.InjectFixedHeader(MqttControlPacketType.ConnAck);
                return(output.WriteToAsync(destination));
            }
        }
示例#26
0
        private MqttBasePacket DeserializeConnAck(MqttPacketReader reader)
        {
            var packet = new MqttConnAckPacket();

            var firstByteReader = new ByteReader(reader.ReadByte());

            if (ProtocolVersion == MqttProtocolVersion.V311)
            {
                packet.IsSessionPresent = firstByteReader.Read();
            }

            packet.ConnectReturnCode = (MqttConnectReturnCode)reader.ReadByte();

            return(packet);
        }
示例#27
0
        MqttPacket DecodeConnAckPacketV311(ArraySegment <byte> body)
        {
            ThrowIfBodyIsEmpty(body);

            _bufferReader.SetBuffer(body.Array, body.Offset, body.Count);

            var packet = new MqttConnAckPacket();

            var acknowledgeFlags = _bufferReader.ReadByte();

            packet.IsSessionPresent = (acknowledgeFlags & 0x1) > 0;
            packet.ReturnCode       = (MqttConnectReturnCode)_bufferReader.ReadByte();

            return(packet);
        }
        static MqttClientConnectResult CreateForMqtt311(MqttConnAckPacket connAckPacket)
        {
            if (connAckPacket == null)
            {
                throw new ArgumentNullException(nameof(connAckPacket));
            }

            return(new MqttClientConnectResult
            {
                RetainAvailable = true,               // Always true because v3.1.1 does not have a way to "disable" that feature.
                WildcardSubscriptionAvailable = true, // Always true because v3.1.1 does not have a way to "disable" that feature.
                IsSessionPresent = connAckPacket.IsSessionPresent,
                ResultCode = ConvertReturnCodeToResultCode(connAckPacket.ReturnCode)
            });
        }
示例#29
0
        private MqttBasePacket DeserializeConnAck(MqttPacketBodyReader body)
        {
            ThrowIfBodyIsEmpty(body);

            var packet = new MqttConnAckPacket();

            var acknowledgeFlags = body.ReadByte();

            if (ProtocolVersion == MqttProtocolVersion.V311)
            {
                packet.IsSessionPresent = (acknowledgeFlags & 0x1) > 0;
            }

            packet.ConnectReturnCode = (MqttConnectReturnCode)body.ReadByte();

            return(packet);
        }
        async Task <MqttClient> CreateClientConnection(
            MqttConnectPacket connectPacket,
            MqttConnAckPacket connAckPacket,
            IMqttChannelAdapter channelAdapter,
            ValidatingConnectionEventArgs validatingConnectionEventArgs)
        {
            MqttClient connection;

            bool sessionShouldPersist;

            if (validatingConnectionEventArgs.ProtocolVersion == MqttProtocolVersion.V500)
            {
                // MQTT 5.0 section 3.1.2.11.2
                // The Client and Server MUST store the Session State after the Network Connection is closed if the Session Expiry Interval is greater than 0 [MQTT-3.1.2-23].
                //
                // A Client that only wants to process messages while connected will set the Clean Start to 1 and set the Session Expiry Interval to 0.
                // It will not receive Application Messages published before it connected and has to subscribe afresh to any topics that it is interested
                // in each time it connects.

                // Persist if SessionExpiryInterval != 0, but may start with a clean session
                sessionShouldPersist = validatingConnectionEventArgs.SessionExpiryInterval != 0;
            }
            else
            {
                // MQTT 3.1.1 section 3.1.2.4: persist only if 'not CleanSession'
                //
                // If CleanSession is set to 1, the Client and Server MUST discard any previous Session and start a new one.
                // This Session lasts as long as the Network Connection. State data associated with this Session MUST NOT be
                // reused in any subsequent Session [MQTT-3.1.2-6].

                sessionShouldPersist = !connectPacket.CleanSession;
            }

            using (await _createConnectionSyncRoot.WaitAsync(CancellationToken.None).ConfigureAwait(false))
            {
                MqttSession session;
                lock (_sessionsManagementLock)
                {
                    if (!_sessions.TryGetValue(connectPacket.ClientId, out session))
                    {
                        session = CreateSession(connectPacket.ClientId, validatingConnectionEventArgs.SessionItems, sessionShouldPersist);
                    }
                    else
                    {
                        if (connectPacket.CleanSession)
                        {
                            _logger.Verbose("Deleting existing session of client '{0}'.", connectPacket.ClientId);
                            session = CreateSession(connectPacket.ClientId, validatingConnectionEventArgs.SessionItems, sessionShouldPersist);
                        }
                        else
                        {
                            _logger.Verbose("Reusing existing session of client '{0}'.", connectPacket.ClientId);
                            // Session persistence could change for MQTT 5 clients that reconnect with different SessionExpiryInterval
                            session.IsPersistent           = sessionShouldPersist;
                            connAckPacket.IsSessionPresent = true;
                            session.Recover();
                        }
                    }

                    _sessions[connectPacket.ClientId] = session;
                }

                if (!connAckPacket.IsSessionPresent)
                {
                    // TODO: This event is not yet final. It can already be used but restoring sessions from storage will be added later!
                    var preparingSessionEventArgs = new PreparingSessionEventArgs();
                    await _eventContainer.PreparingSessionEvent.InvokeAsync(preparingSessionEventArgs).ConfigureAwait(false);
                }

                MqttClient existing;

                lock (_clients)
                {
                    _clients.TryGetValue(connectPacket.ClientId, out existing);
                    connection = CreateConnection(connectPacket, channelAdapter, session);

                    _clients[connectPacket.ClientId] = connection;
                }

                if (existing != null)
                {
                    existing.IsTakenOver = true;
                    await existing.StopAsync(MqttDisconnectReasonCode.SessionTakenOver).ConfigureAwait(false);

                    if (_eventContainer.ClientConnectedEvent.HasHandlers)
                    {
                        var eventArgs = new ClientDisconnectedEventArgs
                        {
                            ClientId       = existing.Id,
                            DisconnectType = MqttClientDisconnectType.Takeover,
                            Endpoint       = existing.Endpoint
                        };

                        await _eventContainer.ClientDisconnectedEvent.InvokeAsync(eventArgs).ConfigureAwait(false);
                    }
                }
            }

            return(connection);
        }