Esempio n. 1
0
    private void IoControl(IoCtrl ioControlCode, IntPtr inBuffer, int inBufferSize, IntPtr outBuffer, int outBufferSize,
                           out int bytesReturned)
    {
      if (!_deviceAvailable)
        throw new InvalidOperationException("Device not available");

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

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

        try
        {
          int lastError;

          IntPtr dangerousWaitHandle = safeWaitHandle.DangerousGetHandle();

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

          bool deviceIoControl = DeviceIoControl(_eHomeHandle, ioControlCode, inBuffer, inBufferSize, outBuffer,
                                                 outBufferSize, out bytesReturned, overlapped.Overlapped);
          lastError = Marshal.GetLastWin32Error();

          if (!deviceIoControl)
          {
            // Now also handles Operation Aborted and Bad Command errors.
            switch (lastError)
            {
              case ErrorIoPending:
                waitHandle.WaitOne();

                bool getOverlapped = GetOverlappedResult(_eHomeHandle, overlapped.Overlapped, out bytesReturned, false);
                lastError = Marshal.GetLastWin32Error();

                if (!getOverlapped)
                {
                  if (lastError == ErrorBadCommand)
                    goto case ErrorBadCommand;
                  if (lastError == ErrorOperationAborted)
                    goto case ErrorOperationAborted;
                  throw new Win32Exception(lastError);
                }
                break;

              case ErrorBadCommand:
                if (Thread.CurrentThread == _readThread)
                  //Cause receive restart
                  _deviceReceiveStarted = false;
                break;

              case ErrorOperationAborted:
                if (Thread.CurrentThread != _readThread)
                  throw new Win32Exception(lastError);

                //Cause receive restart
                _deviceReceiveStarted = false;
                break;

              default:
                throw new Win32Exception(lastError);
            }
          }
        }
        catch
        {
          IrssUtils.IrssLog.Debug("IoControl: something went bad with StructToPtr or the other way around");
          if (_eHomeHandle != null)
            CancelIo(_eHomeHandle);

          throw;
        }
        finally
        {
          safeWaitHandle.DangerousRelease();
        }
      }
      //IrssUtils.IrssLog.Debug("IoControl: End  of [{0}]", ioControlCode.ToString());
      //IrssUtils.IrssLog.Close();
    }
Esempio n. 2
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");
        }
    /// <summary>
    /// Synchronously write a packet of bytes to the device.
    /// </summary>
    /// <param name="data">Packet to write to device.</param>
    private void WriteSync(byte[] data)
    {
      DebugWrite("WriteSync({0}): ", data.Length);
      DebugDump(data);

      if (!_deviceAvailable)
        throw new InvalidOperationException("Device not available");

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

      try
      {
        int lastError;

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

        DeviceIoOverlapped overlapped = new DeviceIoOverlapped();
        overlapped.ClearAndSetEvent(safeWaitHandle.DangerousGetHandle());

        int bytesWritten;
        bool writeDevice = WriteFile(_writeHandle, data, data.Length, out bytesWritten, overlapped.Overlapped);
        lastError = Marshal.GetLastWin32Error();

        if (writeDevice)
          return;

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

        int handle = WaitHandle.WaitAny(waitHandles, WriteSyncTimeout, false);

        if (handle == ErrorWaitTimeout)
          throw new TimeoutException("Timeout trying to write data to device");

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

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

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

        Thread.Sleep(PacketTimeout);
      }
      catch
      {
        if (_writeHandle != null)
          CancelIo(_writeHandle);

        throw;
      }
      finally
      {
        safeWaitHandle.DangerousRelease();
        waitHandle.Close();
      }
    }
Esempio n. 4
0
        /// <summary>
        /// Synchronously write a packet of bytes to the device.
        /// </summary>
        /// <param name="data">Packet to write to device.</param>
        private void WriteSync(byte[] data)
        {
            DebugWrite("WriteSync({0}): ", data.Length);
            DebugDump(data);

            if (!_deviceAvailable)
            {
                throw new InvalidOperationException("Device not available");
            }

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

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

            try
            {
                int lastError;

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

                DeviceIoOverlapped overlapped = new DeviceIoOverlapped();
                overlapped.ClearAndSetEvent(safeWaitHandle.DangerousGetHandle());

                int  bytesWritten;
                bool writeDevice = WriteFile(_writeHandle, data, data.Length, out bytesWritten, overlapped.Overlapped);
                lastError = Marshal.GetLastWin32Error();

                if (writeDevice)
                {
                    return;
                }

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

                int handle = WaitHandle.WaitAny(waitHandles, WriteSyncTimeout, false);

                if (handle == ErrorWaitTimeout)
                {
                    throw new TimeoutException("Timeout trying to write data to device");
                }

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

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

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

                Thread.Sleep(PacketTimeout);
            }
            catch
            {
                if (_writeHandle != null)
                {
                    CancelIo(_writeHandle);
                }

                throw;
            }
            finally
            {
                safeWaitHandle.DangerousRelease();
                waitHandle.Close();
            }
        }
    /// <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");
    }