Beispiel #1
0
        /// <summary>
        /// Stop the device read thread.
        /// </summary>
        private void StopReadThread()
        {
            DebugWriteLine("StopReadThread()");

            if (_readThread == null)
            {
                DebugWriteLine("Read thread already stopped");
                return;
            }

            try
            {
                _readThreadMode = ReadThreadMode.Stop;
                _stopReadThread.Set();
                if (Thread.CurrentThread != _readThread)
                {
                    _readThread.Join(PacketTimeout * 2);
                }

                //_readThread.Abort();
            }
            catch (Exception ex)
            {
                DebugWriteLine(ex.ToString());
            }
            finally
            {
                _stopReadThread.Close();
                _stopReadThread = null;

                _readThread = null;
            }
        }
Beispiel #2
0
        /// <summary>
        /// Learn an IR Command.
        /// </summary>
        /// <param name="learnTimeout">How long to wait before aborting learn.</param>
        /// <param name="learned">Newly learned IR Command.</param>
        /// <returns>Learn status.</returns>
        public override LearnStatus Learn(int learnTimeout, out IrCode learned)
        {
            DebugWriteLine("Learn()");

            learned       = null;
            _learningCode = new IrCode();

            SetInputPort(InputPort.Learning);

            int learnStartTick = Environment.TickCount;

            _readThreadMode = ReadThreadMode.Learning;

            // Wait for the learning to finish ...
            while (_readThreadMode == ReadThreadMode.Learning && Environment.TickCount < learnStartTick + learnTimeout)
            {
                Thread.Sleep(PacketTimeout);
            }

            DebugWriteLine("End Learn");

            ReadThreadMode modeWas = _readThreadMode;

            _readThreadMode = ReadThreadMode.Receiving;
            SetInputPort(InputPort.Receive);

            LearnStatus status = LearnStatus.Failure;

            switch (modeWas)
            {
            case ReadThreadMode.Learning:
                status = LearnStatus.Timeout;
                break;

            case ReadThreadMode.LearningFailed:
                status = LearnStatus.Failure;
                break;

            case ReadThreadMode.LearningDone:
                DebugDump(_learningCode.TimingData);
                if (_learningCode.FinalizeData())
                {
                    learned = _learningCode;
                    status  = LearnStatus.Success;
                }
                break;
            }

            _learningCode = null;
            return(status);
        }
Beispiel #3
0
        /// <summary>
        /// Start the device read thread.
        /// </summary>
        private void StartReadThread()
        {
            DebugWriteLine("StartReadThread()");

            if (_readThread != null)
            {
                DebugWriteLine("Read thread already started");
                return;
            }

            _stopReadThread = new ManualResetEvent(false);
            _readThreadMode = ReadThreadMode.Receiving;

            _readThread              = new Thread(ReadThread);
            _readThread.Name         = "MicrosoftMceTransceiver.DriverReplacement.ReadThread";
            _readThread.IsBackground = true;
            _readThread.Start();
        }
Beispiel #4
0
    /// <summary>
    /// Restart the device read thread.
    /// </summary>
    private void RestartReadThread(ReadThreadMode mode)
    {
      // Alternative to StopReadThread() ... StartReadThread(). Avoids Thread.Abort.

      _readThreadModeNext = mode;
      int numTriesLeft = MaxReadThreadTries;

      // Simple, optimistic wait for read thread to respond. Has room for improvement, but tends to work first time in practice.
      while (_readThreadMode != _readThreadModeNext && numTriesLeft-- != 0)
      {
        // Unblocks read thread, typically with Operation Aborted error. May cause Bad Command error in either thread.
        StopReceive();
        Thread.Sleep(ReadThreadTimeout);
      }

      if (numTriesLeft == 0)
        throw new InvalidOperationException("Failed to cycle read thread");
    }
