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