示例#1
0
        /// <summary>
        /// This function starts the watchdog. This method must be called after instantiating a watchdog
        /// in order for the watchdog to actually begin, umm, "watching". If the watchdog is paused by calling
        /// the Stop() method, then it may be resumed by calling this Start() method.
        /// </summary>
        /// <see cref="https://msdn.microsoft.com/en-us/library/ee482881(v=winembedded.60).aspx"/>
        public void Start()
        {
            if (_handle == IntPtr.Zero)
            {
                return;
            }

            // TRUE indicates success.
            if (!WinCeApi.StartWatchDogTimer(_handle, 0))
            {                                             // Failed
                _lastError = Marshal.GetLastWin32Error(); // only seems reliable if StartWatchDogTimer returns FALSE

                if (_lastError == ERROR_INVALID_HANDLE)
                {
                    Log.Error(string.Format("WATCHDOG: Failed to start \"{0}\" watchdog due to invalid handle, GetLastWin32Error={1}.", _name, _lastError));
                }
                else if (_lastError == ERROR_ALREADY_INITIALIZED)
                {
                    Log.Error(string.Format("WATCHDOG: Failed to start \"{0}\" watchdog as it was already initialized, GetLastWin32Error={1}.", _name, _lastError));
                }
                else
                {
                    Log.Error(string.Format("WATCHDOG: Failed to start \"{0}\" watchdog, GetLastWin32Error={1}.", _name, _lastError));
                }
            }
            else if (_logSuccessMsg)
            {             // Success
                Log.Debug(string.Format("WATCHDOG: Success starting watchdog \"{0}\" with a period of {1} seconds.", _name, _periodSeconds));
            }
        }
示例#2
0
            /// <summary>
            /// Return the system's current "boot vars"
            /// </summary>
            /// <returns></returns>
            static internal BootVars Load()
            {
                BootVars bootVars = new BootVars();

                bool success = false;

                try
                {
                    unsafe
                    {
                        success = bootvars_read(ref bootVars);    // Will set LastError on failure.
                    }

                    if (!success)
                    {
                        int lastError = WinCeApi.GetLastError();
                        throw new ConfigurationException(string.Format("Error {0} reading BootVars", lastError));
                    }
                }
                catch (ConfigurationException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    throw new ConfigurationException("Error reading BootVars", ex);
                }
                finally
                {
                    bootvars_deinit();
                }
                return(bootVars);
            }
示例#3
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="watchDogName">
        /// Name of the watchdog timer to be created. Every watchdog must have a unique name.
        /// </param>
        /// <param name="period">
        /// Watchdog period, in milliseconds. If the watchdog is not refreshed
        /// after 'period' milliseconds is elapsed,then the watchdog will initate a reboot.
        /// </param>
        /// <see cref="https://msdn.microsoft.com/en-US/library/ee482966(v=winembedded.60).aspx"/>
        public WatchDog(string name, int period, bool logSuccessMsg)
        {
            Log.Assert(string.IsNullOrEmpty(name) == false, "WatchDog 'name' must be specified.");
            Log.Assert(period > 0, "WatchDog 'period' must be specified.");

            _name          = name;
            _period        = period;
            _periodSeconds = period / 1000;
            _logSuccessMsg = logSuccessMsg;

// We can't let the watchdog run when using Visual Studio debugger,
// because the watchdog might reboot the device when we stop at a breakpoint.
#if DEBUG
            Log.Debug(string.Format("WATCHDOG: \"{0}\" not created because this is a Debug build.", name));
#else
            // A handle to the watchdog timer indicates success.
            _handle    = WinCeApi.CreateWatchDogTimer(name, period, 0, WinCeApi.WDOG_RESET_DEVICE, 0, 0);
            _lastError = Marshal.GetLastWin32Error();

            if (_handle == IntPtr.Zero)
            {
                Log.Error(string.Format("WATCHDOG: Failed to create watchdog \"{0}\", GetLastWin32Error={1}.", _name, _lastError));
            }
            else if (_lastError == ERROR_ALREADY_EXISTS)               // a new handle will be returned even if a watchdog with the same name exists
            {
                Log.Error(string.Format("WATCHDOG: Failed to create new watchdog as \"{0}\" already exists, GetLastWin32Error={1}.", _name, _lastError));
            }
            else if (_logSuccessMsg)               // error code of 0 is expected
            {
                Log.Debug(string.Format("WATCHDOG: Success creating watchdog \"{0}\", GetLastWin32Error={1}.", _name, _lastError));
            }
#endif
        }
