public static MqttMsgSubscribe Parse(byte fixedHeaderFirstByte, byte protocolVersion, IMqttNetworkChannel channel)
        {
            int num1 = 0;
            MqttMsgSubscribe mqttMsgSubscribe1 = new MqttMsgSubscribe();

            if (protocolVersion == (byte)4 && ((int)fixedHeaderFirstByte & 15) != 2)
            {
                throw new MqttClientException(MqttClientErrorCode.InvalidFlagBits);
            }
            int length1 = MqttMsgBase.decodeRemainingLength(channel);

            byte[] buffer = new byte[length1];
            channel.Receive(buffer);
            if (protocolVersion == (byte)3)
            {
                mqttMsgSubscribe1.qosLevel = checked ((byte)(((int)fixedHeaderFirstByte & 6) >> 1));
                mqttMsgSubscribe1.dupFlag  = ((int)fixedHeaderFirstByte & 8) >> 3 == 1;
                mqttMsgSubscribe1.retain   = false;
            }
            MqttMsgSubscribe mqttMsgSubscribe2 = mqttMsgSubscribe1;

            byte[] numArray1 = buffer;
            int    index1    = num1;
            int    num2      = checked (index1 + 1);
            int    num3      = (int)checked ((ushort)((int)numArray1[index1] << 8 & 65280));

            mqttMsgSubscribe2.messageId = (ushort)num3;
            MqttMsgSubscribe mqttMsgSubscribe3 = mqttMsgSubscribe1;
            int messageId = (int)mqttMsgSubscribe3.messageId;

            byte[] numArray2 = buffer;
            int    index2    = num2;
            int    num4      = checked (index2 + 1);
            int    num5      = (int)numArray2[index2];

            mqttMsgSubscribe3.messageId = (ushort)(messageId | num5);
            IList <string> stringList = (IList <string>) new List <string>();
            IList <byte>   byteList1  = (IList <byte>) new List <byte>();

            do
            {
                byte[] numArray3   = buffer;
                int    index3      = num4;
                int    num6        = checked (index3 + 1);
                int    num7        = (int)numArray3[index3] << 8 & 65280;
                byte[] numArray4   = buffer;
                int    index4      = num6;
                int    sourceIndex = checked (index4 + 1);
                int    num8        = (int)numArray4[index4];
                int    length2     = num7 | num8;
                byte[] bytes       = new byte[length2];
                Array.Copy((Array)buffer, sourceIndex, (Array)bytes, 0, length2);
                int num9 = checked (sourceIndex + length2);
                stringList.Add(new string(Encoding.UTF8.GetChars(bytes)));
                IList <byte> byteList2 = byteList1;
                byte[]       numArray5 = buffer;
                int          index5    = num9;
                num4 = checked (index5 + 1);
                int num10 = (int)numArray5[index5];
                byteList2.Add((byte)num10);
            }while (num4 < length1);
            mqttMsgSubscribe1.topics    = new string[stringList.Count];
            mqttMsgSubscribe1.qosLevels = new byte[byteList1.Count];
            int index6 = 0;

            while (index6 < stringList.Count)
            {
                mqttMsgSubscribe1.topics[index6]    = stringList[index6];
                mqttMsgSubscribe1.qosLevels[index6] = byteList1[index6];
                checked { ++index6; }
            }
            return(mqttMsgSubscribe1);
        }
Exemple #2
0
        /// <summary>
        /// Subscribe for message topics
        /// </summary>
        /// <param name="topics">List of topics to subscribe</param>
        /// <param name="qosLevels">QOS levels related to topics</param>
        /// <returns>Granted QoS Levels in SUBACK message from broker</returns>
        public byte[] Subscribe(string[] topics, byte[] qosLevels)
        {
            int attempts = 0;
            bool acknowledged = false;

            MqttMsgSubscribe subscribe =
                new MqttMsgSubscribe(topics, qosLevels);

            MqttMsgSuback suback = null;
            do
            {
                try
                {
                    // try subscribe
                    suback = (MqttMsgSuback)this.SendReceive(subscribe.GetBytes());
                    acknowledged = true;
                }
                catch (MqttTimeoutException)
                {
                    // no SUBACK message received in time, retry with duplicate flag
                    attempts++;
                    subscribe.DupFlag = true;
                    // delay before retry
                    if (attempts < MQTT_ATTEMPTS_RETRY)
                        Thread.Sleep(MQTT_DELAY_RETRY);
                }
            } while ((attempts < MQTT_ATTEMPTS_RETRY) && !acknowledged);

            // return granted QoS Levels or null
            return acknowledged ? suback.GrantedQoSLevels : null;
        }
        /// <summary>
        /// Subscribe for message topics
        /// </summary>
        /// <param name="topics">List of topics to subscribe</param>
        /// <param name="qosLevels">QOS levels related to topics</param>
        /// <returns>Message Id related to SUBSCRIBE message</returns>
        public ushort Subscribe(string[] topics, byte[] qosLevels)
        {
            MqttMsgSubscribe subscribe =
                new MqttMsgSubscribe(topics, qosLevels);
            subscribe.MessageId = this.GetMessageId();

            // enqueue subscribe request into the inflight queue
            this.EnqueueInflight(subscribe, MqttMsgFlow.ToPublish);

            return subscribe.MessageId;
        }
        /// <summary>
        /// Parse bytes for a SUBSCRIBE message
        /// </summary>
        /// <param name="fixedHeaderFirstByte">First fixed header byte</param>
        /// <param name="protocolVersion">Protocol Version</param>
        /// <param name="channel">Channel connected to the broker</param>
        /// <returns>SUBSCRIBE message instance</returns>
        public static MqttMsgSubscribe Parse(byte fixedHeaderFirstByte, byte protocolVersion, IMqttNetworkChannel channel)
        {
            byte[] buffer;
            int    index = 0;

            byte[]           topicUtf8;
            int              topicUtf8Length;
            MqttMsgSubscribe msg = new MqttMsgSubscribe();

            if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1_1)
            {
                // [v3.1.1] check flag bits
                if ((fixedHeaderFirstByte & MSG_FLAG_BITS_MASK) != MQTT_MSG_SUBSCRIBE_FLAG_BITS)
                {
                    throw new MqttClientException(MqttClientErrorCode.InvalidFlagBits);
                }
            }

            // get remaining length and allocate buffer
            int remainingLength = MqttMsgBase.decodeRemainingLength(channel);

            buffer = new byte[remainingLength];

            // read bytes from socket...
            int received = channel.Receive(buffer);

            if (protocolVersion == MqttMsgConnect.PROTOCOL_VERSION_V3_1)
            {
                // only 3.1.0

                // read QoS level from fixed header
                msg.qosLevel = (byte)((fixedHeaderFirstByte & QOS_LEVEL_MASK) >> QOS_LEVEL_OFFSET);
                // read DUP flag from fixed header
                msg.dupFlag = (((fixedHeaderFirstByte & DUP_FLAG_MASK) >> DUP_FLAG_OFFSET) == 0x01);
                // retain flag not used
                msg.retain = false;
            }

            // message id
            msg.messageId  = (ushort)((buffer[index++] << 8) & 0xFF00);
            msg.messageId |= (buffer[index++]);

            // payload contains topics and QoS levels
            // NOTE : before, I don't know how many topics will be in the payload (so use List)

