예제 #1
0
        public async Task <MqttUnsubAckPacket> UnsubscribeAsync(MqttUnsubscribePacket unsubscribePacket)
        {
            if (unsubscribePacket == null)
            {
                throw new ArgumentNullException(nameof(unsubscribePacket));
            }

            var unsubAckPacket = new MqttUnsubAckPacket
            {
                PacketIdentifier = unsubscribePacket.PacketIdentifier
            };

            lock (_subscriptions)
            {
                foreach (var topicFilter in unsubscribePacket.TopicFilters)
                {
                    if (_subscriptions.Remove(topicFilter))
                    {
                        unsubAckPacket.ReasonCodes.Add(MqttUnsubscribeReasonCode.Success);
                    }
                    else
                    {
                        unsubAckPacket.ReasonCodes.Add(MqttUnsubscribeReasonCode.NoSubscriptionExisted);
                    }
                }
            }

            foreach (var topicFilter in unsubscribePacket.TopicFilters)
            {
                await _eventDispatcher.HandleClientUnsubscribedTopicAsync(_clientId, topicFilter).ConfigureAwait(false);
            }

            return(unsubAckPacket);
        }
예제 #2
0
        private static byte EncodeUnsubAckPacket(MqttUnsubAckPacket packet, IMqttPacketWriter packetWriter)
        {
            if (packet.ReasonCodes?.Any() != true)
            {
                throw new MqttProtocolViolationException("At least one reason code must be set[MQTT - 3.8.3 - 3].");
            }

            ThrowIfPacketIdentifierIsInvalid(packet);

            packetWriter.Write(packet.PacketIdentifier.Value);

            var propertiesWriter = new MqttV500PropertiesWriter();

            if (packet.Properties != null)
            {
                propertiesWriter.WriteReasonString(packet.Properties.ReasonString);
                propertiesWriter.WriteUserProperties(packet.Properties.UserProperties);
            }

            propertiesWriter.WriteTo(packetWriter);

            foreach (var reasonCode in packet.ReasonCodes)
            {
                packetWriter.Write((byte)reasonCode);
            }

            return(MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.UnsubAck));
        }
예제 #3
0
        public void DeserializeV311_MqttUnsubAckPacket()
        {
            var p = new MqttUnsubAckPacket
            {
                PacketIdentifier = 123
            };

            DeserializeAndCompare(p, "sAIAew==");
        }
        private Task SerializeAsync(MqttUnsubAckPacket packet, IMqttCommunicationChannel destination)
        {
            using (var output = new MqttPacketWriter())
            {
                output.Write(packet.PacketIdentifier);

                output.InjectFixedHeader(MqttControlPacketType.UnsubAck);
                return(output.WriteToAsync(destination));
            }
        }
예제 #5
0
        static byte EncodeUnsubAckPacket(MqttUnsubAckPacket packet, IMqttPacketWriter packetWriter)
        {
            if (!packet.PacketIdentifier.HasValue)
            {
                throw new MqttProtocolViolationException("UnsubAck packet has no packet identifier.");
            }

            packetWriter.Write(packet.PacketIdentifier.Value);
            return(MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.UnsubAck));
        }
예제 #6
0
        private static byte Serialize(MqttUnsubAckPacket packet, BinaryWriter writer)
        {
            if (!packet.PacketIdentifier.HasValue)
            {
                throw new MqttProtocolViolationException("UnsubAck packet has no packet identifier.");
            }

            writer.Write(packet.PacketIdentifier.Value);
            return(MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.UnsubAck));
        }
예제 #7
0
        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));
        }
예제 #8
0
        private static MqttBasePacket DecodeUnsubAckPacket(IMqttPacketBodyReader body)
        {
            ThrowIfBodyIsEmpty(body);

            var packet = new MqttUnsubAckPacket
            {
                PacketIdentifier = body.ReadTwoByteInteger()
            };

            var propertiesReader = new MqttV500PropertiesReader(body);

            while (propertiesReader.MoveNext())
            {
                if (packet.Properties == null)
                {
                    packet.Properties = new MqttUnsubAckPacketProperties();
                }

                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(MqttUnsubAckPacket));
                }
            }

            while (!body.EndOfStream)
            {
                var reasonCode = (MqttUnsubscribeReasonCode)body.ReadByte();
                packet.ReasonCodes.Add(reasonCode);
            }

            return(packet);
        }
예제 #9
0
        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));
        }
