private static int libusb_control_transfer(MonoUsbDeviceHandle deviceHandle, MonoUsbControlSetupHandle controlSetupHandle, int timeout) { MonoUsbTransfer transfer = MonoUsbTransfer.Alloc(0); ManualResetEvent completeEvent = new ManualResetEvent(false); GCHandle gcCompleteEvent = GCHandle.Alloc(completeEvent); transfer.FillControl(deviceHandle, controlSetupHandle, controlTransferDelegate, GCHandle.ToIntPtr(gcCompleteEvent), timeout); int r = (int)transfer.Submit(); if (r < 0) { transfer.Free(); gcCompleteEvent.Free(); return(r); } while (!completeEvent.WaitOne(0, false)) { r = MonoUsbApi.HandleEvents(sessionHandle); if (r < 0) { if (r == (int)MonoUsbError.ErrorInterrupted) { continue; } transfer.Cancel(); while (!completeEvent.WaitOne(0, false)) { if (MonoUsbApi.HandleEvents(sessionHandle) < 0) { break; } } transfer.Free(); gcCompleteEvent.Free(); return(r); } } if (transfer.Status == MonoUsbTansferStatus.TransferCompleted) { r = transfer.ActualLength; } else { r = (int)MonoUsbApi.MonoLibUsbErrorFromTransferStatus(transfer.Status); } transfer.Free(); gcCompleteEvent.Free(); return(r); }
public String SendByteArray(byte[] data, short length) { string getString = ""; int ret; byte rquestType = (byte)(UsbCtrlFlags.Direction_Out | UsbCtrlFlags.Recipient_Device | UsbCtrlFlags.RequestType_Class); byte request = 0x0; MonoUsbControlSetupHandle controlSetupHandle = new MonoUsbControlSetupHandle(rquestType, request, 0, 0, length); controlSetupHandle.ControlSetup.SetData(data, 0, length); ret = libusb_control_transfer(myDeviceHandle, controlSetupHandle, 1000); Console.WriteLine("libusb control transfer complete"); return(getString); }
/// <summary> /// Perform a USB control transfer for multi-threaded applications using the <see cref="MonoUsbEventHandler"/> class. /// </summary> /// <remarks> /// <para>The direction of the transfer is inferred from the bmRequestType field of the setup packet.</para> /// <para>The wValue, wIndex and wLength fields values should be given in host-endian byte order.</para> /// <note type="tip" title="Libusb-1.0 API:"><seelibusb10 group="syncio"/></note> /// </remarks> /// <param name="deviceHandle">A handle for the device to communicate with.</param> /// <param name="requestType">The request type field for the setup packet.</param> /// <param name="request">The request field for the setup packet.</param> /// <param name="value">The value field for the setup packet</param> /// <param name="index">The index field for the setup packet.</param> /// <param name="pData">A suitably-sized data buffer for either input or output (depending on direction bits within bmRequestType).</param> /// <param name="dataLength">The length field for the setup packet. The data buffer should be at least this size.</param> /// <param name="timeout">timeout (in milliseconds) that this function should wait before giving up due to no response being received. For an unlimited timeout, use value 0.</param> /// <returns> /// <list type="bullet"> /// <item>on success, the number of bytes actually transferred</item> /// <item><see cref="MonoUsbError.ErrorTimeout"/> if the transfer timed out</item> /// <item><see cref="MonoUsbError.ErrorPipe"/> if the control request was not supported by the device.</item> /// <item><see cref="MonoUsbError.ErrorNoDevice"/> if the device has been disconnected</item> /// <item>another <see cref="MonoUsbError"/> code on other failures</item> /// </list> /// </returns> public static int ControlTransferAsync([In] MonoUsbDeviceHandle deviceHandle, byte requestType, byte request, short value, short index, IntPtr pData, short dataLength, int timeout) { MonoUsbControlSetupHandle setupHandle = new MonoUsbControlSetupHandle(requestType, request, value, index, pData, dataLength); MonoUsbTransfer transfer = new MonoUsbTransfer(0); ManualResetEvent completeEvent = new ManualResetEvent(false); GCHandle gcCompleteEvent = GCHandle.Alloc(completeEvent); transfer.FillControl(deviceHandle, setupHandle, DefaultAsyncDelegate, GCHandle.ToIntPtr(gcCompleteEvent), timeout); int r = (int)transfer.Submit(); if (r < 0) { transfer.Free(); gcCompleteEvent.Free(); return(r); } IntPtr pSessionHandle; MonoUsbSessionHandle sessionHandle = MonoUsbEventHandler.SessionHandle; if (sessionHandle == null) { pSessionHandle = IntPtr.Zero; } else { pSessionHandle = sessionHandle.DangerousGetHandle(); } if (MonoUsbEventHandler.IsStopped) { while (!completeEvent.WaitOne(0)) { r = HandleEvents(pSessionHandle); if (r < 0) { if (r == (int)MonoUsbError.ErrorInterrupted) { continue; } transfer.Cancel(); while (!completeEvent.WaitOne(0)) { if (HandleEvents(pSessionHandle) < 0) { break; } } transfer.Free(); gcCompleteEvent.Free(); return(r); } } } else { completeEvent.WaitOne(Timeout.Infinite); } if (transfer.Status == MonoUsbTansferStatus.TransferCompleted) { r = transfer.ActualLength; if (r > 0) { byte[] ctrlDataBytes = setupHandle.ControlSetup.GetData(r); Marshal.Copy(ctrlDataBytes, 0, pData, Math.Min(ctrlDataBytes.Length, dataLength)); } } else { r = (int)MonoLibUsbErrorFromTransferStatus(transfer.Status); } transfer.Free(); gcCompleteEvent.Free(); return(r); }
public static void ShowConfig(RichTextBox rtb) { // Assign the control transfer delegate to the callback function. controlTransferDelegate = ControlTransferCB; // Initialize the context. sessionHandle = new MonoUsbSessionHandle(); if (sessionHandle.IsInvalid) { throw new Exception(String.Format("Failed intializing libusb context.\n{0}:{1}", MonoUsbSessionHandle.LastErrorCode, MonoUsbSessionHandle.LastErrorString)); } MonoUsbProfileList profileList = new MonoUsbProfileList(); MonoUsbDeviceHandle myDeviceHandle = null; try { // The list is initially empty. // Each time refresh is called the list contents are updated. profileList.Refresh(sessionHandle); // Use the GetList() method to get a generic List of MonoUsbProfiles // Find the first profile that matches in MyVidPidPredicate. MonoUsbProfile myProfile = profileList.GetList().Find(MyVidPidPredicate); if (myProfile == null) { rtb.AppendText("Device not connected."); return; } // Open the device handle to perform I/O myDeviceHandle = myProfile.OpenDeviceHandle(); if (myDeviceHandle.IsInvalid) { throw new Exception(String.Format("Failed opening device handle.\n{0}:{1}", MonoUsbDeviceHandle.LastErrorCode, MonoUsbDeviceHandle.LastErrorString)); } int ret; MonoUsbError e; // Set Configuration e = (MonoUsbError)(ret = MonoUsbApi.SetConfiguration(myDeviceHandle, 1)); if (ret < 0) { throw new Exception(String.Format("Failed SetConfiguration.\n{0}:{1}", e, MonoUsbApi.StrError(e))); } // Claim Interface e = (MonoUsbError)(ret = MonoUsbApi.ClaimInterface(myDeviceHandle, 0)); if (ret < 0) { throw new Exception(String.Format("Failed ClaimInterface.\n{0}:{1}", e, MonoUsbApi.StrError(e))); } // Create a vendor specific control setup, allocate 1 byte for return control data. byte requestType = (byte)(UsbCtrlFlags.Direction_In | UsbCtrlFlags.Recipient_Device | UsbCtrlFlags.RequestType_Vendor); byte request = 0x0F; MonoUsbControlSetupHandle controlSetupHandle = new MonoUsbControlSetupHandle(requestType, request, 0, 0, 1); // Transfer the control setup packet ret = libusb_control_transfer(myDeviceHandle, controlSetupHandle, 1000); if (ret > 0) { rtb.AppendText("\nSuccess!\n"); byte[] ctrlDataBytes = controlSetupHandle.ControlSetup.GetData(ret); string ctrlDataString = Helper.HexString(ctrlDataBytes, String.Empty, "h "); rtb.AppendText(string.Format("Return Length: {0}", ret)); rtb.AppendText(string.Format("DATA (hex) : [ {0} ]\n", ctrlDataString.Trim())); } MonoUsbApi.ReleaseInterface(myDeviceHandle, 0); } finally { profileList.Close(); if (myDeviceHandle != null) { myDeviceHandle.Close(); } sessionHandle.Close(); } }
void testComms() { if (profiles.Count < 1) { logger.info("testComms: no profiles"); return; } foreach (MonoUsbProfile profile in profiles) { MonoUsbDeviceHandle device = null; try { logger.info("Opening {0:x4}:{1:x4}", profile.DeviceDescriptor.VendorID, profile.DeviceDescriptor.ProductID); device = profile.OpenDeviceHandle(); if (device.IsInvalid) { logger.error("Failed opening device handle: {0} ({1})", MonoUsbDeviceHandle.LastErrorCode, MonoUsbDeviceHandle.LastErrorString); continue; } // re-confirm configurations for this profile for (byte i = 0; i < profile.DeviceDescriptor.ConfigurationCount; i++) { MonoUsbConfigHandle configHandle; if (MonoUsbApi.GetConfigDescriptor(profile.ProfileHandle, i, out configHandle) < 0) { continue; } if (configHandle.IsInvalid) { continue; } MonoUsbConfigDescriptor configDescriptor = new MonoUsbConfigDescriptor(configHandle); logger.info(" configuration #{0}: {1} ({2})", i, configDescriptor.bConfigurationValue, configDescriptor); logger.info(" type = {0}", configDescriptor.bDescriptorType); logger.info(" length = {0}", configDescriptor.bLength); logger.info(" attributes = {0:x2}", configDescriptor.bmAttributes); logger.info(" interfaces = {0}", configDescriptor.bNumInterfaces); logger.info(" extLength = {0}", configDescriptor.ExtraLength); logger.info(" iConfig = {0}", configDescriptor.iConfiguration); logger.info(" maxPower = {0}", configDescriptor.MaxPower); logger.info(" totalLength= {0}", configDescriptor.wTotalLength); } int result = 0; // Set Configuration // Note: http://libusb.sourceforge.net/api-1.0/caveats.html#configsel MonoUsbError error = (MonoUsbError)(result = MonoUsbApi.SetConfiguration(device, 1)); if (false && result < 0) { logger.error("Failed SetConfiguration: {0} ({1}) (result = {2})", error, MonoUsbApi.StrError(error), result); continue; } // Claim Interface error = (MonoUsbError)(result = MonoUsbApi.ClaimInterface(device, 0)); if (result < 0) { logger.error("Failed ClaimInterface: {0} ({1})", error, MonoUsbApi.StrError(error)); continue; } // retain device handles devices.Add(device); byte DEVICE_TO_HOST = 0xc0; byte SECOND_TIER_COMMAND = 0xff; byte GET_MODEL_CONFIG = 0x01; byte PAGE_SIZE = 64; byte PAGE_ID = 0; int TIMEOUT_MS = 1000; // Create a vendor specific control setup, allocate 1 byte for return control data. // byte requestType = (byte)(UsbCtrlFlags.Direction_In | UsbCtrlFlags.Recipient_Device | UsbCtrlFlags.RequestType_Vendor); // byte request = 0x0F; // MonoUsbControlSetupHandle controlSetupHandle = new MonoUsbControlSetupHandle(requestType, request, 0, 0, 1); MonoUsbControlSetupHandle controlSetupHandle = new MonoUsbControlSetupHandle(DEVICE_TO_HOST, SECOND_TIER_COMMAND, GET_MODEL_CONFIG, PAGE_ID, PAGE_SIZE); // Transfer the control setup packet int len = libusb_control_transfer(device, controlSetupHandle, TIMEOUT_MS); if (len > 0) { logger.info("Success"); byte[] ctrlDataBytes = controlSetupHandle.ControlSetup.GetData(len); string ctrlDataString = Helper.HexString(ctrlDataBytes, String.Empty, "h "); logger.info("Return Length: {0}", len); logger.info("DATA (hex) : [ {0} ]", ctrlDataString.Trim()); } MonoUsbApi.ReleaseInterface(device, 0); } finally { if (device != null) { logger.info("closing device"); device.Close(); } } } }
private void SendCommand(byte[] data, int duration) { MonoUsbProfileList profileList = new MonoUsbProfileList(); MonoUsbDeviceHandle myDeviceHandle = null; try { // The list is initially empty. // Each time refresh is called the list contents are updated. profileList.Refresh(sessionHandle); // Use the GetList() method to get a generic List of MonoUsbProfiles // Find the first profile that matches in MyVidPidPredicate. MonoUsbProfile myProfile = profileList.GetList().Find(MyVidPidPredicate); if (myProfile == null) { Console.WriteLine("Device not connected."); return; } Console.WriteLine("Device connected."); // Open the device handle to perform I/O myDeviceHandle = myProfile.OpenDeviceHandle(); if (myDeviceHandle.IsInvalid) { throw new Exception(String.Format("Failed opening device handle.\n{0}:{1}", MonoUsbDeviceHandle.LastErrorCode, MonoUsbDeviceHandle.LastErrorString)); } int ret; MonoUsbError e; // Set Configuration e = (MonoUsbError)(ret = MonoUsbApi.SetConfiguration(myDeviceHandle, 1)); if (ret < 0) { throw new Exception(String.Format("Failed SetConfiguration.\n{0}:{1}", e, MonoUsbApi.StrError(e))); } // Claim Interface e = (MonoUsbError)(ret = MonoUsbApi.ClaimInterface(myDeviceHandle, 0)); if (ret < 0) { throw new Exception(String.Format("Failed ClaimInterface.\n{0}:{1}", e, MonoUsbApi.StrError(e))); } // Create a vendor specific control setup, allocate 1 byte for return control data. byte requestType = 0x40;// (byte)(UsbCtrlFlags.Direction_In | UsbCtrlFlags.Recipient_Device | UsbCtrlFlags.RequestType_Vendor); byte request = 6; MonoUsbControlSetupHandle controlSetupHandle = new MonoUsbControlSetupHandle(requestType, request, 0x100, 0, data, 3); // Transfer the control setup packet ret = ControlTransfer(myDeviceHandle, controlSetupHandle, 1000); Thread.Sleep(duration); object data2 = new byte[] { 0, 0, 0 }; MonoUsbControlSetupHandle controlSetupHandle2 = new MonoUsbControlSetupHandle(requestType, request, 0x100, 0, data2, 3); ret = ControlTransfer(myDeviceHandle, controlSetupHandle2, 1000); Thread.Sleep(500); if (ret > 0) { Console.WriteLine("\nSuccess!\n"); byte[] ctrlDataBytes = controlSetupHandle.ControlSetup.GetData(ret); string ctrlDataString = Helper.HexString(ctrlDataBytes, String.Empty, "h "); Console.WriteLine("Return Length: {0}", ret); Console.WriteLine("DATA (hex) : [ {0} ]\n", ctrlDataString.Trim()); } MonoUsbApi.ReleaseInterface(myDeviceHandle, 0); } finally { profileList.Close(); if (myDeviceHandle != null) { myDeviceHandle.Close(); } sessionHandle.Close(); Console.WriteLine("End"); } }