/// <summary> /// Reads the packet from the underlying stream. /// </summary> /// <param name="buffer">The pointer to start reading at.</param> /// <param name="offset">The offset to start at.</param> /// <param name="length">The remaining length.</param> /// <returns>Whether the packet was parsed successfully or not.</returns> public override unsafe MqttStatus TryRead(BufferSegment buffer, int offset, int length) { // Get the pointer var pBuffer = buffer.AsBytePointer(); var header = offset; // Read the topic name this.Channel = ReadString(pBuffer, ref offset); // Read the QoS level, dup and retain from the header this.QoS = (QoS)((*pBuffer & QOS_LEVEL_MASK) >> QOS_LEVEL_OFFSET); this.DupFlag = (((*pBuffer & DUP_FLAG_MASK) >> DUP_FLAG_OFFSET) == 0x01); this.Retain = (((*pBuffer & RETAIN_FLAG_MASK) >> RETAIN_FLAG_OFFSET) == 0x01); // message id is valid only with QOS level 1 or QOS level 2 if (this.IsEmitter || this.QoS != QoS.AtMostOnce) { this.MessageId = (ushort)ReadUInt16(pBuffer, ref offset); } // Copy the message in the segment var segment = buffer.AsSegment(); this.Message = new ArraySegment <byte>(segment.Array, segment.Offset + offset, length - offset + header); // => TEST //var message = new byte[length - offset + header]; //Memory.Copy(segment.Array, segment.Offset + offset, message, 0, length - offset + header); //this.Message = new ArraySegment<byte>(message); // We've parsed it return(MqttStatus.Success); }
/// <summary> /// Reads the packet from the underlying stream. /// </summary> /// <param name="buffer">The pointer to start reading at.</param> /// <param name="offset">The offset to start at.</param> /// <param name="length">The remaining length.</param> /// <returns>Whether the packet was parsed successfully or not.</returns> public override unsafe MqttStatus TryRead(BufferSegment buffer, int offset, int length) { // Get the pointer var pBuffer = buffer.AsBytePointer(); // [v3.1.1] check flag bits if (this.ProtocolVersion == MqttProtocolVersion.V3_1_1 && (*pBuffer & MSG_FLAG_BITS_MASK) != MQTT_MSG_DISCONNECT_FLAG_BITS) { return(MqttStatus.InvalidFlagBits); } // We've parsed it return(MqttStatus.Success); }
/// <summary> /// Reads the packet from the underlying stream. /// </summary> /// <param name="buffer">The pointer to start reading at.</param> /// <param name="offset">The offset to start at.</param> /// <param name="length">The remaining length.</param> /// <returns>Whether the packet was parsed successfully or not.</returns> public override unsafe MqttStatus TryRead(BufferSegment buffer, int offset, int length) { // Get the pointer var pBuffer = buffer.AsBytePointer(); // [v3.1.1] check flag bits if (this.ProtocolVersion == MqttProtocolVersion.V3_1_1 && (*pBuffer & MSG_FLAG_BITS_MASK) != MQTT_MSG_PUBACK_FLAG_BITS) { return(MqttStatus.InvalidFlagBits); } // Read the message id this.MessageId = (ushort)ReadUInt16(pBuffer, ref offset); // We've parsed it return(MqttStatus.Success); }
/// <summary> /// Reads the packet from the underlying stream. /// </summary> /// <param name="buffer">The pointer to start reading at.</param> /// <param name="length">The remaining length.</param> /// <param name="offset">The offset to start at.</param> /// <returns>Whether the packet was parsed successfully or not.</returns> public override unsafe MqttStatus TryRead(BufferSegment buffer, int offset, int length) { // Get the pointer var pBuffer = buffer.AsBytePointer(); // [v3.1.1] check flag bits if (this.ProtocolVersion == MqttProtocolVersion.V3_1_1 && (*pBuffer & MSG_FLAG_BITS_MASK) != MQTT_MSG_SUBSCRIBE_FLAG_BITS) { return(MqttStatus.InvalidFlagBits); } // only 3.1.0 if (this.ProtocolVersion == MqttProtocolVersion.V3_1) { // read QoS level from fixed header this.QoS = (QoS)((*pBuffer & QOS_LEVEL_MASK) >> QOS_LEVEL_OFFSET); // read DUP flag from fixed header this.DupFlag = (((*pBuffer & DUP_FLAG_MASK) >> DUP_FLAG_OFFSET) == 0x01); // retain flag not used this.Retain = false; } // Read the message id this.MessageId = (ushort)ReadUInt16(pBuffer, ref offset); do { // Read the channel string var channel = ReadString(pBuffer, ref offset); // Read the topic string and push it to the channels list this.Channels.Add(channel); // We simply skip the QoS level here, as in Emitter we don't take this // part of MQTT protocol into account and have a QoS = 0 always. ++offset; } while (offset < length); // We've parsed it return(MqttStatus.Success); }
/// <summary> /// Reads the packet from the underlying stream. /// </summary> /// <param name="buffer">The pointer to start reading at.</param> /// <param name="offset">The offset to start at.</param> /// <param name="length">The remaining length.</param> /// <returns>Whether the packet was parsed successfully or not.</returns> public override unsafe MqttStatus TryRead(BufferSegment buffer, int offset, int length) { var pBuffer = buffer.AsBytePointer(); // Read the protocol name this.ProtocolName = ReadString(pBuffer, ref offset); // Validate the protocol name if (!this.ProtocolName.Equals(PROTOCOL_NAME_V31) && !this.ProtocolName.Equals(PROTOCOL_NAME_V311)) { return(MqttStatus.InvalidProtocolName); } // Read the protocol version this.ProtocolVersion = (MqttProtocolVersion)(*(pBuffer + offset++)); // [v3.1.1] check lsb (reserved) must be 0 var flags = 0; flags = ReadByte(pBuffer, ref offset); //if ((this.ProtocolVersion == MqttProtocolVersion.V3_1_1) && ((flags & RESERVED_FLAG_MASK) != 0x00)) // return MqttStatus.InvalidConnectFlags; // Get whether this is our special implementation of MQTT this.IsEmitter = (flags & RESERVED_FLAG_MASK) != 0x00; // Read MQTT flags var isUsernameFlag = (flags & USERNAME_FLAG_MASK) != 0x00; var isPasswordFlag = (flags & PASSWORD_FLAG_MASK) != 0x00; var willRetain = (flags & WILL_RETAIN_FLAG_MASK) != 0x00; var willQosLevel = (byte)((flags & WILL_QOS_FLAG_MASK) >> WILL_QOS_FLAG_OFFSET); var willFlag = (flags & WILL_FLAG_MASK) != 0x00; var cleanSession = (flags & CLEAN_SESSION_FLAG_MASK) != 0x00; // Read the keep alive period var keepAlivePeriod = (ushort)ReadUInt16(pBuffer, ref offset); // client identifier [v3.1.1] it may be zero bytes long (empty string) this.ClientId = ReadString(pBuffer, ref offset); // [v3.1.1] if client identifier is zero bytes long, clean session must be true if ((this.ProtocolVersion == MqttProtocolVersion.V3_1_1) && (ClientId.Length == 0) && (!cleanSession)) { return(MqttStatus.InvalidClientId); } // Read will topic and will message if (willFlag) { this.WillTopic = ReadString(pBuffer, ref offset); this.WillMessage = ReadString(pBuffer, ref offset); } // Read the username if (isUsernameFlag) { this.Username = ReadString(pBuffer, ref offset); } // Read the password if (isPasswordFlag) { this.Password = ReadString(pBuffer, ref offset); } // We've parsed it return(MqttStatus.Success); }