/// <summary>
        ///     Runs polling loop this many times at a minimum.
        ///     Due to timing limitations, this is a minimum run count
        ///     and their may be 1 or more extra loops executed.
        /// </summary>
        /// <param name="loops">Loops to run</param>
        /// <returns></returns>
        public T RunIdleFor(int loops)
        {
            // Setup a semaphore to wait for this many polling loops
            var sem = new EmulationLoopSemaphore(_token)
            {
                SignalAt = loops
            };

            _emulator.OnPollResponseSent += sem.LoopCallback;
            sem.OnLoopCalled             += (sender, args) =>
            {
                // Always be idle
                _emulator.CurrentState = Rs232State.Idling;
            };

            // Create a new validator so we have perfect control of the state
            var validator = new ApexValidator(Config);

            validator.StartPollingLoop();

            // Wait for signal
            sem.Gate.WaitOne();

            // Cleanup
            validator.StopPollingLoop();
            _emulator.OnPollResponseSent -= sem.LoopCallback;

            return(_emulator);
        }
        /// <summary>
        ///     Every n loops, issue the specified credit value
        /// </summary>
        /// <param name="loops">Count of loops between credits</param>
        /// <param name="count">Run this many times. -1 to loop forever.</param>
        /// <param name="creditIndices">Credits to issue</param>
        public T CreditEveryNLoops(int loops, int count, params byte[] creditIndices)
        {
            // Create a new validator so we have perfect control of the state
            var validator = new ApexValidator(Config);

            // Setup a semaphore to wait for this many polling loops
            var sem = new EmulationLoopSemaphore(_token)
            {
                SignalAt = loops * count
            };

            // Start in idling state
            _emulator.CurrentState  = Rs232State.Idling;
            _emulator.CurrentEvents = Rs232Event.None;

            var next = 0;

            _emulator.OnPollResponseSent += sem.LoopCallback;
            sem.OnLoopCalled             += (sender, args) =>
            {
                switch (_emulator.CurrentState)
                {
                case Rs232State.None:
                    _emulator.CurrentState  = Rs232State.Idling;
                    _emulator.CurrentEvents = Rs232Event.None;
                    break;

                case Rs232State.Idling:
                    if (sem.Iterations % loops == 0)
                    {
                        _emulator.CurrentState  = Rs232State.Accepting;
                        _emulator.CurrentEvents = Rs232Event.None;
                    }

                    break;

                case Rs232State.Accepting:
                    _emulator.CurrentState  = Rs232State.Stacking;
                    _emulator.CurrentEvents = Rs232Event.None;
                    break;

                case Rs232State.Stacking:
                    _emulator.CurrentState  = Rs232State.Idling;
                    _emulator.CurrentEvents = Rs232Event.Stacked;
                    _emulator.Credit        = creditIndices[next++ % creditIndices.Length];
                    break;
                }
            };

            validator.StartPollingLoop();

            // Wait for signal
            sem.Gate.WaitOne();

            // Cleanup
            validator.StopPollingLoop();
            _emulator.OnPollResponseSent -= sem.LoopCallback;

            return(_emulator);
        }
        /// <summary>
        ///     Run a real bill validator
        /// </summary>
        /// <param name="logger">Logger attaches to validator</param>
        /// <param name="args">Program arguments</param>
        private static void RunValidator(ILogger logger, string[] args)
        {
            var portName = args.FirstOrDefault();

            if (string.IsNullOrEmpty(portName))
            {
                Console.WriteLine("Usage: rs232validator.cli.exe portName");
                return;
            }


            var config = Rs232Config.UsbRs232Config(portName, logger);

            var validator = new ApexValidator(config);

            validator.OnLostConnection += (sender, eventArgs) =>
            {
                config.Logger?.Error($"[APP] Lost connection to acceptor");
            };

            validator.OnBillInEscrow += (sender, i) =>
            {
                // For USA this index represent $20. This example will always return a $20
                // Alternatively you could set the Rs232Config mask to 0x5F to disable a 20.
                if (i == 5)
                {
                    config.Logger.Info($"[APP] Issuing a return command for this {BillValues[i]}");

                    validator.Return();
                }
                else
                {
                    config.Logger.Info($"[APP] Issuing stack command for this {BillValues[i]}");

                    validator.Stack();
                }
            };

            validator.OnCreditIndexReported += (sender, i) =>
            {
                config.Logger.Info($"[APP] Credit issued: {BillValues[i]}");
            };

            validator.OnStateChanged += (sender, state) =>
            {
                config.Logger.Info($"[APP] State changed from {state.OldState} to {state.NewState}");
            };

            validator.OnEventReported += (sender, evt) => { config.Logger.Info($"[APP] Event(s) reported: {evt}"); };

            validator.OnCashBoxRemoved += (sender, eventArgs) => { config.Logger.Info("[APP] Cash box removed"); };

            validator.OnCashBoxAttached += (sender, eventArgs) => { config.Logger.Info("[APP] Cash box attached"); };

            if (!validator.StartPollingLoop())
            {
                config.Logger.Error("[APP] Failed to start RS232 main loop");
                return;
            }

            config.Logger.Info("[APP] Validator is now running. CTRL+C to Exit");
            while (true)
            {
                Thread.Sleep(TimeSpan.FromMilliseconds(100));

                if (!validator.IsUnresponsive)
                {
                    continue;
                }

                config.Logger?.Error("[APP] validator failed to start. Quitting now");

                validator.StopPollingLoop();

                break;
            }
        }
Exemplo n.º 4
0
        private static void Main(string[] args)
        {
            var portName = args.FirstOrDefault();

            if (string.IsNullOrEmpty(portName))
            {
                Console.WriteLine("Usage: app portName");
                return;
            }

            var logger = new ConsoleLogger {
                Level = 3
            };
            var config = Rs232Config.UsbRs232Config(portName, logger);

            var validator = new ApexValidator(config);

            validator.OnLostConnection += (sender, eventArgs) =>
            {
                config.Logger?.Error($"[APP] Lost connection to acceptor");
            };

            validator.OnCreditIndexReported += (sender, i) =>
            {
                config.Logger.Info($"[APP] Credit issued: {BillValues[i]}");
            };

            validator.OnStateChanged += (sender, state) =>
            {
                config.Logger.Info($"[APP] State changed from {state.OldState} to {state.NewState}");
            };

            validator.OnEventReported += (sender, evt) => { config.Logger.Info($"[APP] Event(s) reported: {evt}"); };

            validator.OnCashBoxRemoved += (sender, eventArgs) => { config.Logger.Info("[APP] Cash box removed"); };

            validator.OnCashBoxAttached += (sender, eventArgs) => { config.Logger.Info("[APP] Cash box attached"); };

            if (!validator.StartPollingLoop())
            {
                config.Logger.Error("[APP] Failed to start RS232 main loop");
                return;
            }

            config.Logger.Info("[APP] Validator is now running. CTRL+C to Exit");
            while (true)
            {
                Thread.Sleep(TimeSpan.FromMilliseconds(100));

                if (!validator.IsUnresponsive)
                {
                    continue;
                }

                config.Logger?.Error("[APP] validator failed to start. Quitting now");

                validator.StopPollingLoop();

                break;
            }
        }