I have a piece of hardware that works in cycles. It comes with a proprietary software tool that lets user control it from PC via USB. User defines how long each cycle is. At the beginning of each cycle the software tool rapidly issues a series of commands to the hardware via USB and then goes into the idle mode, awaiting next cycle.
There's a second piece of hardware that needs to be synched with the first one. Basically, when the aforementioned series of commands is issued to hardware #1, hardware #2 should do its thing too.
Hardware #2 comes with API and SDK and whatnot. Hardware #1 does not - there's only this tool where you can define how long your cycle will be.
In view of all this, it's been decided that the easiest way to achieve this will be by listening on USB port that hardware #1 uses so that each time traffic on it is detected hardware #2 is issued its directives too. I've used a monitoring app on hardware #1's USB port and its traffic looks pretty simple: it's a rapid and short succession of packets at the very beginning of a cycle and then nothing until the next cycle.
The idea is to write a small Windows-based utility app that will listen on hardware #1's USB port and issue an API call to hardware #2 every time it detects a cycle. Ideally, it should be a .NET app, cause I'm familiar it with the most, as far as writing Windows-code goes.
The difficult part is writing the code for listening on hardware #1's USB port. Also, I don't have access to hardware #1 at all times, so I use plain USB keyboard and mouse as its substitutes. At this point the goal is to simply detect traffic on keyboard or mouse USB ports.
So far I have attempted two libraries I found on the web - LibUsbDotNet and Usb.Net. I haven't been able to achieve the goal with either of the two.
I can't get Usb.Net to even read the packets...
And LibUsbDotNet seems to hijack the traffic - so if I type on a keyboard in a notepad or Word, letters don't appear there, while my app successfully reads the packets. Writing intercepted packets back to the port doesn't help.
Here's the code that I use with LibUsbDotNet. It's basically library's example, slightly modified to work with my keyboard.
// 1118 = Vendor Id, 1872 = Product Id
UsbDeviceFinder MyUsbFinder = new UsbDeviceFinder(1118, 1872);
ErrorCode ec = ErrorCode.None;
try
{
// Find and open the usb device.
MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);
// If the device is open and ready
if (MyUsbDevice == null) throw new Exception("Device Not Found.");
// If this is a "whole" usb device (libusb-win32, linux libusb-1.0)
// it exposes an IUsbDevice interface. If not (WinUSB) the
// 'wholeUsbDevice' variable will be null indicating this is
// an interface of a device; it does not require or support
// configuration and interface selection.
IUsbDevice wholeUsbDevice = MyUsbDevice as IUsbDevice;
if (!ReferenceEquals(wholeUsbDevice, null))
{
// This is a "whole" USB device. Before it can be used,
// the desired configuration and interface must be selected.
// Select config #1
wholeUsbDevice.SetConfiguration(1);
// Claim interface #0.
wholeUsbDevice.ClaimInterface(0);
}
// open read endpoint 1.
UsbEndpointReader reader = MyUsbDevice.OpenEndpointReader(ReadEndpointID.Ep01);
// keyboard communicates in packets of size 8
byte[] readBuffer = new byte[8];
while (ec == ErrorCode.None)
{
int bytesRead;
// If the device hasn't sent data in the last 5 seconds,
// a timeout error (ec = IoTimedOut) will occur.
ec = reader.Read(readBuffer, 5000, out bytesRead);
if (bytesRead == 0) throw new Exception(string.Format("{0}:No more bytes!", ec));
Console.WriteLine("{0} bytes read", bytesRead);
// Write that output to the console.
foreach (byte b in readBuffer) Console.Write("{0} ", b);
Console.WriteLine();
}
Console.WriteLine("\r\nDone!\r\n");
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine((ec != ErrorCode.None? ec + ":" : String.Empty) + ex.Message);
}
finally
{
if (MyUsbDevice != null)
{
if (MyUsbDevice.IsOpen)
{
// If this is a "whole" usb device (libusb-win32, linux libusb-1.0)
// it exposes an IUsbDevice interface. If not (WinUSB) the
// 'wholeUsbDevice' variable will be null indicating this is
// an interface of a device; it does not require or support
// configuration and interface selection.
IUsbDevice wholeUsbDevice = MyUsbDevice as IUsbDevice;
if (!ReferenceEquals(wholeUsbDevice, null))
{
// Release interface #0.
wholeUsbDevice.ReleaseInterface(0);
}
MyUsbDevice.Close();
}
MyUsbDevice = null;
// Free usb resources
UsbDevice.Exit();
}
// Wait for user input..
Console.ReadKey();
}
How do I modify this so that it doesn't intercept the packets but simply detects them while letting them pass through to their intended destination?
Any advice is welcome with either Usb.Net or LibUsbDotNet. Or, perhaps, a different library that better suits my needs?