예제 #10
0
        public async Task <MqttUnsubAckPacket> UnsubscribeAsync(MqttUnsubscribePacket unsubscribePacket)
        {
            if (unsubscribePacket == null)
            {
                throw new ArgumentNullException(nameof(unsubscribePacket));
            }

            var unsubAckPacket = new MqttUnsubAckPacket
            {
                PacketIdentifier = unsubscribePacket.PacketIdentifier
            };

            foreach (var topicFilter in unsubscribePacket.TopicFilters)
            {
                var interceptorContext = await InterceptUnsubscribeAsync(topicFilter).ConfigureAwait(false);

                if (!interceptorContext.AcceptUnsubscription)
                {
                    unsubAckPacket.ReasonCodes.Add(MqttUnsubscribeReasonCode.ImplementationSpecificError);
                    continue;
                }

                lock (_subscriptions)
                {
                    if (_subscriptions.Remove(topicFilter))
                    {
                        unsubAckPacket.ReasonCodes.Add(MqttUnsubscribeReasonCode.Success);
                    }
                    else
                    {
                        unsubAckPacket.ReasonCodes.Add(MqttUnsubscribeReasonCode.NoSubscriptionExisted);
                    }
                }
            }

            foreach (var topicFilter in unsubscribePacket.TopicFilters)
            {
                await _eventDispatcher.SafeNotifyClientUnsubscribedTopicAsync(_clientSession.ClientId, topicFilter).ConfigureAwait(false);
            }

            return(unsubAckPacket);
        }
        public MqttUnsubAckPacket Create(MqttUnsubscribePacket unsubscribePacket, MqttUnsubscribeResult mqttUnsubscribeResult)
        {
            if (unsubscribePacket == null)
            {
                throw new ArgumentNullException(nameof(unsubscribePacket));
            }

            if (mqttUnsubscribeResult == null)
            {
                throw new ArgumentNullException(nameof(mqttUnsubscribeResult));
            }

            var unsubAckPacket = new MqttUnsubAckPacket
            {
                PacketIdentifier = unsubscribePacket.PacketIdentifier
            };

            // MQTTv5.0.0 only.
            unsubAckPacket.ReasonCodes = mqttUnsubscribeResult.ReasonCodes;

            return(unsubAckPacket);
        }
        public void Serialize_Full_MqttUnsubAckPacket_V311()
        {
            var unsubAckPacket = new MqttUnsubAckPacket
            {
                PacketIdentifier = 123,
                ReasonCodes      = new List <MqttUnsubscribeReasonCode>
                {
                    MqttUnsubscribeReasonCode.ImplementationSpecificError
                },
                ReasonString   = "ReasonString",
                UserProperties = new List <MqttUserProperty>
                {
                    new MqttUserProperty("Foo", "Bar")
                }
            };

            var deserialized = MqttPacketSerializationHelper.EncodeAndDecodePacket(unsubAckPacket, MqttProtocolVersion.V311);

            Assert.AreEqual(unsubAckPacket.PacketIdentifier, deserialized.PacketIdentifier);
            Assert.AreEqual(null, deserialized.ReasonString);             // Not supported in v3.1.1
            CollectionAssert.AreEqual(null, deserialized.ReasonCodes);    // Not supported in v3.1.1
            CollectionAssert.AreEqual(null, deserialized.UserProperties); // Not supported in v3.1.1
        }
예제 #13
0
        MqttPacket DecodeUnsubAckPacket(ArraySegment <byte> body)
        {
            ThrowIfBodyIsEmpty(body);

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

            var packet = new MqttUnsubAckPacket
            {
                PacketIdentifier = _bufferReader.ReadTwoByteInteger()
            };

            var propertiesReader = new MqttV5PropertiesReader(_bufferReader);

            while (propertiesReader.MoveNext())
            {
                if (propertiesReader.CurrentPropertyId == MqttPropertyId.ReasonString)
                {
                    packet.ReasonString = propertiesReader.ReadReasonString();
                }
                else
                {
                    propertiesReader.ThrowInvalidPropertyIdException(typeof(MqttUnsubAckPacket));
                }
            }

            packet.UserProperties = propertiesReader.CollectedUserProperties;

            packet.ReasonCodes = new List <MqttUnsubscribeReasonCode>(_bufferReader.BytesLeft);

            while (!_bufferReader.EndOfStream)
            {
                var reasonCode = (MqttUnsubscribeReasonCode)_bufferReader.ReadByte();
                packet.ReasonCodes.Add(reasonCode);
            }

            return(packet);
        }
