private Task SerializeAsync(MqttPublishPacket packet, IMqttCommunicationChannel destination)
        {
            ValidatePublishPacket(packet);

            using (var output = new MqttPacketWriter())
            {
                output.WriteWithLengthPrefix(packet.Topic);

                if (packet.QualityOfServiceLevel > MqttQualityOfServiceLevel.AtMostOnce)
                {
                    output.Write(packet.PacketIdentifier);
                }
                else
                {
                    if (packet.PacketIdentifier > 0)
                    {
                        throw new MqttProtocolViolationException("Packet identifier must be empty if QoS == 0 [MQTT-2.3.1-5].");
                    }
                }

                if (packet.Payload?.Length > 0)
                {
                    output.Write(packet.Payload);
                }

                var fixedHeader = new ByteWriter();
                fixedHeader.Write(packet.Retain);
                fixedHeader.Write((byte)packet.QualityOfServiceLevel, 2);
                fixedHeader.Write(packet.Dup);

                output.InjectFixedHeader(MqttControlPacketType.Publish, fixedHeader.Value);
                return(output.WriteToAsync(destination));
            }
        }
예제 #2
0
        public IMqttCommunicationAdapter CreateServerCommunicationAdapter(IMqttCommunicationChannel channel)
        {
            var serializer = _serviceProvider.GetRequiredService <IMqttPacketSerializer>();
            var logger     = _serviceProvider.GetRequiredService <ILogger <MqttChannelCommunicationAdapter> >();

            return(new MqttChannelCommunicationAdapter(channel, serializer, logger));
        }
 private Task SerializeEmptyPacketAsync(MqttControlPacketType type, IMqttCommunicationChannel destination)
 {
     using (var output = new MqttPacketWriter())
     {
         output.InjectFixedHeader(type);
         return(output.WriteToAsync(destination));
     }
 }
예제 #4
0
        public Task WriteToAsync(IMqttCommunicationChannel destination)
        {
            if (destination == null)
            {
                throw new ArgumentNullException(nameof(destination));
            }

            return(destination.WriteAsync(_buffer.ToArray()));
        }
        private async Task SerializeAsync(MqttPubRelPacket packet, IMqttCommunicationChannel destination)
        {
            using (var output = new MqttPacketWriter())
            {
                output.Write(packet.PacketIdentifier);

                output.InjectFixedHeader(MqttControlPacketType.PubRel, 0x02);
                await output.WriteToAsync(destination);
            }
        }
        private Task SerializeAsync(MqttUnsubAckPacket packet, IMqttCommunicationChannel destination)
        {
            using (var output = new MqttPacketWriter())
            {
                output.Write(packet.PacketIdentifier);

                output.InjectFixedHeader(MqttControlPacketType.UnsubAck);
                return(output.WriteToAsync(destination));
            }
        }
        private Task SerializeAsync(MqttConnectPacket packet, IMqttCommunicationChannel destination)
        {
            ValidateConnectPacket(packet);

            using (var output = new MqttPacketWriter())
            {
                // Write variable header
                output.Write(0x00, 0x04);            // 3.1.2.1 Protocol Name
                output.Write(MqttPrefix);
                output.Write(0x04);                  // 3.1.2.2 Protocol Level

                var connectFlags = new ByteWriter(); // 3.1.2.3 Connect Flags
                connectFlags.Write(false);           // Reserved
                connectFlags.Write(packet.CleanSession);
                connectFlags.Write(packet.WillMessage != null);

                if (packet.WillMessage != null)
                {
                    connectFlags.Write((int)packet.WillMessage.QualityOfServiceLevel, 2);
                    connectFlags.Write(packet.WillMessage.Retain);
                }
                else
                {
                    connectFlags.Write(0, 2);
                    connectFlags.Write(false);
                }

                connectFlags.Write(packet.Password != null);
                connectFlags.Write(packet.Username != null);

                output.Write(connectFlags);
                output.Write(packet.KeepAlivePeriod);
                output.WriteWithLengthPrefix(packet.ClientId);

                if (packet.WillMessage != null)
                {
                    output.WriteWithLengthPrefix(packet.WillMessage.Topic);
                    output.WriteWithLengthPrefix(packet.WillMessage.Payload);
                }

                if (packet.Username != null)
                {
                    output.WriteWithLengthPrefix(packet.Username);
                }

                if (packet.Password != null)
                {
                    output.WriteWithLengthPrefix(packet.Password);
                }

                output.InjectFixedHeader(MqttControlPacketType.Connect);
                return(output.WriteToAsync(destination));
            }
        }
        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));
            }
        }
        private Task SerializeAsync(MqttUnsubscribePacket packet, IMqttCommunicationChannel destination)
        {
            using (var output = new MqttPacketWriter())
            {
                output.Write(packet.PacketIdentifier);

                if (packet.TopicFilters?.Any() == true)
                {
                    foreach (var topicFilter in packet.TopicFilters)
                    {
                        output.WriteWithLengthPrefix(topicFilter);
                    }
                }

                output.InjectFixedHeader(MqttControlPacketType.Unsubscibe, 0x02);
                return(output.WriteToAsync(destination));
            }
        }
        private Task SerializeAsync(MqttSubAckPacket packet, IMqttCommunicationChannel destination)
        {
            using (var output = new MqttPacketWriter())
            {
                output.Write(packet.PacketIdentifier);

                if (packet.SubscribeReturnCodes?.Any() == true)
                {
                    foreach (var packetSubscribeReturnCode in packet.SubscribeReturnCodes)
                    {
                        output.Write((byte)packetSubscribeReturnCode);
                    }
                }

                output.InjectFixedHeader(MqttControlPacketType.SubAck);
                return(output.WriteToAsync(destination));
            }
        }
        private Task SerializeAsync(MqttSubscribePacket packet, IMqttCommunicationChannel destination)
        {
            using (var output = new MqttPacketWriter())
            {
                output.Write(packet.PacketIdentifier);

                if (packet.TopicFilters?.Count > 0)
                {
                    foreach (var topicFilter in packet.TopicFilters)
                    {
                        output.WriteWithLengthPrefix(topicFilter.Topic);
                        output.Write((byte)topicFilter.QualityOfServiceLevel);
                    }
                }

                output.InjectFixedHeader(MqttControlPacketType.Subscribe, 0x02);
                return(output.WriteToAsync(destination));
            }
        }
