public void Accept(NotifyStatusOperation operation)
            {
                AssignmentStateMachine stateMachine = AssertStateMachineIsAssigned(assignmentStateMachine);

                stateMachine.ExecuteIfInPhase <PhaseWaitingForSetupResponse>(phase =>
                                                                             phase.NewAddress == operation.OriginatingAddress ? new PhaseAssignmentCompleted(null) : null);
            }
            public void Accept(KeepAliveOperation operation)
            {
                AssignmentStateMachine stateMachine = AssertStateMachineIsAssigned(assignmentStateMachine);

                bool transitioned = stateMachine.ExecuteIfInPhase <PhaseWaitingForLoginResponse>(_ => new PhaseReadyForDeviceSetup(operation.MediatorStatus));

                if (!transitioned)
                {
                    stateMachine.ExecuteIfInPhase <PhaseWaitingForSetupResponse>(_ =>
                                                                                 owner.IsConfiguringMediator ? (AssignmentPhase) new PhaseAssignmentCompleted(operation.MediatorStatus) : null);
                }
            }
        public void Run()
        {
            var stateMachine = new AssignmentStateMachine(new PhaseWaitingForConnection());
            CirceComConnection connection = null;

            Log.Info($"Connecting to mediator on {startupArguments.ComPortName}...");
            stateMachine.ExecuteIfInPhase<PhaseWaitingForConnection>(phase =>
            {
                connection = new CirceComConnection(startupArguments.ComPortName);
                connection.OperationReceived +=
                    (sender, eventArgs) => ConnectionOperationReceived(eventArgs, stateMachine);
                connection.Open();
                connection.Send(new LoginOperation());

                return new PhaseWaitingForLoginResponse();
            });

            Log.Info("Waiting for login response...");
            var readyForDeviceSetup = stateMachine.WaitForPhase<PhaseReadyForDeviceSetup>();
            Log.Info($"Mediator status in login response: {readyForDeviceSetup.MediatorStatus}.");

            if (!IsConfiguringMediator &&
                readyForDeviceSetup.MediatorStatus == KnownMediatorStatusCode.MediatorUnconfigured)
            {
                Log.Info("ERROR: Connected to unconfigured mediator. Please configure mediator first.");
                return;
            }

            Log.Info("Sending address assignment...");
            stateMachine.ExecuteIfInPhase<PhaseReadyForDeviceSetup>(phase1 =>
            {
                connection.Send(new DeviceSetupOperation(startupArguments.NewAddress)
                {
                    DestinationAddress = startupArguments.OldAddress,
                    Capabilities = startupArguments.Capabilities
                });

                return new PhaseWaitingForSetupResponse(startupArguments.NewAddress);
            });

            Log.Info("Waiting for response from new device...");
            var assignmentCompleted = stateMachine.WaitForPhase<PhaseAssignmentCompleted>();

            Log.Info(assignmentCompleted.MediatorStatus == KnownMediatorStatusCode.MediatorUnconfigured
                ? "ERROR: Failed to assign mediator address."
                : "Received response on new address.");

            Log.Info("Disconnecting...");
            connection.Send(new LogoutOperation());
        }
 public void SetStateMachine([NotNull] AssignmentStateMachine stateMachine)
 {
     Guard.NotNull(stateMachine, nameof(stateMachine));
     assignmentStateMachine = stateMachine;
 }
 public void SetStateMachine(AssignmentStateMachine stateMachine)
 {
     Guard.NotNull(stateMachine, nameof(stateMachine));
     assignmentStateMachine = stateMachine;
 }