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 void EncodeFbnsConnectPacket(IByteBufferAllocator bufferAllocator, FbnsConnectPacket packet, List <object> output) { var payload = packet.Payload; int payloadSize = payload?.ReadableBytes ?? 0; byte[] protocolNameBytes = EncodeStringInUtf8(packet.ProtocolName); // variableHeaderBufferSize = 2 bytes length + ProtocolName bytes + 4 bytes // 4 bytes are reserved for: 1 byte ProtocolLevel, 1 byte ConnectFlags, 2 byte KeepAlive int variableHeaderBufferSize = STRING_SIZE_LENGTH + protocolNameBytes.Length + 4; int variablePartSize = variableHeaderBufferSize + payloadSize; int fixedHeaderBufferSize = 1 + MAX_VARIABLE_LENGTH; IByteBuffer buf = null; try { // MQTT message format from: http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/MQTT_V3.1_Protocol_Specific.pdf buf = bufferAllocator.Buffer(fixedHeaderBufferSize + variableHeaderBufferSize); buf.WriteByte((int)packet.PacketType << 4); // Write packet type WriteVariableLengthInt(buf, variablePartSize); // Write remaining length // Variable part buf.WriteShort(protocolNameBytes.Length); buf.WriteBytes(protocolNameBytes); buf.WriteByte(packet.ProtocolLevel); buf.WriteByte(packet.ConnectFlags); buf.WriteShort(packet.KeepAliveInSeconds); output.Add(buf); buf = null; } finally { buf?.SafeRelease(); } if (payload?.IsReadable() ?? false) { output.Add(payload.Retain()); } }
static void DecodeConnectPacket(IByteBuffer buffer, FbnsConnectPacket packet, ref int remainingLength) { string protocolName = DecodeString(buffer, 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 = buffer.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 = buffer.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(buffer, ref remainingLength); string clientId = DecodeString(buffer, ref remainingLength); if (string.IsNullOrEmpty(clientId)) { throw new DecoderException("Client identifier is required."); } packet.ClientId = clientId; if (hasWill) { packet.WillTopicName = DecodeString(buffer, ref remainingLength); int willMessageLength = DecodeUnsignedShort(buffer, ref remainingLength); DecreaseRemainingLength(ref remainingLength, willMessageLength); packet.WillMessage = buffer.ReadBytes(willMessageLength); } if (packet.HasUsername) { packet.Username = DecodeString(buffer, ref remainingLength); } if (packet.HasPassword) { packet.Password = DecodeString(buffer, ref remainingLength); } }
private Packet DecodePacketInternal(IByteBuffer buffer, int packetSignature, ref int 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(buffer, 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(buffer, subscribePacket, ref remainingLength); DecodeSubscribePayload(buffer, subscribePacket, ref remainingLength); return(subscribePacket); case Signatures.Connect: var connectPacket = new FbnsConnectPacket(); DecodeConnectPacket(buffer, connectPacket, ref remainingLength); return(connectPacket); case Signatures.PubAck: var pubAckPacket = new PubAckPacket(); DecodePacketIdVariableHeader(buffer, pubAckPacket, ref remainingLength); return(pubAckPacket); case Signatures.ConnAck: var connAckPacket = new FbnsConnAckPacket(); DecodeConnAckPacket(buffer, connAckPacket, ref remainingLength); return(connAckPacket); case Signatures.SubAck: var subAckPacket = new SubAckPacket(); DecodePacketIdVariableHeader(buffer, subAckPacket, ref remainingLength); DecodeSubAckPayload(buffer, subAckPacket, ref remainingLength); return(subAckPacket); case Signatures.Unsubscribe& 240: var unsubscribePacket = new UnsubscribePacket(); DecodePacketIdVariableHeader(buffer, unsubscribePacket, ref remainingLength); DecodeUnsubscribePayload(buffer, unsubscribePacket, ref remainingLength); return(unsubscribePacket); case Signatures.PingResp: return(PingRespPacket.Instance); default: throw new DecoderException($"Packet type {packetSignature} not supported"); } }