private async Task ProcessConnAckAsync(IChannelHandlerContext context, ConnAckPacket packet) { if (packet.SessionPresent) { await FailWithExceptionAsync( context, new ProvisioningTransportException( $"{ExceptionPrefix} Unexpected CONNACK with SessionPresent.")).ConfigureAwait(false); } switch (packet.ReturnCode) { case ConnectReturnCode.Accepted: try { await SubscribeAsync(context).ConfigureAwait(false); ChangeState(State.WaitForConnack, State.WaitForSuback); } catch (Exception ex) { await FailWithExceptionAsync(context, ex).ConfigureAwait(false); } break; case ConnectReturnCode.RefusedUnacceptableProtocolVersion: case ConnectReturnCode.RefusedIdentifierRejected: case ConnectReturnCode.RefusedBadUsernameOrPassword: case ConnectReturnCode.RefusedNotAuthorized: await FailWithExceptionAsync( context, new ProvisioningTransportException( $"{ExceptionPrefix} CONNACK failed with {packet.ReturnCode}")).ConfigureAwait(false); break; case ConnectReturnCode.RefusedServerUnavailable: await FailWithExceptionAsync( context, new ProvisioningTransportException( $"{ExceptionPrefix} CONNACK failed with {packet.ReturnCode}. Try again later.", null, true)).ConfigureAwait(false); break; default: await FailWithExceptionAsync( context, new ProvisioningTransportException( $"{ExceptionPrefix} CONNACK failed unknown return code: {packet.ReturnCode}")).ConfigureAwait(false); break; } }
public void TestConnAckMessage(bool sessionPresent, ConnectReturnCode returnCode) { var packet = new ConnAckPacket(); packet.SessionPresent = sessionPresent; packet.ReturnCode = returnCode; ConnAckPacket recoded = this.RecodePacket(packet, false, true); this.contextMock.Verify(x => x.FireChannelRead(It.IsAny <ConnAckPacket>()), Times.Once); Assert.Equal(packet.SessionPresent, recoded.SessionPresent); Assert.Equal(packet.ReturnCode, recoded.ReturnCode); }
public void ConnAckMessageTest(bool sessionPresent, ConnectReturnCode returnCode) { var packet = new ConnAckPacket(); packet.VariableHeader.SessionPresent = sessionPresent; packet.VariableHeader.ConnectReturnCode = returnCode; var recoded = RecodePacket(packet, false, false); contextMock.Verify(x => x.FireChannelRead(It.IsAny <ConnAckPacket>()), Times.Once); Assert.Equal(packet.VariableHeader.SessionPresent, recoded.VariableHeader.SessionPresent); Assert.Equal(packet.VariableHeader.ConnectReturnCode, recoded.VariableHeader.ConnectReturnCode); }
protected override async Task <MqttMessage> ProcessAsync(MqttClientSession clientSession, ConnectPacket packet) { var ack = new ConnAckPacket(); var resultMsg = new MqttMessage { Packet = ack }; _logger.LogInformation("receive connect packet ,clientId={0}", packet.ClientId); IMqttResult validResult = await _mqttAuthorize.Validate(packet); ack.ReturnCode = validResult.Code == 0 ? ConnectReturnCode.Accepted : ConnectReturnCode.RefusedNotAuthorized; return(resultMsg); }
static void EncodeConnAckMessage(DataWriter writer, ConnAckPacket message) { writer.WriteByte(CalculateFirstByteOfFixedHeader(message)); writer.WriteByte(2); // remaining length if (message.SessionPresent) { writer.WriteByte(1); // 7 reserved 0-bits and SP = 1 } else { writer.WriteByte(0); // 7 reserved 0-bits and SP = 0 } writer.WriteByte((byte)message.ReturnCode); }
public void OnConnAck(IChannelHandlerContext context, ConnAckPacket packet) { switch (packet.ReturnCode) { case ConnectReturnCode.Accepted: connectFuture.SetResult(new ConnectResult(true, ConnectReturnCode.Accepted, context.Channel.CloseCompletion)); foreach (var value in pendingSubscribes.Values) { if (!value.Sent) { context.WriteAsync(value.Packet).Wait(); value.Sent = true; } } foreach (var value in pendingPublishes.Values) { if (value.Sent) { continue; } context.WriteAsync(value.Packet).Wait(); value.Sent = true; if (value.Packet.QualityOfService == QualityOfService.AtMostOnce) { value.Promise.SetResult(null); //We don't get an ACK for QOS 0 pendingPublishes.TryRemove(value.Packet.PacketId, out _); } } context.Flush(); if (reconnecting) { if (OnConnectionChange != null) { OnConnectionChange.OnReconnect(); } } break; default: connectFuture.SetResult(new ConnectResult(false, packet.ReturnCode, context.Channel.CloseCompletion)); context.CloseAsync(); break; } }
static void EncodeConnAckMessage(IByteBufferAllocator bufferAllocator, ConnAckPacket message, List <object> output) { IByteBuffer buffer = bufferAllocator.Buffer(4); buffer.WriteByte(CalculateFirstByteOfFixedHeader(message)); buffer.WriteByte(2); // remaining length if (message.SessionPresent) { buffer.WriteByte(1); // 7 reserved 0-bits and SP = 1 } else { buffer.WriteByte(0); // 7 reserved 0-bits and SP = 0 } buffer.WriteByte((byte)message.ReturnCode); output.Add(buffer); }
Packet DecodePacketInternal(IByteBuffer buffer, byte packetSignature, ref int remainingLength) { Packet packet; var fixedHeader = new FixedHeader(packetSignature, remainingLength); switch (fixedHeader.PacketType) { case PacketType.CONNECT: packet = new ConnectPacket(); break; case PacketType.CONNACK: packet = new ConnAckPacket(); break; case PacketType.DISCONNECT: packet = new DisconnectPacket(); break; case PacketType.PINGREQ: packet = new PingReqPacket(); break; case PacketType.PINGRESP: packet = new PingRespPacket(); break; case PacketType.PUBACK: packet = new PubAckPacket(); break; case PacketType.PUBCOMP: packet = new PubCompPacket(); break; case PacketType.PUBLISH: packet = new PublishPacket(); break; case PacketType.PUBREC: packet = new PubRecPacket(); break; case PacketType.PUBREL: packet = new PubRelPacket(); break; case PacketType.SUBSCRIBE: packet = new SubscribePacket(); break; case PacketType.SUBACK: packet = new SubAckPacket(); break; case PacketType.UNSUBSCRIBE: packet = new UnsubscribePacket(); break; case PacketType.UNSUBACK: packet = new UnsubscribePacket(); break; default: throw new DecoderException("Unsupported Message Type"); } packet.FixedHeader = fixedHeader; packet.Decode(buffer); remainingLength = packet.RemaingLength; return(packet); }
public async Task <MqttMessage> ProcessAsync(MqttClientSession clientSession, Packet packet) { var ack = new ConnAckPacket(); var resultMsg = new MqttMessage { Packet = ack }; if (!(packet is ConnectPacket cntPacket)) { this.logger.LogWarning("bad data format"); ack.ReturnCode = ConnectReturnCode.RefusedNotAuthorized; return(resultMsg); } this.logger.LogWarning("receive connect packet ,clientId={0}", cntPacket.ClientId); IMqttResult validResult = await this.mqttAuthorize.Validate(cntPacket); ack.ReturnCode = validResult.Code == 0 ? ConnectReturnCode.Accepted : ConnectReturnCode.RefusedNotAuthorized; return(resultMsg); }
private void ProcessMessage(IChannel channel, ConnAckPacket message) { switch (message.VariableHeader.ConnectReturnCode) { case ConnectReturnCode.CONNECTION_ACCEPTED: connectFuture.TrySetResult(new MqttConnectResult(ConnectReturnCode.CONNECTION_ACCEPTED)); if (client.ConnectedHandler != null) { client.ConnectedHandler.OnConnected(); } break; case ConnectReturnCode.CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD: case ConnectReturnCode.CONNECTION_REFUSED_IDENTIFIER_REJECTED: case ConnectReturnCode.CONNECTION_REFUSED_SERVER_UNAVAILABLE: case ConnectReturnCode.CONNECTION_REFUSED_UNACCEPTABLE_PROTOCOL_VERSION: connectFuture.TrySetResult(new MqttConnectResult(message.VariableHeader.ConnectReturnCode)); channel.CloseAsync(); break; } }
async Task ProcessConnectAckAsync(IChannelHandlerContext context, ConnAckPacket packet) { if (Logging.IsEnabled) { Logging.Enter(this, context.Name, packet, nameof(ProcessConnectAckAsync)); } if (packet.ReturnCode != ConnectReturnCode.Accepted) { string reason = "CONNECT failed: " + packet.ReturnCode; var iotHubException = new UnauthorizedException(reason); ShutdownOnError(context, iotHubException); return; } if (!this.IsInState(StateFlags.Connecting)) { string reason = "CONNECT has been received, however a session has already been established. Only one CONNECT/CONNACK pair is expected per session."; var iotHubException = new IotHubException(reason); ShutdownOnError(context, iotHubException); return; } this.stateFlags = StateFlags.Connected; this.mqttIotHubEventHandler.OnConnected(); this.ResumeReadingIfNecessary(context); if (packet.SessionPresent) { await this.SubscribeAsync(context, null).ConfigureAwait(true); } if (Logging.IsEnabled) { Logging.Exit(this, context.Name, packet, nameof(ProcessConnectAckAsync)); } }
private void HandleConack(IChannel channel, ConnAckPacket message) { switch (message.ConnectReturnCode) { case ConnectReturnCode.ConnectionAccepted: connectFuture.TrySetResult(new MqttConnectResult(ConnectReturnCode.ConnectionAccepted)); if (client.ConnectedHandler != null) { client.ConnectedHandler.OnConnected(); } break; case ConnectReturnCode.BadUsernameOrPassword: case ConnectReturnCode.IdentifierRejected: case ConnectReturnCode.RefusedNotAuthorized: case ConnectReturnCode.BrokerUnavailable: case ConnectReturnCode.UnacceptableProtocolVersion: connectFuture.TrySetResult(new MqttConnectResult(message.ConnectReturnCode)); channel.CloseAsync(); break; } }
void ProcessConnectAck(IChannelHandlerContext context, ConnAckPacket packet) { if (packet.ReturnCode != ConnectReturnCode.Accepted) { string reason = "CONNECT failed: " + packet.ReturnCode; var iotHubException = new IotHubException(reason); ShutdownOnError(context, iotHubException); return; } if (!this.IsInState(StateFlags.Connecting)) { string reason = "CONNECT has been received, however a session has already been established. Only one CONNECT/CONNACK pair is expected per session."; var iotHubException = new IotHubException(reason); ShutdownOnError(context, iotHubException); return; } this.stateFlags = StateFlags.Connected; this.ResumeReadingIfNecessary(context); this.onConnected(); }
public async Task ConnAck(IChannelHandlerContext context, ConnAckPacket packet) { await context.WriteAndFlushAsync(packet); }
public abstract void ConnAck(IChannelHandlerContext context, ConnAckPacket packet);
Packet DecodePacketInternal(IByteBuffer buffer, int packetSignature, ref int remainingLength, IChannelHandlerContext context) { 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) { ThrowHelper.ThrowDecoderException_UnexpectedQoSValueForPublish(qualityOfService); } 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) // strict match checks for valid message type + correct values in flags part { case Signatures.PubAck: var pubAckPacket = new PubAckPacket(); DecodePacketIdVariableHeader(buffer, pubAckPacket, ref remainingLength); return(pubAckPacket); case Signatures.PubRec: var pubRecPacket = new PubRecPacket(); DecodePacketIdVariableHeader(buffer, pubRecPacket, ref remainingLength); return(pubRecPacket); case Signatures.PubRel: var pubRelPacket = new PubRelPacket(); DecodePacketIdVariableHeader(buffer, pubRelPacket, ref remainingLength); return(pubRelPacket); case Signatures.PubComp: var pubCompPacket = new PubCompPacket(); DecodePacketIdVariableHeader(buffer, pubCompPacket, ref remainingLength); return(pubCompPacket); case Signatures.PingReq: if (!_isServer) { ValidateServerPacketExpected(packetSignature); } return(PingReqPacket.Instance); case Signatures.Subscribe: if (!_isServer) { ValidateServerPacketExpected(packetSignature); } var subscribePacket = new SubscribePacket(); DecodePacketIdVariableHeader(buffer, subscribePacket, ref remainingLength); DecodeSubscribePayload(buffer, subscribePacket, ref remainingLength); return(subscribePacket); case Signatures.Unsubscribe: if (!_isServer) { ValidateServerPacketExpected(packetSignature); } var unsubscribePacket = new UnsubscribePacket(); DecodePacketIdVariableHeader(buffer, unsubscribePacket, ref remainingLength); DecodeUnsubscribePayload(buffer, unsubscribePacket, ref remainingLength); return(unsubscribePacket); case Signatures.Connect: if (!_isServer) { ValidateServerPacketExpected(packetSignature); } var connectPacket = new ConnectPacket(); DecodeConnectPacket(buffer, connectPacket, ref remainingLength, context); return(connectPacket); case Signatures.Disconnect: if (!_isServer) { ValidateServerPacketExpected(packetSignature); } return(DisconnectPacket.Instance); case Signatures.ConnAck: if (_isServer) { ValidateClientPacketExpected(packetSignature); } var connAckPacket = new ConnAckPacket(); DecodeConnAckPacket(buffer, connAckPacket, ref remainingLength); return(connAckPacket); case Signatures.SubAck: if (_isServer) { ValidateClientPacketExpected(packetSignature); } var subAckPacket = new SubAckPacket(); DecodePacketIdVariableHeader(buffer, subAckPacket, ref remainingLength); DecodeSubAckPayload(buffer, subAckPacket, ref remainingLength); return(subAckPacket); case Signatures.UnsubAck: if (_isServer) { ValidateClientPacketExpected(packetSignature); } var unsubAckPacket = new UnsubAckPacket(); DecodePacketIdVariableHeader(buffer, unsubAckPacket, ref remainingLength); return(unsubAckPacket); case Signatures.PingResp: if (_isServer) { ValidateClientPacketExpected(packetSignature); } return(PingRespPacket.Instance); default: return(ThrowHelper.FromDecoderException_FirstPacketByteValueIsInvalid(packetSignature)); } }
Packet DecodePacketInternal(IByteBuffer buffer, int packetSignature, ref int remainingLength, IChannelHandlerContext context) { 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) // strict match checks for valid message type + correct values in flags part { case Signatures.PubAck: var pubAckPacket = new PubAckPacket(); DecodePacketIdVariableHeader(buffer, pubAckPacket, ref remainingLength); return(pubAckPacket); case Signatures.PubRec: var pubRecPacket = new PubRecPacket(); DecodePacketIdVariableHeader(buffer, pubRecPacket, ref remainingLength); return(pubRecPacket); case Signatures.PubRel: var pubRelPacket = new PubRelPacket(); DecodePacketIdVariableHeader(buffer, pubRelPacket, ref remainingLength); return(pubRelPacket); case Signatures.PubComp: var pubCompPacket = new PubCompPacket(); DecodePacketIdVariableHeader(buffer, pubCompPacket, ref remainingLength); return(pubCompPacket); case Signatures.PingReq: this.ValidateServerPacketExpected(packetSignature); return(PingReqPacket.Instance); case Signatures.Subscribe: this.ValidateServerPacketExpected(packetSignature); var subscribePacket = new SubscribePacket(); DecodePacketIdVariableHeader(buffer, subscribePacket, ref remainingLength); DecodeSubscribePayload(buffer, subscribePacket, ref remainingLength); return(subscribePacket); case Signatures.Unsubscribe: this.ValidateServerPacketExpected(packetSignature); var unsubscribePacket = new UnsubscribePacket(); DecodePacketIdVariableHeader(buffer, unsubscribePacket, ref remainingLength); DecodeUnsubscribePayload(buffer, unsubscribePacket, ref remainingLength); return(unsubscribePacket); case Signatures.Connect: this.ValidateServerPacketExpected(packetSignature); var connectPacket = new ConnectPacket(); DecodeConnectPacket(buffer, connectPacket, ref remainingLength, context); return(connectPacket); case Signatures.Disconnect: this.ValidateServerPacketExpected(packetSignature); return(DisconnectPacket.Instance); case Signatures.ConnAck: this.ValidateClientPacketExpected(packetSignature); var connAckPacket = new ConnAckPacket(); DecodeConnAckPacket(buffer, connAckPacket, ref remainingLength); return(connAckPacket); case Signatures.SubAck: this.ValidateClientPacketExpected(packetSignature); var subAckPacket = new SubAckPacket(); DecodePacketIdVariableHeader(buffer, subAckPacket, ref remainingLength); DecodeSubAckPayload(buffer, subAckPacket, ref remainingLength); return(subAckPacket); case Signatures.UnsubAck: this.ValidateClientPacketExpected(packetSignature); var unsubAckPacket = new UnsubAckPacket(); DecodePacketIdVariableHeader(buffer, unsubAckPacket, ref remainingLength); return(unsubAckPacket); case Signatures.PingResp: this.ValidateClientPacketExpected(packetSignature); return(PingRespPacket.Instance); default: throw new DecoderException($"First packet byte value of `{packetSignature}` is invalid."); } }
static void DecodeConnectPacket(IByteBuffer buffer, ConnectPacket packet, ref int remainingLength, IChannelHandlerContext context) { string protocolName = DecodeString(buffer, ref remainingLength); if (!Util.ProtocolName.Equals(protocolName, StringComparison.Ordinal)) { throw new DecoderException($"Unexpected protocol name. Expected: {Util.ProtocolName}. Actual: {protocolName}"); } packet.ProtocolName = Util.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); Util.ValidateClientId(clientId); 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); } }
static void DecodeConnectPacket(IByteBuffer buffer, ConnectPacket packet, ref int remainingLength, IChannelHandlerContext context) { string protocolName = DecodeString(buffer, ref remainingLength); if (!string.Equals(Util.ProtocolName, protocolName #if NETCOREAPP_3_0_GREATER || NETSTANDARD_2_0_GREATER )) #else , StringComparison.Ordinal)) #endif { ThrowHelper.ThrowDecoderException_UnexpectedProtocolName(protocolName); } packet.ProtocolName = Util.ProtocolName; DecreaseRemainingLength(ref remainingLength, 1); packet.ProtocolLevel = buffer.ReadByte(); if (packet.ProtocolLevel != Util.ProtocolLevel) { var connAckPacket = new ConnAckPacket { ReturnCode = ConnectReturnCode.RefusedUnacceptableProtocolVersion }; context.WriteAndFlushAsync(connAckPacket); ThrowHelper.ThrowDecoderException_UnexpectedProtocolLevel(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; var willQualityOfService = packet.WillQualityOfService = (QualityOfService)((connectFlags & 0x18) >> 3); if (willQualityOfService == QualityOfService.Reserved) { ThrowHelper.ThrowDecoderException_UnexpectedWillQoSValueOf(willQualityOfService); } packet.WillTopicName = string.Empty; } else if ((connectFlags & 0x38) != 0) // bits 3,4,5 [MQTT-3.1.2-11] { ThrowHelper.ThrowDecoderException_MQTT_312_11(); } packet.HasUsername = (connectFlags & 0x80) == 0x80; packet.HasPassword = (connectFlags & 0x40) == 0x40; if (packet.HasPassword && !packet.HasUsername) { ThrowHelper.ThrowDecoderException_MQTT_312_22(); } if ((connectFlags & 0x1) != 0) // [MQTT-3.1.2-3] { ThrowHelper.ThrowDecoderException_MQTT_312_3(); } packet.KeepAliveInSeconds = DecodeUnsignedShort(buffer, ref remainingLength); string clientId = DecodeString(buffer, ref remainingLength); if (clientId is null) { Util.ValidateClientId(); } 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); } }