// if .Net Micro Framework
#if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3)
            IList tmpTopics    = new ArrayList();
            IList tmpQosLevels = new ArrayList();
// else other frameworks (.Net, .Net Compact, Mono, Windows Phone)
#else
            IList <String> tmpTopics    = new List <String>();
            IList <byte>   tmpQosLevels = new List <byte>();
#endif
            do
            {
                // topic name
                topicUtf8Length  = ((buffer[index++] << 8) & 0xFF00);
                topicUtf8Length |= buffer[index++];
                topicUtf8        = new byte[topicUtf8Length];
                Array.Copy(buffer, index, topicUtf8, 0, topicUtf8Length);
                index += topicUtf8Length;
                tmpTopics.Add(new String(Encoding.UTF8.GetChars(topicUtf8)));

                // QoS level
                tmpQosLevels.Add(buffer[index++]);
            } while (index < remainingLength);

            // copy from list to array
            msg.topics    = new string[tmpTopics.Count];
            msg.qosLevels = new byte[tmpQosLevels.Count];
            for (int i = 0; i < tmpTopics.Count; i++)
            {
                msg.topics[i]    = (string)tmpTopics[i];
                msg.qosLevels[i] = (byte)tmpQosLevels[i];
            }

            return(msg);
        }
        /// <summary>
        /// Parse bytes for a SUBSCRIBE message
        /// </summary>
        /// <param name="fixedHeaderFirstByte">First fixed header byte</param>
        /// <param name="channel">Channel connected to the broker</param>
        /// <returns>SUBSCRIBE message instance</returns>
        public static MqttMsgSubscribe Parse(byte fixedHeaderFirstByte, IMqttNetworkChannel channel)
        {
            byte[] buffer;
            int index = 0;
            byte[] topicUtf8;
            int topicUtf8Length;
            MqttMsgSubscribe msg = new MqttMsgSubscribe();

            // get remaining length and allocate buffer
            int remainingLength = MqttMsgBase.decodeRemainingLength(channel);
            buffer = new byte[remainingLength];

            // read bytes from socket...
            int received = channel.Receive(buffer);

            // read QoS level from fixed header
            msg.qosLevel = (byte)((fixedHeaderFirstByte & QOS_LEVEL_MASK) >> QOS_LEVEL_OFFSET);
            // read DUP flag from fixed header
            msg.dupFlag = (((fixedHeaderFirstByte & DUP_FLAG_MASK) >> DUP_FLAG_OFFSET) == 0x01);
            // retain flag not used
            msg.retain = false;

            // message id
            msg.messageId = (ushort)((buffer[index++] << 8) & 0xFF00);
            msg.messageId |= (buffer[index++]);

            // payload contains topics and QoS levels
            // NOTE : before, I don't know how many topics will be in the payload (so use List)

            // if .Net Micro Framework
            #if (MF_FRAMEWORK_VERSION_V4_2 || MF_FRAMEWORK_VERSION_V4_3)
            IList tmpTopics = new ArrayList();
            IList tmpQosLevels = new ArrayList();
            // else other frameworks (.Net, .Net Compact, Mono, Windows Phone)
            #else
            IList<String> tmpTopics = new List<String>();
            IList<byte> tmpQosLevels = new List<byte>();
            #endif
            do
            {
                // topic name
                topicUtf8Length = ((buffer[index++] << 8) & 0xFF00);
                topicUtf8Length |= buffer[index++];
                topicUtf8 = new byte[topicUtf8Length];
                Array.Copy(buffer, index, topicUtf8, 0, topicUtf8Length);
                index += topicUtf8Length;
                tmpTopics.Add(new String(Encoding.UTF8.GetChars(topicUtf8)));

                // QoS level
                tmpQosLevels.Add(buffer[index++]);

            } while (index < remainingLength);

            // copy from list to array
            msg.topics = new string[tmpTopics.Count];
            msg.qosLevels = new byte[tmpQosLevels.Count];
            for (int i = 0; i < tmpTopics.Count; i++)
            {
                msg.topics[i] = (string)tmpTopics[i];
                msg.qosLevels[i] = (byte)tmpQosLevels[i];
            }

            return msg;
        }