예제 #14
0
        public void Serialize_Full_MqttUnsubAckPacket_V500()
        {
            var unsubAckPacket = new MqttUnsubAckPacket
            {
                PacketIdentifier = 123,
                ReasonCodes      = new List <MqttUnsubscribeReasonCode>
                {
                    MqttUnsubscribeReasonCode.ImplementationSpecificError
                },
                ReasonString   = "ReasonString",
                UserProperties = new List <MqttUserProperty>
                {
                    new MqttUserProperty("Foo", "Bar")
                }
            };

            var deserialized = MqttPacketSerializationHelper.EncodeAndDecodePacket(unsubAckPacket, MqttProtocolVersion.V500);

            Assert.AreEqual(unsubAckPacket.PacketIdentifier, deserialized.PacketIdentifier);
            Assert.AreEqual(unsubAckPacket.ReasonString, deserialized.ReasonString);
            Assert.AreEqual(unsubAckPacket.ReasonCodes.Count, deserialized.ReasonCodes.Count);
            Assert.AreEqual(unsubAckPacket.ReasonCodes[0], deserialized.ReasonCodes[0]);
            CollectionAssert.AreEqual(unsubAckPacket.UserProperties, deserialized.UserProperties);
        }
예제 #15
0
        public MqttClientUnsubscribeResult Create(MqttUnsubscribePacket unsubscribePacket, MqttUnsubAckPacket unsubAckPacket)
        {
            if (unsubscribePacket == null)
            {
                throw new ArgumentNullException(nameof(unsubscribePacket));
            }
            if (unsubAckPacket == null)
            {
                throw new ArgumentNullException(nameof(unsubAckPacket));
            }

            // MQTTv3.1.1 has no reason code at all!
            if (unsubAckPacket.ReasonCodes != null && unsubAckPacket.ReasonCodes.Count != unsubscribePacket.TopicFilters.Count)
            {
                throw new MqttProtocolViolationException(
                          "The return codes are not matching the topic filters [MQTT-3.9.3-1].");
            }

            var items = new List <MqttClientUnsubscribeResultItem>();

            for (var i = 0; i < unsubscribePacket.TopicFilters.Count; i++)
            {
                items.Add(CreateUnsubscribeResultItem(i, unsubscribePacket, unsubAckPacket));
            }

            var result = new MqttClientUnsubscribeResult
            {
                PacketIdentifier = unsubAckPacket.PacketIdentifier,
                ReasonString     = unsubAckPacket.ReasonString,
                UserProperties   = unsubAckPacket.UserProperties ?? EmptyUserProperties,
                Items            = items
            };

            return(result);
        }
예제 #16
0
        public MqttClientUnsubscribeResult CreateClientUnsubscribeResult(MqttUnsubscribePacket unsubscribePacket, MqttUnsubAckPacket unsubAckPacket)
        {
            if (unsubscribePacket == null)
            {
                throw new ArgumentNullException(nameof(unsubscribePacket));
            }
            if (unsubAckPacket == null)
            {
                throw new ArgumentNullException(nameof(unsubAckPacket));
            }

            var result = new MqttClientUnsubscribeResult();

            result.Items.AddRange(unsubscribePacket.TopicFilters.Select((t, i) =>
                                                                        new MqttClientUnsubscribeResultItem(t, MqttClientUnsubscribeResultCode.Success)));

            return(result);
        }
예제 #17
0
        private static byte Serialize(MqttUnsubAckPacket packet, MqttPacketWriter writer)
        {
            writer.Write(packet.PacketIdentifier);

            return(MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.UnsubAck));
        }
예제 #18
0
        public MqttClientUnsubscribeResult CreateClientUnsubscribeResult(MqttUnsubscribePacket unsubscribePacket, MqttUnsubAckPacket unsubAckPacket)
        {
            if (unsubscribePacket == null)
            {
                throw new ArgumentNullException(nameof(unsubscribePacket));
            }
            if (unsubAckPacket == null)
            {
                throw new ArgumentNullException(nameof(unsubAckPacket));
            }

            if (unsubAckPacket.ReasonCodes.Count != unsubscribePacket.TopicFilters.Count)
            {
                throw new MqttProtocolViolationException("The return codes are not matching the topic filters [MQTT-3.9.3-1].");
            }

            var result = new MqttClientUnsubscribeResult();

            result.Items.AddRange(unsubscribePacket.TopicFilters.Select((t, i) =>
                                                                        new MqttClientUnsubscribeResultItem(t, (MqttClientUnsubscribeResultCode)unsubAckPacket.ReasonCodes[i])));

            return(result);
        }
예제 #19
0
        static MqttClientUnsubscribeResultItem CreateUnsubscribeResultItem(int index, MqttUnsubscribePacket unsubscribePacket, MqttUnsubAckPacket unsubAckPacket)
        {
            var resultCode = MqttClientUnsubscribeResultCode.Success;

            if (unsubAckPacket.ReasonCodes != null)
            {
                // MQTTv3.1.1 has no reason code and no return code!.
                resultCode = (MqttClientUnsubscribeResultCode)unsubAckPacket.ReasonCodes[index];
            }

            return(new MqttClientUnsubscribeResultItem
            {
                TopicFilter = unsubscribePacket.TopicFilters[index],
                ResultCode = resultCode
            });
        }