예제 #1
0
        public byte[] Serialize(MqttBasePacket packet)
        {
            if (packet == null)
            {
                throw new ArgumentNullException(nameof(packet));
            }

            using (var stream = new MemoryStream())
                using (var writer = new MqttPacketWriter(stream))
                {
                    var fixedHeader  = SerializePacket(packet, writer);
                    var headerBuffer = new List <byte> {
                        fixedHeader
                    };
                    MqttPacketWriter.WriteRemainingLength((int)stream.Length, headerBuffer);

                    var header = headerBuffer.ToArray();
                    var body   = stream.ToArray();

                    var buffer = new byte[header.Length + body.Length];
                    Buffer.BlockCopy(header, 0, buffer, 0, header.Length);
                    Buffer.BlockCopy(body, 0, buffer, header.Length, body.Length);

                    return(buffer);
                }
        }
        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));
            }
        }
예제 #3
0
        private byte SerializePacket(MqttBasePacket packet, MqttPacketWriter writer)
        {
            switch (packet)
            {
            case MqttConnectPacket connectPacket: return(Serialize(connectPacket, writer));

            case MqttConnAckPacket connAckPacket: return(Serialize(connAckPacket, writer));

            case MqttDisconnectPacket _: return(SerializeEmptyPacket(MqttControlPacketType.Disconnect));

            case MqttPingReqPacket _: return(SerializeEmptyPacket(MqttControlPacketType.PingReq));

            case MqttPingRespPacket _: return(SerializeEmptyPacket(MqttControlPacketType.PingResp));

            case MqttPublishPacket publishPacket: return(Serialize(publishPacket, writer));

            case MqttPubAckPacket pubAckPacket: return(Serialize(pubAckPacket, writer));

            case MqttPubRecPacket pubRecPacket: return(Serialize(pubRecPacket, writer));

            case MqttPubRelPacket pubRelPacket: return(Serialize(pubRelPacket, writer));

            case MqttPubCompPacket pubCompPacket: return(Serialize(pubCompPacket, writer));

            case MqttSubscribePacket subscribePacket: return(Serialize(subscribePacket, writer));

            case MqttSubAckPacket subAckPacket: return(Serialize(subAckPacket, writer));

            case MqttUnsubscribePacket unsubscribePacket: return(Serialize(unsubscribePacket, writer));

            case MqttUnsubAckPacket unsubAckPacket: return(Serialize(unsubAckPacket, writer));

            default: throw new MqttProtocolViolationException("Packet type invalid.");
            }
        }
예제 #4
0
        private byte Serialize(MqttConnectPacket packet, MqttPacketWriter writer)
        {
            ValidateConnectPacket(packet);

            // Write variable header
            writer.Write(0x00, 0x04); // 3.1.2.1 Protocol Name
            if (ProtocolVersion == MqttProtocolVersion.V311)
            {
                writer.Write(ProtocolVersionV311Name);
                writer.Write(0x04); // 3.1.2.2 Protocol Level (4)
            }
            else
            {
                writer.Write(ProtocolVersionV310Name);
                writer.Write(0x64, 0x70, 0x03); // Protocol Level (0x03)
            }

            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);

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

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

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

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

            return(MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.Connect));
        }
 private Task SerializeEmptyPacketAsync(MqttControlPacketType type, IMqttCommunicationChannel destination)
 {
     using (var output = new MqttPacketWriter())
     {
         output.InjectFixedHeader(type);
         return(output.WriteToAsync(destination));
     }
 }
        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));
            }
        }
예제 #9
0
        private static byte Serialize(MqttSubAckPacket packet, MqttPacketWriter writer)
        {
            writer.Write(packet.PacketIdentifier);

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

            return(MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.SubAck));
        }
예제 #10
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));
        }
        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(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(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));
            }
        }
예제 #14
0
        private static byte Serialize(MqttUnsubscribePacket packet, MqttPacketWriter writer)
        {
            if (!packet.TopicFilters.Any())
            {
                throw new MqttProtocolViolationException("At least one topic filter must be set [MQTT-3.10.3-2].");
            }

            writer.Write(packet.PacketIdentifier);

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

            return(MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.Unsubscibe, 0x02));
        }
        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));
            }
        }
예제 #16
0
        private static byte Serialize(MqttSubscribePacket packet, MqttPacketWriter writer)
        {
            if (!packet.TopicFilters.Any())
            {
                throw new MqttProtocolViolationException("At least one topic filter must be set [MQTT-3.8.3-3].");
            }

            writer.Write(packet.PacketIdentifier);

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

            return(MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.Subscribe, 0x02));
        }