示例#4
0
            /// <summary>
            /// Store the passed in "boot vars" as the system's current "boot vars".
            /// </summary>
            /// <param name="bootVars"></param>
            internal static void Save(BootVars bootVars)
            {
                bool success = false;

                try
                {
                    unsafe
                    {
                        success = bootvars_write(ref bootVars);   // Will set LastError on failure.
                    }

                    if (!success)
                    {
                        int lastError = WinCeApi.GetLastError();
                        throw new ConfigurationException(string.Format("Error {0} writing BootVars", lastError));
                    }
                }
                catch (ConfigurationException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    throw new ConfigurationException("Error writing BootVars", ex);
                }
                finally
                {
                    bootvars_deinit();
                }
            }
示例#5
0
        /// <summary>
        /// Checks a given pressure switch and returns.
        /// </summary>
        /// <param name="position">The position of the switch to check</param>
        /// <returns>True, if the pressure is good</returns>
        public static bool CheckPressureSwitch(int position)
        {
            if (!IsPressureSwitchPresent(position))
            {
                return(true);
            }

            int    success = 0;
            ushort data    = 0;

            for (int attempt = 1; attempt <= 10; attempt++)
            {
                unsafe
                {
                    success = GetPressureSwitchState(Convert.ToByte(position), &data);     // returns 1 on success, 0 on error
                }

                if (success != 0)   // success?
                {
                    break;
                }

                Log.Error(string.Format("Error calling GetPressureSwitchState({0}), attempt {1}, GetLastError={2}", position, attempt, WinCeApi.GetLastError()));
                Thread.Sleep(100);
            }

            if (success == 0)   // error?
            {
                int lastError = WinCeApi.GetLastError();
                Log.Error(string.Format("Failure in GetPressureSwitchState({0}), GetLastError={1}", position, lastError));
                throw new DeviceDriverException(DeviceHardware.PressureSwitchState, position, lastError);
            }

            return(data == 0);
        }
示例#6
0
        /// <summary>
        /// Returns a value indicating whether there is smart card present in a given slot.
        /// </summary>
        /// <param name="position">The card slot number</param>
        /// <returns>True if there is a card in the slot, 0 if not.</returns>
        public static bool IsCardPresent(int position)
        {
            ushort data  = 0;
            int    error = 0;

            for (int attempt = 1; attempt <= 10; attempt++)
            {
                unsafe
                {
                    error = GetSmartCardPresence(Convert.ToByte(position), &data);     // returns 1 on error, 0 on success
                }

                if (error == 0)   // success?
                {
                    break;
                }

                Log.Error(string.Format("Error calling GetSmartCardPresence({0}), attempt {1}, GetLastError={2}", position, attempt, WinCeApi.GetLastError()));
                Thread.Sleep(100);
            }

            if (error != 0)   // error?
            {
                int lastError = WinCeApi.GetLastError();
                Log.Error(string.Format("Failure in GetSmartCardPresence({0}), GetLastError={1}", position, lastError));
                throw new DeviceDriverException(DeviceHardware.SmartCardPresence, position, lastError);
            }

            return(data != 0);
        }
示例#7
0
        private byte [] _GetRandomBytes(byte[] seed)
        {
            IntPtr prov;
            bool   retVal = WinCeApi.CryptAcquireContext(out prov, null, null, (int)WinCeApi.SecurityProviderType.RSA_FULL, 0);

            retVal = _CryptGenRandom(prov, seed.Length, seed);
            WinCeApi.CryptReleaseContext(prov, 0);
            return(seed);
        }