Beispiel #5
0
    /// <summary>
    /// Start the device read thread.
    /// </summary>
    private void StartReadThread(ReadThreadMode mode)
    {
      DebugWriteLine("StartReadThread({0})", Enum.GetName(typeof(ReadThreadMode), mode));

      if (_readThread != null && _readThread.IsAlive)
      {
        DebugWriteLine("Read thread already started");
        return;
      }

      _deviceReceiveStarted = false;
      _readThreadModeNext = mode;

      _readThread = new Thread(ReadThread)
                      {
                        Name = "MicrosoftMceTransceiver.DriverVista.ReadThread",
                        IsBackground = true
                      };
      _readThread.Start();
    }
        /// <summary>
        /// Stop the device read thread.
        /// </summary>
        private void StopReadThread()
        {
            Log.Trace("StopReadThread()");

            if (_readThread == null)
            {
                Log.Info("Read thread already stopped");
                return;
            }

            try
            {
                _readThreadMode = ReadThreadMode.Stop;
                _stopReadThread.Set();
                if (Thread.CurrentThread != _readThread)
                    _readThread.Join(PacketTimeout * 2);

                //_readThread.Abort();
            }
            catch (Exception ex)
            {
                Log.Warn(ex);
            }
            finally
            {
                _stopReadThread.Close();
                _stopReadThread = null;

                _readThread = null;
            }
        }
        /// <summary>
        /// Start the device read thread.
        /// </summary>
        private void StartReadThread()
        {
            Log.Trace("StartReadThread()");

            if (_readThread != null)
            {
                Log.Info("Read thread already started");
                return;
            }

            _stopReadThread = new ManualResetEvent(false);
            _readThreadMode = ReadThreadMode.Receiving;

            _readThread = new Thread(ReadThread)
                              {
                                  Name = "MicrosoftMceTransceiver.DriverReplacement.ReadThread",
                                  IsBackground = true
                              };
            _readThread.Start();

            FireStateChanged(new StateChangedEventArgs(RunningState.Started));
        }
        /// <summary>
        /// Device read thread method.
        /// </summary>
        private void ReadThread()
        {
            byte[] packetBytes;

            WaitHandle waitHandle = new ManualResetEvent(false);
            SafeHandle safeWaitHandle = waitHandle.SafeWaitHandle;
            var waitHandles = new WaitHandle[] { waitHandle, _stopReadThread };

            var deviceBufferPtr = IntPtr.Zero;

            var success = false;
            safeWaitHandle.DangerousAddRef(ref success);
            if (!success)
                throw new InvalidOperationException("Failed to initialize safe wait handle");

            try
            {
                var dangerousWaitHandle = safeWaitHandle.DangerousGetHandle();

                var overlapped = new DeviceIoOverlapped();
                overlapped.ClearAndSetEvent(dangerousWaitHandle);

                deviceBufferPtr = Marshal.AllocHGlobal(DeviceBufferSize);

                while (_readThreadMode != ReadThreadMode.Stop)
                {
                    int lastError;
                    int bytesRead;

                    var readDevice = ReadFile(_readHandle, deviceBufferPtr, DeviceBufferSize, out bytesRead,
                                              overlapped.Overlapped);
                    lastError = Marshal.GetLastWin32Error();

                    switch (_readThreadMode)
                    {
                        case ReadThreadMode.Receiving:
                            FireStateChanged(new StateChangedEventArgs(RunningState.Started, ReceivingState.Receiving));
                            break;
                        case ReadThreadMode.Learning:
                            FireStateChanged(new StateChangedEventArgs(RunningState.Started, ReceivingState.Learning));
                            break;
                    }

                    if (!readDevice)
                    {
                        if (lastError != ErrorSuccess && lastError != ErrorIoPending)
                            throw new Win32Exception(lastError);

                        while (true)
                        {
                            var handle = WaitHandle.WaitAny(waitHandles, 2*PacketTimeout, false);

                            if (handle == ErrorWaitTimeout)
                                continue;

                            if (handle == 0)
                                break;

                            if (handle == 1)
                                throw new ThreadInterruptedException("Read thread stopping by request");

                            throw new InvalidOperationException(String.Format("Invalid wait handle return: {0}", handle));
                        }

                        var getOverlapped = GetOverlappedResult(_readHandle, overlapped.Overlapped, out bytesRead, true);
                        lastError = Marshal.GetLastWin32Error();

                        if (!getOverlapped && lastError != ErrorSuccess)
                            throw new Win32Exception(lastError);
                    }

                    if (bytesRead == 0)
                        continue;

                    packetBytes = new byte[bytesRead];
                    Marshal.Copy(deviceBufferPtr, packetBytes, 0, bytesRead);

                    Log.Trace("Received bytes ({0}): ", bytesRead);
                    Log.WriteArray(LogLevel.Trace, packetBytes);

                    int[] timingData = null;

                    if (_decodeCarry != 0 || packetBytes[0] >= 0x81 && packetBytes[0] <= 0x9E)
                    {
                        timingData = GetTimingDataFromPacket(packetBytes);
                    }
                    else
                    {
                        double firmware = 0.0;

                        var indexOfFF = Array.IndexOf(packetBytes, (byte) 0xFF);
                        while (indexOfFF != -1)
                        {
                            if (packetBytes.Length > indexOfFF + 2 && packetBytes[indexOfFF + 1] == 0x0B)
                                // FF 0B XY - Firmware X.Y00
                            {
                                byte b1 = packetBytes[indexOfFF + 2];

                                firmware += (b1 >> 4) + (0.1*(b1 & 0x0F));
                                Log.Debug("Firmware: {0}", firmware);
                            }

                            if (packetBytes.Length > indexOfFF + 2 && packetBytes[indexOfFF + 1] == 0x1B)
                                // FF 1B XY - Firmware 0.0XY
                            {
                                byte b1 = packetBytes[indexOfFF + 2];

                                firmware += (0.01*(b1 >> 4)) + (0.001*(b1 & 0x0F));
                                Log.Debug("Firmware: {0}", firmware);
                            }

                            if (packetBytes.Length > indexOfFF + 1)
                                indexOfFF = Array.IndexOf(packetBytes, (byte) 0xFF, indexOfFF + 1);
                            else
                                break;
                        }
                    }

                    switch (_readThreadMode)
                    {
                        case ReadThreadMode.Receiving:
                            {
                                var code = new IRCode(timingData);
                                code.FinalizeData();
                                FireCodeReceived(new CodeReceivedEventArgs(code));
                                break;
                            }

                        case ReadThreadMode.Learning:
                            {
                                if (timingData == null)
                                {
                                    if (_learningCode.TimingData.Length > 0)
                                    {
                                        _learningCode = null;
                                        _readThreadMode = ReadThreadMode.LearningFailed;
                                    }
                                    break;
                                }

                                if (_learningCode == null)
                                    throw new InvalidOperationException(
                                        "Learning not initialised correctly, _learningCode object is null");

                                _learningCode.AddTimingData(timingData);

                                // Example: 9F 01 02 9F 15 00 BE 80
                                var indexOf9F = Array.IndexOf(packetBytes, (byte) 0x9F);
                                while (indexOf9F != -1)
                                {
                                    if (packetBytes.Length > indexOf9F + 3 && packetBytes[indexOf9F + 1] == 0x15)
                                        // 9F 15 XX XX
                                    {
                                        byte b1 = packetBytes[indexOf9F + 2];
                                        byte b2 = packetBytes[indexOf9F + 3];

                                        int onTime, onCount;
                                        GetIrCodeLengths(_learningCode, out onTime, out onCount);

                                        double carrierCount = (b1*256) + b2;

                                        if (carrierCount/onCount < 2.0)
                                        {
                                            _learningCode.Carrier = IRCode.CarrierFrequencyDCMode;
                                        }
                                        else
                                        {
                                            double carrier = 1000000*carrierCount/onTime;

                                            // TODO: Double-Check this calculation.
                                            if (carrier > 32000)
                                            {
                                                _learningCode.Carrier = (int) (carrier + 0.05*carrier - 0.666667);
                                                // was: _learningCode.Carrier = (int) (carrier + 0.05*carrier - 32000/48000);
                                            }
                                            else
                                            {
                                                _learningCode.Carrier = (int) carrier;
                                            }
                                        }

                                        _readThreadMode = ReadThreadMode.LearningDone;
                                        break;
                                    }

                                    if (packetBytes.Length > indexOf9F + 1)
                                    {
                                        indexOf9F = Array.IndexOf(packetBytes, (byte) 0x9F, indexOf9F + 1);
                                    }
                                    else
                                    {
                                        _readThreadMode = ReadThreadMode.LearningFailed;
                                        break;
                                    }
                                }

                                break;
                            }
                    }
                }
                FireStateChanged(new StateChangedEventArgs(RunningState.Stopping));
            }
            catch (ThreadInterruptedException ex)
            {
                Log.Info(ex);

                if (_readHandle != null)
                    CancelIo(_readHandle);
            }
            catch (Exception ex)
            {
                Log.Warn(ex);

                if (_readHandle != null)
                    CancelIo(_readHandle);
            }
            finally
            {
                if (deviceBufferPtr != IntPtr.Zero)
                    Marshal.FreeHGlobal(deviceBufferPtr);

                safeWaitHandle.DangerousRelease();
                waitHandle.Close();
            }

            Log.Debug("Read Thread Ended");
            FireStateChanged(new StateChangedEventArgs(RunningState.Stopped));
        }
        /// <summary>
        /// Learn an IR Command.
        /// </summary>
        /// <param name="learnTimeout">How long to wait before aborting learn.</param>
        /// <param name="learned">Newly learned IR Command.</param>
        /// <returns>Learn status.</returns>
        public override LearnStatus Learn(int learnTimeout, out IRCode learned)
        {
            Log.Trace("Learn()");

            learned = null;
            _learningCode = new IRCode();

            SetInputPort(InputPort.Learning);

            var learnStartTick = Environment.TickCount;
            _readThreadMode = ReadThreadMode.Learning;

            // Wait for the learning to finish ...
            while (_readThreadMode == ReadThreadMode.Learning && Environment.TickCount < learnStartTick + learnTimeout)
                Thread.Sleep(PacketTimeout);

            Log.Trace("End Learn");

            var modeWas = _readThreadMode;

            _readThreadMode = ReadThreadMode.Receiving;
            SetInputPort(InputPort.Receive);

            var status = LearnStatus.Failure;

            switch (modeWas)
            {
                case ReadThreadMode.Learning:
                    status = LearnStatus.Timeout;
                    break;

                case ReadThreadMode.LearningFailed:
                    status = LearnStatus.Failure;
                    break;

                case ReadThreadMode.LearningDone:
                    Log.WriteArray(LogLevel.Trace, _learningCode.TimingData);
                    if (_learningCode.FinalizeData())
                    {
                        learned = _learningCode;
                        status = LearnStatus.Success;
                    }
                    break;
            }

            _learningCode = null;
            return status;
        }
