private static void EncodeFbnsConnectPacket(FbnsConnectPacket packet, DataWriter writer) { var payload = packet.Payload; uint payloadSize = payload?.Length ?? 0; byte[] protocolNameBytes = EncodeStringInUtf8(packet.ProtocolName); // variableHeaderwriterferSize = 2 bytes length + ProtocolName bytes + 4 bytes // 4 bytes are reserved for: 1 byte ProtocolLevel, 1 byte ConnectFlags, 2 byte KeepAlive uint variableHeaderwriterferSize = (uint)(STRING_SIZE_LENGTH + protocolNameBytes.Length + 4); uint variablePartSize = variableHeaderwriterferSize + payloadSize; // MQTT message format from: http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/MQTT_V3.1_Protocol_Specific.pdf writer.WriteByte((byte)((int)packet.PacketType << 4)); // Write packet type WriteVariableLengthInt(writer, variablePartSize); // Write remaining length // Variable part writer.WriteUInt16((ushort)protocolNameBytes.Length); writer.WriteBytes(protocolNameBytes); writer.WriteByte(packet.ProtocolLevel); writer.WriteByte(packet.ConnectFlags); writer.WriteUInt16(packet.KeepAliveInSeconds); if (payload != null) { writer.WriteBuffer(payload); } }
private static Packet DecodePacketInternal(DataReader reader, int packetSignature, ref uint remainingLength) { 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(reader, packet, ref remainingLength); return(packet); } switch (packetSignature & 240) // We don't care about flags for these packets { case Signatures.Subscribe& 240: var subscribePacket = new SubscribePacket(); DecodePacketIdVariableHeader(reader, subscribePacket, ref remainingLength); DecodeSubscribePayload(reader, subscribePacket, ref remainingLength); return(subscribePacket); case Signatures.Connect: var connectPacket = new FbnsConnectPacket(); DecodeConnectPacket(reader, connectPacket, ref remainingLength); return(connectPacket); case Signatures.ConnAck: var connAckPacket = new FbnsConnAckPacket(); DecodeConnAckPacket(reader, connAckPacket, ref remainingLength); return(connAckPacket); case Signatures.SubAck: var subAckPacket = new SubAckPacket(); DecodePacketIdVariableHeader(reader, subAckPacket, ref remainingLength); DecodeSubAckPayload(reader, subAckPacket, ref remainingLength); return(subAckPacket); case Signatures.Unsubscribe& 240: var unsubscribePacket = new UnsubscribePacket(); DecodePacketIdVariableHeader(reader, unsubscribePacket, ref remainingLength); DecodeUnsubscribePayload(reader, unsubscribePacket, ref remainingLength); return(unsubscribePacket); case Signatures.PingResp: return(PingRespPacket.Instance); case Signatures.PubAck: var pubAckPacket = new PubAckPacket(); DecodePacketIdVariableHeader(reader, pubAckPacket, ref remainingLength); return(pubAckPacket); default: return(null); //default: // throw new DecoderException($"Packet type {packetSignature} not supported"); } }
static void DecodeConnectPacket(DataReader reader, FbnsConnectPacket packet, ref uint remainingLength) { string protocolName = DecodeString(reader, ref remainingLength); // if (!PROTOCOL_NAME.Equals(protocolName, StringComparison.Ordinal)) // { // throw new DecoderException($"Unexpected protocol name. Expected: {PROTOCOL_NAME}. Actual: {protocolName}"); // } packet.ProtocolName = protocolName; DecreaseRemainingLength(ref remainingLength, 1); packet.ProtocolLevel = reader.ReadByte(); // if (packet.ProtocolLevel != Util.ProtocolLevel) // { // var connAckPacket = new ConnAckPacket(); // connAckPacket.ReturnCode = ConnectReturnCode.RefusedUnacceptableProtocolVersion; // context.WriteAndFlushAsync(connAckPacket); // throw new DecoderException($"Unexpected protocol level. Expected: {Util.ProtocolLevel}. Actual: {packet.ProtocolLevel}"); // } DecreaseRemainingLength(ref remainingLength, 1); int connectFlags = reader.ReadByte(); packet.CleanSession = (connectFlags & 0x02) == 0x02; bool hasWill = (connectFlags & 0x04) == 0x04; if (hasWill) { packet.HasWill = true; packet.WillRetain = (connectFlags & 0x20) == 0x20; packet.WillQualityOfService = (QualityOfService)((connectFlags & 0x18) >> 3); if (packet.WillQualityOfService == QualityOfService.Reserved) { throw new DecoderException($"[MQTT-3.1.2-14] Unexpected Will QoS value of {(int)packet.WillQualityOfService}."); } packet.WillTopicName = string.Empty; } else if ((connectFlags & 0x38) != 0) // bits 3,4,5 [MQTT-3.1.2-11] { throw new DecoderException("[MQTT-3.1.2-11]"); } packet.HasUsername = (connectFlags & 0x80) == 0x80; packet.HasPassword = (connectFlags & 0x40) == 0x40; if (packet.HasPassword && !packet.HasUsername) { throw new DecoderException("[MQTT-3.1.2-22]"); } if ((connectFlags & 0x1) != 0) // [MQTT-3.1.2-3] { throw new DecoderException("[MQTT-3.1.2-3]"); } packet.KeepAliveInSeconds = DecodeUnsignedShort(reader, ref remainingLength); string clientId = DecodeString(reader, ref remainingLength); if (string.IsNullOrEmpty(clientId)) { throw new DecoderException("Client identifier is required."); } packet.ClientId = clientId; if (hasWill) { packet.WillTopicName = DecodeString(reader, ref remainingLength); var willMessageLength = DecodeUnsignedShort(reader, ref remainingLength); DecreaseRemainingLength(ref remainingLength, willMessageLength); packet.WillMessage = reader.ReadBuffer(willMessageLength); } if (packet.HasUsername) { packet.Username = DecodeString(reader, ref remainingLength); } if (packet.HasPassword) { packet.Password = DecodeString(reader, ref remainingLength); } }