示例#8
0
 private bool _CryptGenRandom(IntPtr hProv, int dwLen, byte[] pbBuffer)
 {
     if (System.Environment.OSVersion.Platform == PlatformID.WinCE)
     {
         return(WinCeApi.CryptGenRandomCe(hProv, dwLen, pbBuffer));
     }
     else
     {
         return(WinCeApi.CryptGenRandomXp(hProv, dwLen, pbBuffer));
     }
 }
示例#9
0
        /// <summary>
        /// This function refreshes ("pets") the watchdog.
        /// </summary>
        public void Refresh()
        {
            if (_handle == IntPtr.Zero)
            {
                return;
            }

            if (!WinCeApi.RefreshWatchDogTimer(_handle, 0))
            {
                Log.Error(string.Format("WATCHDOG: Failed to refresh watchdog \"{0}\", GetLastWin32Error={1}.", _name, Marshal.GetLastWin32Error()));
            }
        }
示例#10
0
        /// <summary>
        /// This function stops (pauses) the watchdog.
        /// </summary>
        /// <see cref="https://msdn.microsoft.com/en-us/library/ee482847(v=winembedded.60).aspx"/>
        public void Stop()
        {
            if (_handle == IntPtr.Zero)
            {
                return;
            }

            // Returns TRUE if the function succeeds.
            if (!WinCeApi.StopWatchDogTimer(_handle, 0))
            {                                             // Failed
                _lastError = Marshal.GetLastWin32Error(); // only seems reliable if StopWatchDogTimer returns FALSE
                Log.Error(string.Format("WATCHDOG: Failed to stop watchdog \"{0}\", GetLastWin32Error={1}.", _name, _lastError));
            }
            else if (_logSuccessMsg)
            {             // Success
                Log.Debug(string.Format("WATCHDOG: Success stopping watchdog \"{0}\".", _name));
            }
        }
示例#11
0
        /// <summary>
        /// This function releases the memory used by the watchdog timer.
        /// </summary>
        /// <see cref="https://msdn.microsoft.com/en-us/library/ee490442(v=winembedded.60).aspx"/>
        public void Close()
        {
            if (_handle == IntPtr.Zero)
            {
                return;
            }

            // Nonzero indicates success. Zero indicates failure.
            int result = WinCeApi.CloseHandle(_handle);

            if (result == 0)
            {                                             // Failed
                _lastError = Marshal.GetLastWin32Error(); // only seems reliable if CloseHandle returns 0
                Log.Error(string.Format("WATCHDOG: Failed to close watchdog \"{0}\", GetLastWin32Error={1}.", _name, _lastError));
            }
            else if (_logSuccessMsg)
            {             // Success
                Log.Debug(string.Format("WATCHDOG: Success({1}) closing watchdog \"{0}\".", _name, result));
            }
        }
示例#12
0
        // <summary>
        /// return a SHA1 Hash on PPC and Smartphone
        /// </summary>
        /// <param name="pass"></param>
        /// <returns></returns>
        public static byte[] Sha1Hash(byte[] pass)
        {
            IntPtr hProv;
            bool   retVal = WinCeApi.CryptAcquireContext(out hProv, null, null, (int)WinCeApi.SecurityProviderType.RSA_FULL, 0);
            IntPtr hHash;

            retVal = WinCeApi.CryptCreateHash(hProv, (int)WinCeApi.SecurityProviderType.CALG_SHA1, IntPtr.Zero, 0, out hHash);

            byte [] publicKey    = pass;
            int     publicKeyLen = publicKey.Length;

            retVal = WinCeApi.CryptHashData(hHash, publicKey, publicKeyLen, 0);
            int bufferLen = 20;             // SHA1 size

            byte [] buffer = new byte[bufferLen];
            retVal = WinCeApi.CryptGetHashParam(hHash, (int)WinCeApi.SecurityProviderType.HP_HASHVAL, buffer, ref bufferLen, 0);
            retVal = WinCeApi.CryptDestroyHash(hHash);
            retVal = WinCeApi.CryptReleaseContext(hProv, 0);

            return(buffer);
        }