Beispiel #10
0
        /// <summary>
        /// Device read thread method.
        /// </summary>
        private void ReadThread()
        {
            var receiveParamsPtr = IntPtr.Zero;

            try
            {
                IReceiveParams receiveParams;
                if (_isSystem64Bit)
                {
                    receiveParams = new ReceiveParams64();
                }
                else
                {
                    receiveParams = new ReceiveParams32();
                }

                var receiveParamsSize = Marshal.SizeOf(receiveParams) + DeviceBufferSize + 8;
                receiveParamsPtr = Marshal.AllocHGlobal(receiveParamsSize);

                receiveParams.ByteCount = DeviceBufferSize;
                Marshal.StructureToPtr(receiveParams, receiveParamsPtr, false);

                while (_readThreadMode != ReadThreadMode.Stop)
                {
                    // Cycle thread if device stopped reading.
                    if (!_deviceReceiveStarted)
                    {
                        StartReceive(_readThreadModeNext == ReadThreadMode.Receiving ? _receivePort : _learnPort,
                                     PacketTimeout);
                        _readThreadMode = _readThreadModeNext;
                        _deviceReceiveStarted = true;

                        switch (_readThreadMode)
                        {
                            case ReadThreadMode.Receiving:
                                FireStateChanged(new StateChangedEventArgs(RunningState.Started, ReceivingState.Receiving));
                                break;
                            case ReadThreadMode.Learning:
                                FireStateChanged(new StateChangedEventArgs(RunningState.Started, ReceivingState.Learning));
                                break;
                        }
                    }

                    int bytesRead;
                    IoControl(IoCtrl.Receive, IntPtr.Zero, 0, receiveParamsPtr, receiveParamsSize, out bytesRead);

                    if (bytesRead > Marshal.SizeOf(receiveParams))
                    {
                        var dataSize = bytesRead;

                        bytesRead -= Marshal.SizeOf(receiveParams);

                        var packetBytes = new byte[bytesRead];
                        var dataBytes = new byte[dataSize];

                        Marshal.Copy(receiveParamsPtr, dataBytes, 0, dataSize);
                        Array.Copy(dataBytes, dataSize - bytesRead, packetBytes, 0, bytesRead);

                        var timingData = GetTimingDataFromPacket(packetBytes);

                        Log.Trace("{0:yyyy-MM-dd HH:mm:ss.ffffff} - ", DateTime.Now);
                        Log.Trace("Received timing:    ");
                        Log.WriteArray(LogLevel.Trace, timingData);

                        if (_readThreadMode == ReadThreadMode.Learning)
                            _learningCode.AddTimingData(timingData);
                        else
                        {
                            var code = new IRCode(timingData);
                            code.FinalizeData();
                            FireCodeReceived(new CodeReceivedEventArgs(code));
                        }
                    }

                    // Determine carrier frequency when learning ...
                    Log.Trace("bytesRead: {0}, receiveParams Size: {1}", bytesRead, Marshal.SizeOf(receiveParams));
                    if (_readThreadMode == ReadThreadMode.Learning && bytesRead >= Marshal.SizeOf(receiveParams))
                    {
                        IReceiveParams receiveParams2;
                        if (_isSystem64Bit)
                        {
                            receiveParams2 =
                                (ReceiveParams64) Marshal.PtrToStructure(receiveParamsPtr, receiveParams.GetType());
                        }
                        else
                        {
                            receiveParams2 =
                                (ReceiveParams32) Marshal.PtrToStructure(receiveParamsPtr, receiveParams.GetType());
                        }
                        Log.Trace("DataEnd {0}", Convert.ToInt64(receiveParams2.DataEnd));
                        if (Convert.ToInt64(receiveParams2.DataEnd) != 0)
                        {
                            _learningCode.Carrier = Convert.ToInt32(receiveParams2.CarrierFrequency);
                            _readThreadMode = ReadThreadMode.LearningDone;
                        }
                    }
                }
                FireStateChanged(new StateChangedEventArgs(RunningState.Stopping));
            }
            catch (Exception ex)
            {
                Log.Warn(ex);

                if (_eHomeHandle != null)
                    CancelIo(_eHomeHandle);
            }
            finally
            {
                if (receiveParamsPtr != IntPtr.Zero)
                    Marshal.FreeHGlobal(receiveParamsPtr);

                try
                {
                    if (_eHomeHandle != null)
                        StopReceive();
                }
                catch (Exception ex)
                {
                    Log.Warn(ex);
                }
            }

            Log.Debug("Read Thread Ended");
            FireStateChanged(new StateChangedEventArgs(RunningState.Stopped));
        }
    /// <summary>
    /// Stop the device read thread.
    /// </summary>
    private void StopReadThread()
    {
      DebugWriteLine("StopReadThread()");

      if (_readThread == null)
      {
        DebugWriteLine("Read thread already stopped");
        return;
      }

      try
      {
        _readThreadMode = ReadThreadMode.Stop;
        _stopReadThread.Set();
        if (Thread.CurrentThread != _readThread)
          _readThread.Join(PacketTimeout * 2);

        //_readThread.Abort();
      }
      catch (Exception ex)
      {
        DebugWriteLine(ex.ToString());
      }
      finally
      {
        _stopReadThread.Close();
        _stopReadThread = null;

        _readThread = null;
      }
    }
    /// <summary>
    /// Start the device read thread.
    /// </summary>
    private void StartReadThread()
    {
      DebugWriteLine("StartReadThread()");

      if (_readThread != null)
      {
        DebugWriteLine("Read thread already started");
        return;
      }

      _stopReadThread = new ManualResetEvent(false);
      _readThreadMode = ReadThreadMode.Receiving;

      _readThread = new Thread(ReadThread);
      _readThread.Name = "MicrosoftMceTransceiver.DriverReplacement.ReadThread";
      _readThread.IsBackground = true;
      _readThread.Start();
    }
