我有一个循环工作的硬件。它带有一个专有软件工具,允许用户通过 USB 从 PC 控制它。用户定义每个周期有多长。在每个周期开始时,软件工具通过 USB 快速向硬件发出一系列命令,然后进入空闲模式,等待下一个周期。
第二个硬件需要与第一个同步。基本上,当向硬件#1 发出上述一系列命令时,硬件#2 也应该做它的事情。
硬件 #2 带有 API 和 SDK 等等。硬件 #1 没有——只有这个工具可以定义你的周期有多长。
鉴于这一切,我们决定实现这一目标的最简单方法是侦听硬件#1 使用的 USB 端口,以便每次检测到硬件#2 上的流量时也会发出其指令。我在硬件 #1 的 USB 端口上使用了一个监控应用程序,它的流量看起来非常简单:它是一个周期开始时快速而短暂的连续数据包,然后直到下一个周期才没有。
这个想法是编写一个基于 Windows 的小型实用程序应用程序,该应用程序将侦听硬件 #1 的 USB 端口,并在每次检测到循环时向硬件 #2 发出 API 调用。理想情况下,它应该是一个 .NET 应用程序,因为我最熟悉它,就编写 Windows 代码而言。
困难的部分是编写用于监听硬件#1 的 USB 端口的代码。此外,我始终无法访问硬件 #1,因此我使用普通的 USB 键盘和鼠标作为其替代品。此时的目标是简单地检测键盘或鼠标 USB 端口上的流量。
到目前为止,我已经尝试了我在网上找到的两个库——LibUsbDotNet 和 Usb.Net。两者中的任何一个我都无法实现目标。
我什至无法让 Usb.Net 读取数据包......
LibUsbDotNet 似乎劫持了流量 - 因此,如果我在记事本或 Word 中的键盘上键入,字母不会出现在那里,而我的应用程序成功读取了数据包。将截获的数据包写回端口没有帮助。
这是我与 LibUsbDotNet 一起使用的代码。它基本上是库的示例,稍作修改以与我的键盘一起使用。
// 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();
}
如何修改它以使其不拦截数据包,而只是在让它们通过到预期目的地的同时检测它们?
欢迎使用 Usb.Net 或 LibUsbDotNet 提供任何建议。或者,也许,一个更适合我需要的不同图书馆?