예제 #17
0
        private static byte Serialize(MqttPublishPacket packet, MqttPacketWriter writer)
        {
            ValidatePublishPacket(packet);

            writer.WriteWithLengthPrefix(packet.Topic);

            if (packet.QualityOfServiceLevel > MqttQualityOfServiceLevel.AtMostOnce)
            {
                writer.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)
            {
                writer.Write(packet.Payload);
            }

            byte fixedHeader = 0;

            if (packet.Retain)
            {
                fixedHeader |= 0x01;
            }

            fixedHeader |= (byte)((byte)packet.QualityOfServiceLevel << 1);

            if (packet.Dup)
            {
                fixedHeader |= 0x08;
            }

            return(MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.Publish, fixedHeader));
        }
예제 #18
0
        public byte[] Serialize(MqttBasePacket packet)
        {
            if (packet == null)
            {
                throw new ArgumentNullException(nameof(packet));
            }

            using (var stream = new MemoryStream())
                using (var writer = new MqttPacketWriter(stream))
                {
                    var header = new List <byte> {
                        SerializePacket(packet, writer)
                    };
                    var body = stream.ToArray();
                    MqttPacketWriter.BuildLengthHeader(body.Length, header);
                    var headerArray = header.ToArray();
                    var writeBuffer = new byte[header.Count + body.Length];
                    Buffer.BlockCopy(headerArray, 0, writeBuffer, 0, headerArray.Length);
                    Buffer.BlockCopy(body, 0, writeBuffer, headerArray.Length, body.Length);

                    return(writeBuffer);
                }
        }
예제 #19
0
 private static byte Serialize(MqttPingRespPacket packet, MqttPacketWriter writer)
 {
     return(SerializeEmptyPacketAsync(MqttControlPacketType.PingResp, writer));
 }
예제 #20
0
 private static byte SerializeEmptyPacket(MqttControlPacketType type)
 {
     return(MqttPacketWriter.BuildFixedHeader(type));
 }
예제 #21
0
 private static byte Serialize(IMqttPacketWithIdentifier packet, BinaryWriter writer)
 {
     writer.Write(packet.PacketIdentifier);
     return(MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.UnsubAck));
 }
예제 #22
0
        private static byte Serialize(MqttPubCompPacket packet, MqttPacketWriter writer)
        {
            writer.Write(packet.PacketIdentifier);

            return(MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.PubComp));
        }
예제 #23
0
        private byte SerializePacket(MqttBasePacket packet, MqttPacketWriter writer)
        {
            if (packet is MqttConnectPacket connectPacket)
            {
                return(Serialize(connectPacket, writer));
            }

            if (packet is MqttConnAckPacket connAckPacket)
            {
                return(Serialize(connAckPacket, writer));
            }

            if (packet is MqttDisconnectPacket disconnectPacket)
            {
                return(Serialize(disconnectPacket, writer));
            }

            if (packet is MqttPingReqPacket pingReqPacket)
            {
                return(Serialize(pingReqPacket, writer));
            }

            if (packet is MqttPingRespPacket pingRespPacket)
            {
                return(Serialize(pingRespPacket, writer));
            }

            if (packet is MqttPublishPacket publishPacket)
            {
                return(Serialize(publishPacket, writer));
            }

            if (packet is MqttPubAckPacket pubAckPacket)
            {
                return(Serialize(pubAckPacket, writer));
            }

            if (packet is MqttPubRecPacket pubRecPacket)
            {
                return(Serialize(pubRecPacket, writer));
            }

            if (packet is MqttPubRelPacket pubRelPacket)
            {
                return(Serialize(pubRelPacket, writer));
            }

            if (packet is MqttPubCompPacket pubCompPacket)
            {
                return(Serialize(pubCompPacket, writer));
            }

            if (packet is MqttSubscribePacket subscribePacket)
            {
                return(Serialize(subscribePacket, writer));
            }

            if (packet is MqttSubAckPacket subAckPacket)
            {
                return(Serialize(subAckPacket, writer));
            }

            if (packet is MqttUnsubscribePacket unsubscribePacket)
            {
                return(Serialize(unsubscribePacket, writer));
            }

            if (packet is MqttUnsubAckPacket unsubAckPacket)
            {
                return(Serialize(unsubAckPacket, writer));
            }

            throw new MqttProtocolViolationException("Packet type invalid.");
        }
예제 #24
0
 private static byte Serialize(MqttDisconnectPacket packet, MqttPacketWriter writer)
 {
     return(SerializeEmptyPacketAsync(MqttControlPacketType.Disconnect, writer));
 }