Beispiel #13
0
        /// <summary>
        /// Start the device read thread.
        /// </summary>
        private void StartReadThread(ReadThreadMode mode)
        {
            Log.Trace("StartReadThread({0})", Enum.GetName(typeof (ReadThreadMode), mode));

            if (_readThread != null)
            {
                Log.Warn("Read thread already started");
                return;
            }

            _deviceReceiveStarted = false;
            _readThreadModeNext = mode;

            _readThread = new Thread(ReadThread)
                              {
                                  Name = "MicrosoftMceTransceiver.DriverVista.ReadThread",
                                  IsBackground = true
                              };
            _readThread.Start();

            FireStateChanged(new StateChangedEventArgs(RunningState.Started));
        }
Beispiel #14
0
    /// <summary>
    /// Stop the device read thread.
    /// </summary>
    private void StopReadThread()
    {
      DebugWriteLine("StopReadThread()");

      if (_readThread == null)
      {
        DebugWriteLine("Read thread already stopped");
        return;
      }

      //if (_eHomeHandle != null)
      //  CancelIo(_eHomeHandle);

      if (_readThread.IsAlive)
      {
        _readThread.Abort();

        if (Thread.CurrentThread != _readThread)
          _readThread.Join();
      }

      _readThreadMode = ReadThreadMode.Stop;

      _readThread = null;
    }
