private async Task ProcessConnectAckAsync()

in iothub/device/src/Transport/Mqtt/MqttIotHubAdapter.cs [518:588]


        private async Task ProcessConnectAckAsync(IChannelHandlerContext context, ConnAckPacket packet)
        {
            if (Logging.IsEnabled)
                Logging.Enter(this, context.Name, packet, nameof(ProcessConnectAckAsync));

            if (Logging.IsEnabled)
                Logging.Info(this, $"ConnAckPacket.ReturnCode={packet.ReturnCode}", nameof(ProcessConnectAckAsync));

            if (packet.ReturnCode != ConnectReturnCode.Accepted)
            {
                string reason = "CONNECT failed: " + packet.ReturnCode;
                IotHubException iotHubException;

                switch (packet.ReturnCode)
                {
                    // A Connect return code of RefusedServerUnavailable should be retried, so it is mapped to IotHubCommunicationException.
                    case ConnectReturnCode.RefusedServerUnavailable:
                        if (Logging.IsEnabled)
                            Logging.Error(this, "The endpoint server was unavailable while attempting a CONNECT, will shut down.", nameof(ProcessConnectAckAsync));

                        iotHubException = new IotHubCommunicationException(reason);
                        ShutdownOnErrorAsync(context, iotHubException);
                        return;

                    // These return codes indicate incorrect credentials being supplied, they are mapped to UnauthorizedException.
                    case ConnectReturnCode.RefusedNotAuthorized:
                    case ConnectReturnCode.RefusedBadUsernameOrPassword:
                        if (Logging.IsEnabled)
                            Logging.Error(this, "Invalid credentials were provided while attempting a CONNECT, will shut down.", nameof(ProcessConnectAckAsync));

                        iotHubException = new UnauthorizedException(reason);
                        ShutdownOnErrorAsync(context, iotHubException);
                        return;

                    // These return codes are non-retryable, they are mapped to IotHubException.
                    case ConnectReturnCode.RefusedIdentifierRejected:
                    case ConnectReturnCode.RefusedUnacceptableProtocolVersion:
                        if (Logging.IsEnabled)
                            Logging.Error(this, "Invalid MQTT specification was provided while attempting a CONNECT, will shut down.", nameof(ProcessConnectAckAsync));

                        iotHubException = new IotHubException(reason);
                        ShutdownOnErrorAsync(context, iotHubException);
                        return;
                }
            }

            if (!IsInState(StateFlags.Connecting))
            {
                if (Logging.IsEnabled)
                    Logging.Error(this, "A CONNECT packet was received while the connection was already open, will shut down.", nameof(ProcessConnectAckAsync));

                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);
                ShutdownOnErrorAsync(context, iotHubException);
                return;
            }

            _stateFlags = StateFlags.Connected;

            _mqttIotHubEventHandler.OnConnected();

            ResumeReadingIfNecessary(context);

            if (packet.SessionPresent)
            {
                await SubscribeAsync(context, null).ConfigureAwait(true);
            }

            if (Logging.IsEnabled)
                Logging.Exit(this, context.Name, packet, nameof(ProcessConnectAckAsync));
        }