Example #1
0
        Packet DecodePacketInternal(IByteBuffer buffer, int packetSignature, ref int remainingLength, IChannelHandlerContext context)
        {
            if (Signatures.IsPublish(packetSignature))
            {
                var qualityOfService = (QualityOfService)((packetSignature >> 1) & 0x3); // take bits #1 and #2 ONLY and convert them into QoS value
                if (qualityOfService == QualityOfService.Reserved)
                {
                    throw new DecoderException($"Unexpected QoS value of {(int)qualityOfService} for {PacketType.PUBLISH} packet.");
                }

                bool duplicate = (packetSignature & 0x8) == 0x8; // test bit#3
                bool retain    = (packetSignature & 0x1) != 0;   // test bit#0
                var  packet    = new PublishPacket(qualityOfService, duplicate, retain);
                DecodePublishPacket(buffer, packet, ref remainingLength);
                return(packet);
            }

            switch (packetSignature) // strict match checks for valid message type + correct values in flags part
            {
            case Signatures.PubAck:
                var pubAckPacket = new PubAckPacket();
                DecodePacketIdVariableHeader(buffer, pubAckPacket, ref remainingLength);
                return(pubAckPacket);

            case Signatures.PubRec:
                var pubRecPacket = new PubRecPacket();
                DecodePacketIdVariableHeader(buffer, pubRecPacket, ref remainingLength);
                return(pubRecPacket);

            case Signatures.PubRel:
                var pubRelPacket = new PubRelPacket();
                DecodePacketIdVariableHeader(buffer, pubRelPacket, ref remainingLength);
                return(pubRelPacket);

            case Signatures.PubComp:
                var pubCompPacket = new PubCompPacket();
                DecodePacketIdVariableHeader(buffer, pubCompPacket, ref remainingLength);
                return(pubCompPacket);

            case Signatures.PingReq:
                this.ValidateServerPacketExpected(packetSignature);
                return(PingReqPacket.Instance);

            case Signatures.Subscribe:
                this.ValidateServerPacketExpected(packetSignature);
                var subscribePacket = new SubscribePacket();
                DecodePacketIdVariableHeader(buffer, subscribePacket, ref remainingLength);
                DecodeSubscribePayload(buffer, subscribePacket, ref remainingLength);
                return(subscribePacket);

            case Signatures.Unsubscribe:
                this.ValidateServerPacketExpected(packetSignature);
                var unsubscribePacket = new UnsubscribePacket();
                DecodePacketIdVariableHeader(buffer, unsubscribePacket, ref remainingLength);
                DecodeUnsubscribePayload(buffer, unsubscribePacket, ref remainingLength);
                return(unsubscribePacket);

            case Signatures.Connect:
                this.ValidateServerPacketExpected(packetSignature);
                var connectPacket = new ConnectPacket();
                DecodeConnectPacket(buffer, connectPacket, ref remainingLength, context);
                return(connectPacket);

            case Signatures.Disconnect:
                this.ValidateServerPacketExpected(packetSignature);
                return(DisconnectPacket.Instance);

            case Signatures.ConnAck:
                this.ValidateClientPacketExpected(packetSignature);
                var connAckPacket = new ConnAckPacket();
                DecodeConnAckPacket(buffer, connAckPacket, ref remainingLength);
                return(connAckPacket);

            case Signatures.SubAck:
                this.ValidateClientPacketExpected(packetSignature);
                var subAckPacket = new SubAckPacket();
                DecodePacketIdVariableHeader(buffer, subAckPacket, ref remainingLength);
                DecodeSubAckPayload(buffer, subAckPacket, ref remainingLength);
                return(subAckPacket);

            case Signatures.UnsubAck:
                this.ValidateClientPacketExpected(packetSignature);
                var unsubAckPacket = new UnsubAckPacket();
                DecodePacketIdVariableHeader(buffer, unsubAckPacket, ref remainingLength);
                return(unsubAckPacket);

            case Signatures.PingResp:
                this.ValidateClientPacketExpected(packetSignature);
                return(PingRespPacket.Instance);

            default:
                throw new DecoderException($"First packet byte value of `{packetSignature}` is invalid.");
            }
        }