Beispiel #15
0
        /// <summary>
        /// Device read thread method.
        /// </summary>
        private void ReadThread()
        {
            byte[] packetBytes;

            WaitHandle waitHandle     = new ManualResetEvent(false);
            SafeHandle safeWaitHandle = waitHandle.SafeWaitHandle;

            WaitHandle[] waitHandles = new WaitHandle[] { waitHandle, _stopReadThread };

            IntPtr deviceBufferPtr = IntPtr.Zero;

            bool success = false;

            safeWaitHandle.DangerousAddRef(ref success);
            if (!success)
            {
                throw new InvalidOperationException("Failed to initialize safe wait handle");
            }

            try
            {
                IntPtr dangerousWaitHandle = safeWaitHandle.DangerousGetHandle();

                DeviceIoOverlapped overlapped = new DeviceIoOverlapped();
                overlapped.ClearAndSetEvent(dangerousWaitHandle);

                deviceBufferPtr = Marshal.AllocHGlobal(DeviceBufferSize);

                while (_readThreadMode != ReadThreadMode.Stop)
                {
                    int  lastError;
                    int  bytesRead;
                    bool readDevice = ReadFile(_readHandle, deviceBufferPtr, DeviceBufferSize, out bytesRead,
                                               overlapped.Overlapped);
                    lastError = Marshal.GetLastWin32Error();

                    if (!readDevice)
                    {
                        if (lastError != ErrorSuccess && lastError != ErrorIoPending)
                        {
                            throw new Win32Exception(lastError);
                        }

                        while (true)
                        {
                            int handle = WaitHandle.WaitAny(waitHandles, 2 * PacketTimeout, false);

                            if (handle == ErrorWaitTimeout)
                            {
                                continue;
                            }

                            if (handle == 0)
                            {
                                break;
                            }

                            if (handle == 1)
                            {
                                throw new ThreadInterruptedException("Read thread stopping by request");
                            }

                            throw new InvalidOperationException(String.Format("Invalid wait handle return: {0}", handle));
                        }

                        bool getOverlapped = GetOverlappedResult(_readHandle, overlapped.Overlapped, out bytesRead, true);
                        lastError = Marshal.GetLastWin32Error();

                        if (!getOverlapped && lastError != ErrorSuccess)
                        {
                            throw new Win32Exception(lastError);
                        }
                    }

                    if (bytesRead == 0)
                    {
                        continue;
                    }

                    packetBytes = new byte[bytesRead];
                    Marshal.Copy(deviceBufferPtr, packetBytes, 0, bytesRead);

                    DebugWrite("Received bytes ({0}): ", bytesRead);
                    DebugDump(packetBytes);

                    int[] timingData = null;

                    if (_decodeCarry != 0 || packetBytes[0] >= 0x81 && packetBytes[0] <= 0x9E)
                    {
                        timingData = GetTimingDataFromPacket(packetBytes);
                    }
                    else
                    {
                        double firmware = 0.0;

                        int indexOfFF = Array.IndexOf(packetBytes, (byte)0xFF);
                        while (indexOfFF != -1)
                        {
                            if (packetBytes.Length > indexOfFF + 2 && packetBytes[indexOfFF + 1] == 0x0B) // FF 0B XY - Firmware X.Y00
                            {
                                byte b1 = packetBytes[indexOfFF + 2];

                                firmware += (b1 >> 4) + (0.1 * (b1 & 0x0F));
                                DebugWriteLine("Firmware: {0}", firmware);
                            }

                            if (packetBytes.Length > indexOfFF + 2 && packetBytes[indexOfFF + 1] == 0x1B) // FF 1B XY - Firmware 0.0XY
                            {
                                byte b1 = packetBytes[indexOfFF + 2];

                                firmware += (0.01 * (b1 >> 4)) + (0.001 * (b1 & 0x0F));
                                DebugWriteLine("Firmware: {0}", firmware);
                            }

                            if (packetBytes.Length > indexOfFF + 1)
                            {
                                indexOfFF = Array.IndexOf(packetBytes, (byte)0xFF, indexOfFF + 1);
                            }
                            else
                            {
                                break;
                            }
                        }
                    }

                    switch (_readThreadMode)
                    {
                    case ReadThreadMode.Receiving:
                    {
                        IrDecoder.DecodeIR(timingData, _remoteCallback, _keyboardCallback, _mouseCallback);
                        break;
                    }

                    case ReadThreadMode.Learning:
                    {
                        if (timingData == null)
                        {
                            if (_learningCode.TimingData.Length > 0)
                            {
                                _learningCode   = null;
                                _readThreadMode = ReadThreadMode.LearningFailed;
                            }
                            break;
                        }

                        if (_learningCode == null)
                        {
                            throw new InvalidOperationException("Learning not initialised correctly, _learningCode object is null");
                        }

                        _learningCode.AddTimingData(timingData);

                        // Example: 9F 01 02 9F 15 00 BE 80
                        int indexOf9F = Array.IndexOf(packetBytes, (byte)0x9F);
                        while (indexOf9F != -1)
                        {
                            if (packetBytes.Length > indexOf9F + 3 && packetBytes[indexOf9F + 1] == 0x15) // 9F 15 XX XX
                            {
                                byte b1 = packetBytes[indexOf9F + 2];
                                byte b2 = packetBytes[indexOf9F + 3];

                                int onTime, onCount;
                                GetIrCodeLengths(_learningCode, out onTime, out onCount);

                                double carrierCount = (b1 * 256) + b2;

                                if (carrierCount / onCount < 2.0)
                                {
                                    _learningCode.Carrier = IrCode.CarrierFrequencyDCMode;
                                }
                                else
                                {
                                    double carrier = 1000000 * carrierCount / onTime;

                                    // TODO: Double-Check this calculation.
                                    if (carrier > 32000)
                                    {
                                        _learningCode.Carrier = (int)(carrier + 0.05 * carrier - 0.666667);
                                        // was: _learningCode.Carrier = (int) (carrier + 0.05*carrier - 32000/48000);
                                    }
                                    else
                                    {
                                        _learningCode.Carrier = (int)carrier;
                                    }
                                }

                                _readThreadMode = ReadThreadMode.LearningDone;
                                break;
                            }

                            if (packetBytes.Length > indexOf9F + 1)
                            {
                                indexOf9F = Array.IndexOf(packetBytes, (byte)0x9F, indexOf9F + 1);
                            }
                            else
                            {
                                _readThreadMode = ReadThreadMode.LearningFailed;
                                break;
                            }
                        }

                        break;
                    }
                    }
                }
            }
            catch (ThreadInterruptedException ex)
            {
                DebugWriteLine(ex.Message);

                if (_readHandle != null)
                {
                    CancelIo(_readHandle);
                }
            }
            catch (Exception ex)
            {
                DebugWriteLine(ex.ToString());

                if (_readHandle != null)
                {
                    CancelIo(_readHandle);
                }
            }
            finally
            {
                if (deviceBufferPtr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(deviceBufferPtr);
                }

                safeWaitHandle.DangerousRelease();
                waitHandle.Close();
            }

            DebugWriteLine("Read Thread Ended");
        }