예제 #12
0
 public MqttPacketReader(IMqttCommunicationChannel source)
 {
     _source = source ?? throw new ArgumentNullException(nameof(source));
 }
        private Task _sendTask = Task.FromResult(0); // this task is used to prevent overlapping write

        public MqttChannelCommunicationAdapter(IMqttCommunicationChannel channel, IMqttPacketSerializer serializer)
        {
            _channel         = channel ?? throw new ArgumentNullException(nameof(channel));
            PacketSerializer = serializer ?? throw new ArgumentNullException(nameof(serializer));
        }
 public IMqttCommunicationAdapter CreateServerCommunicationAdapter(IMqttCommunicationChannel channel)
 {
     return(_adapter);
 }
        public async Task <MqttBasePacket> DeserializeAsync(IMqttCommunicationChannel source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            using (var mqttPacketReader = new MqttPacketReader(source))
            {
                await mqttPacketReader.ReadToEndAsync();

                switch (mqttPacketReader.ControlPacketType)
                {
                case MqttControlPacketType.Connect:
                {
                    return(await DeserializeConnectAsync(mqttPacketReader));
                }

                case MqttControlPacketType.ConnAck:
                {
                    return(await DeserializeConnAck(mqttPacketReader));
                }

                case MqttControlPacketType.Disconnect:
                {
                    return(new MqttDisconnectPacket());
                }

                case MqttControlPacketType.Publish:
                {
                    return(await DeserializePublishAsync(mqttPacketReader));
                }

                case MqttControlPacketType.PubAck:
                {
                    return(new MqttPubAckPacket
                        {
                            PacketIdentifier = await mqttPacketReader.ReadRemainingDataUShortAsync()
                        });
                }

                case MqttControlPacketType.PubRec:
                {
                    return(new MqttPubRecPacket
                        {
                            PacketIdentifier = await mqttPacketReader.ReadRemainingDataUShortAsync()
                        });
                }

                case MqttControlPacketType.PubRel:
                {
                    return(new MqttPubRelPacket
                        {
                            PacketIdentifier = await mqttPacketReader.ReadRemainingDataUShortAsync()
                        });
                }

                case MqttControlPacketType.PubComp:
                {
                    return(new MqttPubCompPacket
                        {
                            PacketIdentifier = await mqttPacketReader.ReadRemainingDataUShortAsync()
                        });
                }

                case MqttControlPacketType.PingReq:
                {
                    return(new MqttPingReqPacket());
                }

                case MqttControlPacketType.PingResp:
                {
                    return(new MqttPingRespPacket());
                }

                case MqttControlPacketType.Subscribe:
                {
                    return(await DeserializeSubscribeAsync(mqttPacketReader));
                }

                case MqttControlPacketType.SubAck:
                {
                    return(await DeserializeSubAck(mqttPacketReader));
                }

                case MqttControlPacketType.Unsubscibe:
                {
                    return(await DeserializeUnsubscribeAsync(mqttPacketReader));
                }

                case MqttControlPacketType.UnsubAck:
                {
                    return(new MqttUnsubAckPacket
                        {
                            PacketIdentifier = await mqttPacketReader.ReadRemainingDataUShortAsync()
                        });
                }

                default:
                {
                    throw new MqttProtocolViolationException($"Packet type ({(int)mqttPacketReader.ControlPacketType}) not supported.");
                }
                }
            }
        }
        public Task SerializeAsync(MqttBasePacket packet, IMqttCommunicationChannel destination)
        {
            if (packet == null)
            {
                throw new ArgumentNullException(nameof(packet));
            }
            if (destination == null)
            {
                throw new ArgumentNullException(nameof(destination));
            }

            var connectPacket = packet as MqttConnectPacket;

            if (connectPacket != null)
            {
                return(SerializeAsync(connectPacket, destination));
            }

            var connAckPacket = packet as MqttConnAckPacket;

            if (connAckPacket != null)
            {
                return(SerializeAsync(connAckPacket, destination));
            }

            var disconnectPacket = packet as MqttDisconnectPacket;

            if (disconnectPacket != null)
            {
                return(SerializeAsync(disconnectPacket, destination));
            }

            var pingReqPacket = packet as MqttPingReqPacket;

            if (pingReqPacket != null)
            {
                return(SerializeAsync(pingReqPacket, destination));
            }

            var pingRespPacket = packet as MqttPingRespPacket;

            if (pingRespPacket != null)
            {
                return(SerializeAsync(pingRespPacket, destination));
            }

            var publishPacket = packet as MqttPublishPacket;

            if (publishPacket != null)
            {
                return(SerializeAsync(publishPacket, destination));
            }

            var pubAckPacket = packet as MqttPubAckPacket;

            if (pubAckPacket != null)
            {
                return(SerializeAsync(pubAckPacket, destination));
            }

            var pubRecPacket = packet as MqttPubRecPacket;

            if (pubRecPacket != null)
            {
                return(SerializeAsync(pubRecPacket, destination));
            }

            var pubRelPacket = packet as MqttPubRelPacket;

            if (pubRelPacket != null)
            {
                return(SerializeAsync(pubRelPacket, destination));
            }

            var pubCompPacket = packet as MqttPubCompPacket;

            if (pubCompPacket != null)
            {
                return(SerializeAsync(pubCompPacket, destination));
            }

            var subscribePacket = packet as MqttSubscribePacket;

            if (subscribePacket != null)
            {
                return(SerializeAsync(subscribePacket, destination));
            }

            var subAckPacket = packet as MqttSubAckPacket;

            if (subAckPacket != null)
            {
                return(SerializeAsync(subAckPacket, destination));
            }

            var unsubscribePacket = packet as MqttUnsubscribePacket;

            if (unsubscribePacket != null)
            {
                return(SerializeAsync(unsubscribePacket, destination));
            }

            var unsubAckPacket = packet as MqttUnsubAckPacket;

            if (unsubAckPacket != null)
            {
                return(SerializeAsync(unsubAckPacket, destination));
            }

            throw new MqttProtocolViolationException("Packet type invalid.");
        }
 private Task SerializeAsync(MqttPingRespPacket packet, IMqttCommunicationChannel destination)
 {
     return(SerializeEmptyPacketAsync(MqttControlPacketType.PingResp, destination));
 }
 private Task SerializeAsync(MqttDisconnectPacket packet, IMqttCommunicationChannel destination)
 {
     return(SerializeEmptyPacketAsync(MqttControlPacketType.Disconnect, destination));
 }