示例#13
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="args"></param>
        private void Run(string[] args)
        {
            Thread.CurrentThread.Name = "Master";

            string applicationPath = Assembly.GetExecutingAssembly().GetName().CodeBase;

            Log.Info(Log.Dashes);
            Log.Info("STARTING " + applicationPath);
            foreach (string arg in args)
            {
                Log.Info(string.Format("arg: \"{0}\"", arg));
            }
            Log.Debug(Thread.CurrentThread.Name + " ThreadId=" + Thread.CurrentThread.ManagedThreadId.ToString("x8"));
            Log.Info(Log.Dashes);

            // We want the Controller class to load now, so that it's static
            // constructor reads the config file.  It's important to do this
            // before starting ANY of the service threads. Calling any
            // random property of the Controller class will cause the class to load.

            Controller.ApplicationPath = applicationPath;

            // Stop the pump and speaker on startup.  This is primarily done because if
            // the debugger is stopped then restarted while the pump or speaker are on, then they're left on.
            // if we don't do this...
            Controller.TurnBuzzerOff();
            Pump.Stop();

            // Instantiate the console service immediately so that we can display
            // the "Starting" message ASAP. Note that we don't yet start the thread,
            // though, since we don't need (yet), to monitor for keypad input.
            LCD.Clear(); // This is the first time we're accessing the LCD class, so it's static constructor will be called here.
            LCD.SetLanguage(Configuration.DockingStation.Language);

            Controller.LastRebootTime = DateTime.UtcNow;

            Controller.FirmwareVersion = string.Format("{0}.{1}.{2}.{3}",
                                                       Assembly.GetExecutingAssembly().GetName().Version.Major,
                                                       Assembly.GetExecutingAssembly().GetName().Version.Minor,
                                                       Assembly.GetExecutingAssembly().GetName().Version.Build,
                                                       Assembly.GetExecutingAssembly().GetName().Version.Revision);

            _consoleService = new ConsoleService(this);
            Log.Debug(ConsoleService.Name + " has been created.");

            ConsoleService.Start();
            // Calling InitializeState now will force the display to refresh and say "Starting"
            // right away. If we don't do this, it remains blank for a second or two.
            ConsoleService.InitializeState();

            try
            {
                Configuration.ServiceMode = Controller.DetermineServiceMode();
            }
            catch (Exception e)
            {
                Log.Error(e);
            }

            // Did something go wrong trying to read the configuration data from the flash memory?
            if (Configuration.HasConfigurationError && Configuration.DockingStation.IsSerialized())
            {
                Controller.RunState |= Controller.State.ConfigError;
            }

            // Verify that we have a flash card.  We can't do much of anything without one.
            bool haveFlashCard = FlashCard.WaitForMount();

            if (haveFlashCard)
            {
                Log.Info("Found a mounted flash card");
            }
            else
            {
                Log.Fatal("ERROR: FLASH CARD NOT FOUND.");
                Controller.RunState |= Controller.State.FlashCardError;
            }

            Log.Info(Log.Dashes);
            Log.Info("Firmware Version: " + Controller.FirmwareVersion);
            Log.Info(Log.Dashes);
            Controller.LogSystemInfo();
            Log.Info(Log.Dashes);
            Controller.LogProcessorInfo();
            Log.Info(Log.Dashes);
            Controller.LogMemory();
            Log.Info(Log.Dashes);
            if (haveFlashCard)
            {
                FlashCard.Log();
                Log.Info(Log.Dashes);
            }
            Log.Info("MAC Address: " + Controller.GetWiredNetworkAdapter().MacAddress);
            Log.Info(Log.Dashes);

            if (haveFlashCard)
            {
                DataAccess.DataAccess.StartInet();
                DataAccess.DataAccess.StartInetQueue();
            }

            // Before we can start the WebAppService, we need to initialize
            // the password used to login to it.
            // Note that for debug builds, we configure it to not use SLL.
            // There are two reasons for this...
            // 1) SSL slows done iNet DS Configurator, which is annoying
            // when we developers are constantly logging into it to use it.
            // 2) There is some sort of problem when Padarn is using SSL
            // that causes the Visual Studio debugger to lose its connections
            // to the device.
#if DEBUG
            Configuration.ConfigureWebApp(Configuration.DockingStation.WebAppPassword, false);
#else
            Configuration.ConfigureWebApp(Configuration.DockingStation.WebAppPassword, true);
#endif

            if (Controller.RunState == Controller.State.OK)
            {
                InitializeWinsock();
            }

            // AJAY: INS-8380 Service accounts need to perform auto-upgrade on instruments even in error/fail state - DSX
            // If service account is configured to override event priority in admin console,
            // this method reorders events that needs to be executed on docking station.
            if (Configuration.IsRepairAccount() && Configuration.DockingStation.UpgradeOnErrorFail)
            {
                ISC.iNet.DS.DomainModel.EventCode.SetEventPriorityForService();
            }

            // Initialize, wire up and start all necessary services.
            // Note that this will be iterated every time any of the
            // services gets interrupted.

            // Create the services.
            Log.Debug("Creating services...");

            _resourceService = new ResourceService(this);
            Log.Debug(ResourceService.Name + " has been created.");

            _reporterService = new ReporterService(this);
            Log.Debug(ReporterService.Name + " has been created.");

            _executerService = new ExecuterService(this);
            Log.Debug(ExecuterService.Name + " has been created.");

            _switchService = new SwitchService(this);
            Log.Debug(SwitchService.Name + " has been created.");

            _chargingService = new ChargingService(this);
            Log.Debug(ChargingService.Name + " has been created.");

            _webAppService = new WebAppService(this);
            Log.Debug(WebAppService.Name + " has been created.");

            _controllerWrapper = ControllerWrapper.Instance;

            _pumpWrapper = PumpManager.Instance;

            _lcdWrapper = LCDWrapper.Instance;

            _smartCardWrapper = SmartCardWrapper.Instance;

            // Start the services.
            Log.Debug("Starting service threads...");

            if (Controller.RunState == Controller.State.OK)
            {
                ResourceService.Start();
            }

            // Don't start the Switch, Charging, or Executer service if the DS has
            // not been serialized.  Only the Configurator web app will be functional.
            if (Configuration.DockingStation.IsSerialized())
            {
                ExecuterService.Start();

                if (Controller.RunState == Controller.State.OK)
                {
                    SwitchService.Start();
                }

                if (Controller.RunState == Controller.State.OK)
                {
                    ChargingService.Start();
                }
            }
            else
            {
                // update the LCD
                ConsoleService.UpdateState(ConsoleState.NotSerialized);
            }

            if (Controller.RunState == Controller.State.OK)
            {
                ReporterService.Start();
            }

            WebAppService.Start();

            Log.Debug("Service threads started.");

            // the controller's static constructor will initialize the other logging settings,
            // but we always want to log all the initialization stuff above out the serial port
            Log.LogToSerialPort = Configuration.ServiceMode ? true : Configuration.DockingStation.LogToSerialPort;             // always log in service mode

            // Determine if sequenceId passed in as argument. This is number that will be automatically
            // passed in as an argument to the process when Windows CE boots the device.  If process
            // is manually started, then no sequence ID will be passed.  If sequenceId is passed in,
            // then process MUST call SignalStarted when it feels that it's safely up and running
            // in order to continue with the proper boot sequence.
            if (args.Length > 0)
            {
                uint sequenceId = 0;
                try
                {
                    sequenceId = UInt32.Parse(args[0]);
                }
                catch
                {
                    Log.Debug("Invalid sequenceId (" + args[0] + ") found.  SignalStarted not called.");
                }
                if (sequenceId > 0)
                {
                    Log.Debug("SignalStarted(" + sequenceId + ")");
                    WinCeApi.SignalStarted(sequenceId);
                }
            }

            // INS-6183, 6/8/2015 - This watchdog is used in the below while-loop. The  while-loop
            // periodically calls MonitorNetworkConnection(), which calls GetWiredNetworkAdapter(),
            // which calls GetNetworkAdapters().  GetNetworkAdapters() makes a call to OpenNetCF
            // SDF's GetAllNetworkInterfaces() to get the networking info from the OS.
            // Sometimes that call throws a Data Abort (unmanaged exception).  Unmanaged exceptions
            // cannot be caught in .Net, so the exception is thrown outside and above the application,
            // which causes OS to display a message box informing of the Data Abort.  The message box
            // waits for a user to press its OK button, so the thread that threw the Data Abort is
            // effectly hung waiting for somebody to press an OK button which is never going to happen.
            // The data abort may be thrown by a thread other this Master thread. But this watchdog
            // for the master thread should still work in that situation.  This is because the
            // aforementioned GetNetworkAdapters has a "lock" block in it. If another thread calls
            // GetNetworkAdapters, it will a obtain a lock, then call into SDF's GetAllNetworkInterfaces.
            // If the data abort is then thrown, then GetNetworkAdapters will not have a chance to
            // release its lock. Then, next time master thread trys to call GetNetworkAdapters, it will
            // hang trying to obtain a lock, which it will never be able to do, so the watchdog timer
            // will eventually expire, causing a reboot, as desired.
            WatchDog watchDog = new WatchDog("MasterWatchDog", 60000, Log.LogToFile);               // reboot if not refreshed in 60 seconds.
            watchDog.Start();

            ///////////////////////////////////////////////////////////////////////
            // Used for smart card debugging.  Please leave this code here for now.
            ///////////////////////////////////////////////////////////////////////
            //            I2CTestThread i2cTest= new I2CTestThread();
            //            i2cTest.StartWork();

            MonitorNetworkConnection();

            Controller.LogMemoryUsage();

            // Now that we've fired off the child worker threads, we have nothing more to do
            // except hang out and stay alive.  Lower our priority and take a nap.
            //Thread.CurrentThread.Priority = ThreadPriority.BelowNormal;
            int sleepTime = 5000;
            int lastCheck = 0;

            while (true)
            {
                Thread.Sleep(sleepTime);

                lastCheck += sleepTime;

                if (lastCheck >= 300000)                   // 5 minutes
                {
                    MonitorNetworkConnection();

                    //Logger.Debug( "Total Up Time: " + ( runTime / 1000 ) + " seconds" );
                    //Controller.LogMemoryUsage();
                    lastCheck = 0;
                }

                if (Controller.RunState != Controller.State.OK)
                {
                    string errNum = ((int)Controller.RunState).ToString("x8");
                    // If a menu is active, skip the operation for now. (the only menu that should
                    // possibly ever be active is the factory reset confirmation menu).
                    if (!ConsoleService.IsMenuActive)
                    {
                        Log.Trace("SYSTEM ERROR ENCOUNTERED with error number " + errNum);

                        if (errNum.Equals("00000001"))
                        {
                            ConsoleService.UpdateState(ConsoleState.ContactISCCode1011);
                        }
                        else if (errNum.Equals("00000002"))
                        {
                            ConsoleService.UpdateState(ConsoleState.ContactISCCode1012);
                        }
                        else if (errNum.Equals("00000004"))
                        {
                            ConsoleService.UpdateState(ConsoleState.ContactISCCode1014);
                        }
                        else if (errNum.Equals("00000008"))
                        {
                            ConsoleService.UpdateState(ConsoleState.ContactISCCode1018);
                        }
                        else if (errNum.Equals("00000010"))
                        {
                            ConsoleService.UpdateState(ConsoleState.ContactISCCode10110);
                        }
                        else
                        {
                            ConsoleService.UpdateState(ConsoleState.ContactISCCode10160);
                        }
                    }
                }

                if (lastCheck == 0 || lastCheck >= 10000)
                {
                    watchDog.Refresh();
                }
            }
        } // end-Run