예제 #1
0
        /// <exception cref="MalformedMessageException">Exception is thrown in case of invalid packet format</exception>
        public static IByteBuffer encode(MQMessage header)
        {
            int         length = header.GetLength();
            IByteBuffer buf    = GetBuffer(length);
            MessageType type   = header.MessageType;

            switch (type)
            {
            case MessageType.CONNECT:
                Connect connect = (Connect)header;
                if (connect.Will != null && !connect.Will.IsValid())
                {
                    throw new MalformedMessageException("invalid will encoding");
                }

                buf.SetByte(0, (byte)(((Int32)type) << 4));
                buf.WriteShort(Connect.DEFAULT_PROTOCOL_LEVEL);
                buf.WriteBytes(Encoding.UTF8.GetBytes(connect.Name));
                buf.WriteByte(connect.ProtocolLevel);
                byte contentFlags = 0;
                if (connect.CleanSession)
                {
                    contentFlags += 0x02;
                }

                if (connect.Will != null)
                {
                    contentFlags += 0x04;
                    contentFlags += (byte)(((Int32)connect.Will.Topic.Qos) << 3);
                    if (connect.Will.Retain)
                    {
                        contentFlags += 0x20;
                    }
                }

                if (connect.Username != null)
                {
                    contentFlags += 0x40;
                }

                if (connect.Password != null)
                {
                    contentFlags += 0x80;
                }

                buf.WriteByte(contentFlags);
                buf.WriteShort(connect.Keepalive);
                buf.WriteShort(connect.ClientID.Length);
                buf.WriteBytes(Encoding.UTF8.GetBytes(connect.ClientID));

                if (connect.Will != null)
                {
                    String willTopic = connect.Will.Topic.Name;
                    if (willTopic != null)
                    {
                        buf.WriteShort(willTopic.Length);
                        buf.WriteBytes(Encoding.UTF8.GetBytes(willTopic));
                    }

                    byte[] willMessage = connect.Will.Content;
                    if (willMessage != null)
                    {
                        buf.WriteShort(willMessage.Length);
                        buf.WriteBytes(willMessage);
                    }
                }

                String username = connect.Username;
                if (username != null)
                {
                    buf.WriteShort(username.Length);
                    buf.WriteBytes(Encoding.UTF8.GetBytes(username));
                }

                String password = connect.Password;
                if (password != null)
                {
                    buf.WriteShort(password.Length);
                    buf.WriteBytes(Encoding.UTF8.GetBytes(password));
                }
                break;

            case MessageType.CONNACK:
                Connack connack = (Connack)header;
                buf.SetByte(0, (byte)(((Int32)type) << 4));
                buf.WriteBoolean(connack.SessionPresent);
                buf.WriteByte((Int32)connack.ReturnCode);
                break;

            case MessageType.PUBLISH:
                Publish publish   = (Publish)header;
                byte    firstByte = (byte)(((Int32)type) << 4);
                if (publish.Dup)
                {
                    firstByte += 0x08;
                }

                firstByte += (byte)(((Int32)publish.Topic.Qos) << 1);

                if (publish.Retain)
                {
                    firstByte += 0x01;
                }

                buf.SetByte(0, firstByte);
                buf.WriteShort(publish.Topic.Name.Length);
                buf.WriteBytes(Encoding.UTF8.GetBytes(publish.Topic.Name));
                if (publish.PacketID.HasValue)
                {
                    buf.WriteShort(publish.PacketID.Value);
                }
                buf.WriteBytes(publish.Content);
                break;

            case MessageType.PUBACK:
                Puback puback = (Puback)header;
                buf.SetByte(0, (byte)(((Int32)type) << 4));
                buf.WriteShort(puback.PacketID.Value);
                break;

            case MessageType.PUBREC:
                Pubrec pubrec = (Pubrec)header;
                buf.SetByte(0, (byte)(((Int32)type) << 4));
                buf.WriteShort(pubrec.PacketID.Value);
                break;

            case MessageType.PUBREL:
                Pubrel pubrel = (Pubrel)header;
                buf.SetByte(0, (byte)((((Int32)type) << 4) | 0x2));
                buf.WriteShort(pubrel.PacketID.Value);
                break;

            case MessageType.PUBCOMP:
                Pubcomp pubcomp = (Pubcomp)header;
                buf.SetByte(0, (byte)(((Int32)type) << 4));
                buf.WriteShort(pubcomp.PacketID.Value);
                break;

            case MessageType.SUBSCRIBE:
                Subscribe sub = (Subscribe)header;
                buf.SetByte(0, (byte)((((Int32)type) << 4) | 0x2));
                buf.WriteShort(sub.PacketID.Value);
                foreach (Topic subscription in sub.Topics)
                {
                    buf.WriteShort(subscription.Name.Length);
                    buf.WriteBytes(Encoding.UTF8.GetBytes(subscription.Name));
                    buf.WriteByte((Int32)subscription.Qos);
                }
                break;

            case MessageType.SUBACK:
                Suback suback = (Suback)header;
                buf.SetByte(0, (byte)(((Int32)type) << 4));
                buf.WriteShort(suback.PacketID.Value);
                foreach (SubackCode code in suback.ReturnCodes)
                {
                    buf.WriteByte((Int32)code);
                }
                break;

            case MessageType.UNSUBSCRIBE:
                Unsubscribe unsub = (Unsubscribe)header;
                buf.SetByte(0, (byte)((((Int32)type) << 4) | 0x2));
                buf.WriteShort(unsub.PacketID.Value);
                foreach (String topic in unsub.Topics)
                {
                    buf.WriteShort(topic.Length);
                    buf.WriteBytes(Encoding.UTF8.GetBytes(topic));
                }
                break;

            case MessageType.UNSUBACK:
                Unsuback unsuback = (Unsuback)header;
                buf.SetByte(0, (byte)(((Int32)type) << 4));
                buf.WriteShort(unsuback.PacketID.Value);
                break;

            case MessageType.DISCONNECT:
            case MessageType.PINGREQ:
            case MessageType.PINGRESP:
                buf.SetByte(0, (byte)(((Int32)type) << 4));
                break;

            default:
                throw new MalformedMessageException("Invalid header type: " + type);
            }

            return(buf);
        }