예제 #1
0
 // Protected implementation of Dispose pattern.
 protected virtual void Dispose(bool disposing)
 {
     if (disposed)
     {
         return;
     }
     if (disposing)
     {
         // Free any other managed objects here.
         if (asyncReadOn)
         {
             asyncReadOn = false;
             readThread.Join(readTimeoutInMillisecs);
             if (readThread.IsAlive)
             {
                 readThread.Abort();
             }
         }
     }
     // Free any UN-managed objects here.
     // so we are not reading or writing as the device gets closed
     lock (syncLock)
     {
         if (isOpen)
         {
             HidApi.hid_close(DeviceHandle);
             DeviceHandle = IntPtr.Zero;
         }
     }
     HidApi.hid_exit();
     // mark object as having been disposed
     disposed = true;
 }
예제 #2
0
        public string GetErrorString()
        {
            AssertValidDev();
            IntPtr ret = HidApi.hid_error(DeviceHandle);

            // I can not find the info in the docs, but guess this frees
            // the ret pointer after we created a managed string object
            // else this would be a memory leak
            return(Marshal.PtrToStringAuto(ret));
        }
예제 #3
0
 // HIDAPI does not provide any way to get or parse the HID Report Descriptor,
 // This means you must know in advance what it the report size for your device.
 // For this reason, reportLen is a necessary parameter to the constructor.
 //
 // Serial Number is optional, pass null (do NOT pass an empty string) if it is unknown.
 //
 public USBDevice(ushort VendorID
                  , ushort ProductID
                  , string serial_number
                  , bool HasReportIDs         = true
                  , int defaultInputReportLen = -1)
 {
     DeviceHandle = HidApi.hid_open(VendorID, ProductID, serial_number);
     AssertValidDev();
     DefaultInputReportLength = defaultInputReportLen;
     hasReportIds             = HasReportIDs;
 }
예제 #4
0
 public void GetFeatureReport(byte[] buffer, int length = -1)
 {
     AssertValidDev();
     if (length < 0)
     {
         length = buffer.Length;
     }
     if (HidApi.hid_get_feature_report(DeviceHandle, buffer, (uint)length) < 0)
     {
         throw new Exception("failed to get feature report");
     }
 }
예제 #5
0
 // All the string functions are in a little bit of trouble becasue
 // wchar_t is 2 bytes on windows and 4 bytes on linux.
 // So we should just alloc a hell load of space for the return buffer.
 //
 // We must divide Capacity / 4 because this takes the buffer length in multiples of
 // wchar_t whoose length is 4 on Linux and 2 on Windows. So we allocate a big
 // buffer beforehand and just divide the capacity by 4.
 public string GetIndexedString(int index)
 {
     lock (syncLock)
     {
         AssertValidDev();
         if (HidApi.hid_get_indexed_string(DeviceHandle, index, pOutBuf, (uint)pOutBuf.Capacity / 4) < 0)
         {
             throw new Exception("failed to get indexed string");
         }
         return(pOutBuf.ToString());
     }
 }
예제 #6
0
 // Meaning OutputReport
 private void WriteRaw(byte[] buffer, int length = -1)
 {
     AssertValidDev();
     if (length < 0)
     {
         length = buffer.Length;
     }
     if (HidApi.hid_write(DeviceHandle, buffer, (uint)length) < 0)
     {
         throw new Exception("Failed to write.");
     }
 }
예제 #7
0
 public string GetSerialNumberString()
 {
     lock (syncLock)
     {
         AssertValidDev();
         pOutBuf.Clear();
         if (HidApi.hid_get_serial_number_string(DeviceHandle, pOutBuf, (uint)pOutBuf.Capacity / 4) < 0)
         {
             throw new Exception("failed to get serial number string");
         }
         return(pOutBuf.ToString());
     }
 }
예제 #8
0
 public string GetProductString()
 {
     lock (syncLock)
     {
         AssertValidDev();
         pOutBuf.Clear();
         if (HidApi.hid_get_product_string(DeviceHandle, pOutBuf, (uint)pOutBuf.Capacity / 4) < 0)
         {
             throw new Exception("failed to get product string");
         }
         return(pOutBuf.ToString());
     }
 }
예제 #9
0
        // either everything is good, or throw exception
        // Meaning InputReport
        // This function is slightly different, as we must return the number of bytes read.
        private int ReadRaw(byte[] buffer, int length = -1)
        {
            AssertValidDev();
            if (length < 0)
            {
                length = buffer.Length;
            }
            int bytes_read = HidApi.hid_read_timeout(DeviceHandle, buffer, (uint)length, readTimeoutInMillisecs);

            if (bytes_read < 0)
            {
                throw new Exception("Failed to Read.");
            }
            return(bytes_read);
        }
예제 #10
0
        // Meaning OutputReport
        private int WriteRaw(byte[] buffer, int length = -1)
        {
            int byte_written = 0;

            AssertValidDev();
            if (length < 0)
            {
                length = buffer.Length;
            }
            byte_written = HidApi.hid_write(DeviceHandle, buffer, (uint)length);
            if (byte_written < 0)
            {
                throw new Exception("Failed to write.");
            }
            return(byte_written);
        }
예제 #11
0
        private void ScanLoop()
        {
            var culture = CultureInfo.InvariantCulture;

            Thread.CurrentThread.CurrentCulture   = culture;
            Thread.CurrentThread.CurrentUICulture = culture;

            // The read has a timeout parameter, so every X milliseconds
            // we check if the user wants us to continue scanning.
            while (asyncScanOn)
            {
                try
                {
                    IntPtr device_info   = HidApi.hid_enumerate(vendorId, productId);
                    bool   device_on_bus = device_info != IntPtr.Zero;
                    // freeing the enumeration releases the device,
                    // do it as soon as you can, so we dont block device from others
                    HidApi.hid_free_enumeration(device_info);
                    if (device_on_bus && !deviceConnected)
                    {
                        // just found new device
                        deviceConnected = true;
                        if (DeviceArrived != null)
                        {
                            DeviceArrived(this, EventArgs.Empty);
                        }
                    }
                    if (!device_on_bus && deviceConnected)
                    {
                        // just lost device connection
                        deviceConnected = false;
                        if (DeviceRemoved != null)
                        {
                            DeviceRemoved(this, EventArgs.Empty);
                        }
                    }
                }
                catch (Exception e)
                {
                    // stop scan, user can manually restart again with StartAsyncScan()
                    asyncScanOn = false;
                }
                // when read 0 bytes, sleep and read again
                Thread.Sleep(ScanIntervalInMillisecs);
            }
        }
예제 #12
0
 // scanning for device when it is open by another process will return false
 public static bool ScanOnce(ushort vid, ushort pid)
 {
     return(HidApi.hid_enumerate(vid, pid) != IntPtr.Zero);
 }