Beispiel #16
0
    /// <summary>
    /// Device read thread method.
    /// </summary>
    private void ReadThread()
    {
      IntPtr receiveParamsPtr = IntPtr.Zero;

      try
      {
        IReceiveParams receiveParams;
        if (_isSystem64Bit)
        {
          receiveParams = new ReceiveParams64();
        }
        else
        {
          receiveParams = new ReceiveParams32();
        }

        int receiveParamsSize = Marshal.SizeOf(receiveParams) + DeviceBufferSize + 8;
        receiveParamsPtr = Marshal.AllocHGlobal(receiveParamsSize);

        receiveParams.ByteCount = DeviceBufferSize;
        Marshal.StructureToPtr(receiveParams, receiveParamsPtr, false);

        _readThreadMode = _readThreadModeNext;
        while (_readThreadMode != ReadThreadMode.Stop)
        {
          // Cycle thread if device stopped reading.
          if (!_deviceReceiveStarted)
          {
            if (_readThreadModeNext == ReadThreadMode.Receiving)
              StartReceive(_receivePort, PacketTimeout);
            else
            {
              StartReceive(_learnPort, PacketTimeout);
            }
            _readThreadMode = _readThreadModeNext;
            _deviceReceiveStarted = true;
          }

          int bytesRead;
          IoControl(IoCtrl.Receive, IntPtr.Zero, 0, receiveParamsPtr, receiveParamsSize, out bytesRead);

          if (bytesRead > Marshal.SizeOf(receiveParams))
          {
            int dataSize = bytesRead;

            bytesRead -= Marshal.SizeOf(receiveParams);

            byte[] packetBytes = new byte[bytesRead];
            byte[] dataBytes = new byte[dataSize];

            Marshal.Copy(receiveParamsPtr, dataBytes, 0, dataSize);
            Array.Copy(dataBytes, dataSize - bytesRead, packetBytes, 0, bytesRead);

            int[] timingData = GetTimingDataFromPacket(packetBytes);

            DebugWrite("{0:yyyy-MM-dd HH:mm:ss.ffffff} - ", DateTime.Now);
            DebugWrite("Received timing:    ");
            DebugDump(timingData);

            if (_readThreadMode == ReadThreadMode.Learning)
              _learningCode.AddTimingData(timingData);
            else
              IrDecoder.DecodeIR(timingData, _remoteCallback, _keyboardCallback, _mouseCallback);
          }

          // Determine carrier frequency when learning ...
          if (_readThreadMode == ReadThreadMode.Learning && bytesRead >= Marshal.SizeOf(receiveParams))
          {
            IReceiveParams receiveParams2;
            if (_isSystem64Bit)
            {
              receiveParams2 = (ReceiveParams64)Marshal.PtrToStructure(receiveParamsPtr, receiveParams.GetType());
            }
            else
            {
              receiveParams2 = (ReceiveParams32)Marshal.PtrToStructure(receiveParamsPtr, receiveParams.GetType());
            }
            if (System.Convert.ToInt64(receiveParams2.DataEnd) != 0)
            {
              _learningCode.Carrier = System.Convert.ToInt32(receiveParams2.CarrierFrequency);
              _readThreadMode = ReadThreadMode.LearningDone;
            }
          }
        }
      }
      catch (Exception ex)
      {
        DebugWriteLine(ex.ToString());

        if (_eHomeHandle != null)
          CancelIo(_eHomeHandle);
      }
      finally
      {
        if (receiveParamsPtr != IntPtr.Zero)
          Marshal.FreeHGlobal(receiveParamsPtr);

        try
        {
          if (_eHomeHandle != null)
            StopReceive();
        }
        catch (Exception ex)
        {
          DebugWriteLine(ex.ToString());
        }
      }

      DebugWriteLine("Read Thread Ended");
    }
Beispiel #17
0
        /// <summary>
        /// Stop the device read thread.
        /// </summary>
        private void StopReadThread()
        {
            Log.Trace("StopReadThread()");

            if (_readThread == null)
            {
                Log.Warn("Read thread already stopped");
                return;
            }

            if (_readThread.IsAlive)
            {
                _readThread.Abort();

                if (Thread.CurrentThread != _readThread)
                    _readThread.Join();
            }

            _readThreadMode = ReadThreadMode.Stop;

            _readThread = null;
        }