コード例 #1
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)
        {
            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;
        }
コード例 #2
0
        /// <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));
        }
コード例 #3
0
ファイル: DriverVista.cs プロジェクト: UnifiedControl/PyMCE
        /// <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));
        }