5

I'm using the LibUSBDotNet library in a WPF application that communicates with a simple USB device. I'm only sending 3 bytes to the device as a command, there's no response to be expected from it and my code works like a charm:

MyUsbFinder = new UsbDeviceFinder(vid, pid);
MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);
wholeUsbDevice = MyUsbDevice as IUsbDevice;
if (!ReferenceEquals(wholeUsbDevice, null))
{
    wholeUsbDevice.SetConfiguration(1);
    wholeUsbDevice.ClaimInterface(0);
}

writer = MyUsbDevice.OpenEndpointWriter(WriteEndpointID.Ep01);

And then the process of writing to the device:

byte[] update = { 0x21, some_code_generated_byte, some_code_generated_byte };
int bytesWritten;

if (MyUsbDevice != null)
{
     ec = writer.Write(update, 2000, out bytesWritten);
}

I'm relatively new to working with USB but I got thus far and it all works. However, after awhile, every now and then, upon attempting to write again to the device I would get one of the following two errors:

Win32Error:GetOverlappedResult Ep 0x01
31:The parameter is incorrect.

Win32Error:PipeTransferSubmit Ep 0x01
87:The parameter is incorrect.

Often I need to restart the device/application several times before it starts working again and then it goes another several hours working like a charm before it happens again... I have not been able to replicate the crash so far in a testing environment either.

I did a lot of research trying to find a problem/solution similar to mine with no success. The only suggestion that I have left is that at some point the device does not have enough power and it goes into this error mode but even that seems unlikely as it has a separate 12V power supply and all that it does is to switch on and off several relays...

I've also tried flooding the device with a lot of consecutive commands one after another, including garbage ones but it still works and behaves properly only to crash a little bit later.

Open to any suggestions or ideas, thank you!

EDIT: After many attempts I'm still not able to identify the root cause of the issue but I managed to get to a point where my code is working and is able to recover from the OverlappedResult error using reconnect functions that try to reset the device once it starts failing. I'm posting some code below and hopefully someone will be able to narrow down the issue and identify the cause of the error.

Some code during initialization:

        UsbDeviceFinder MyUsbFinder;
        UsbDevice MyUsbDevice;
        IUsbDevice wholeUsbDevice;

                MyUsbFinder = new UsbDeviceFinder(vid, pid);
                MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);

                    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.
                        // I think those do make some difference...

                        // Select config #1
                        wholeUsbDevice.SetConfiguration(1);

                        // Claim interface #0.
                        wholeUsbDevice.ClaimInterface(0);
                    }

                    writer = MyUsbDevice.OpenEndpointWriter(WriteEndpointID.Ep01);

Next I'm trying to send some information to the device. This is where the error will eventually pop up and I'm catching it as an exception in a simple try/catch block:

ErrorCode ec = ErrorCode.None;
if (MyUsbDevice != null)
{
    ec = writer.Write(update, 2000, out bytesWritten);
    if (ec != ErrorCode.None)
    {
        //now try to reconnect to the device, dispose writer first
        writer.Dispose(); // I think this also helps to reestablish the connection and get rid of the error
        if (this.reconnect())
        {
            //reconnected, try to write to the device again
            ec = writer.Write(update, 2000, out bytesWritten);
            if (ec != ErrorCode.None)
            {
                //log the error
            }
        }
    }
}
else //there's no connection to the device, try to reconnect and update again
{
    //now try to reconnect to the device, dispose writer first
    //writer.Dispose();
    if (this.reconnect())
        updateRelayController(); 
}

Up there "update" is a byte array that I'm sending to my device with the appropriate commands and updateRelayController is actually the function that has the code snippet above writing commands to the USB device. Finally, here's my reconnect() function that manages to reestablish connection to the device 99% of the time without having to manually restart the device and plug/unplug usb cables, etc:

public bool reconnect()
{
    //clear the info so far
    if (MyUsbDevice != null)
    {
        writer.Dispose();
        wholeUsbDevice.ReleaseInterface(0);
        wholeUsbDevice.Close();
        MyUsbDevice.Close();
        UsbDevice.Exit();
    }

    //now start over
    MyUsbFinder = new UsbDeviceFinder(vid, pid);
    MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);

    // If the device is open and ready
    if (MyUsbDevice == null)
    {
        //log the error
        return false;
    }
    else
    {
        wholeUsbDevice = MyUsbDevice as IUsbDevice;
        if (!ReferenceEquals(wholeUsbDevice, null))
        {
            // Select config #1
            wholeUsbDevice.SetConfiguration(1);

            // Claim interface #0.
            wholeUsbDevice.ClaimInterface(0);
        }

        writer = MyUsbDevice.OpenEndpointWriter(WriteEndpointID.Ep01);

        return true;
    }
}

That's pretty much it so far. The combination of SetConfiguration/ClaimInterface/Dispose reduce the times I see the OverlappedResult error and whenever that happens, judging from my logs, I'm able to recover right away and resend the command to the device. As I said above, this is a workaround to the problem as I'm still getting the error every now and then and I still have no idea why, but at least I'm able to continue working with the device at this point. Would love to find out more on this issue if anyone has more insights. Thanks and I hope this helps!

mmvsbg
  • 3,570
  • 17
  • 52
  • 73
  • I'm having same problem. Have you find a solution for it ? I thought it can be variable type incompatibility while calling kernel methods or host device waiting for some data which I don't send it in time. – Davut Gürbüz May 21 '14 at 12:18
  • Hi, what kind of device are you using? Just wondering if it's the same as mine. After many tests and tweaks in the code I have the device working in production now almost without giving the error going for several days without problems. It would still give the OverlappedResult every now and then but I managed to write the code so it recovers without the need of human interaction. I'll have a look at the code over the weekend and I'll post an update here with my changes. Hopefully that will help! – mmvsbg May 21 '14 at 20:24
  • Hi, it is WelchAllyn's Propaq LT,a medical patient care device. As you said on the question after getting OverlappedResult error.I can't get any further meaningful response then. It stucks on OverlappedResult error. It would be great if you will be able to share your solution here. If you wanna chat with me and using skype, davut06 is my skype.Best wishes! – Davut Gürbüz May 22 '14 at 06:40
  • Hello, mine is quite different - simple relay controller but the problem is the same. I'll post a bit of code above to show you how I get around this issue. I haven't managed to identify the root cause of the problem yet but at least my code works and I'm almost always able to recover from the OverlappedResult and continue working without the need of human interaction using reconnect functions and trying to reset the device if it spits out the error. I'll add some comments in my code to explain what I've used and why. If you have any questions let me know and we can chat on skype.Best regards! – mmvsbg May 25 '14 at 14:42
  • I think this project is not a managed code. It relies on some kernel calls and it might fails on some multi threaded jobs. – Davut Gürbüz May 30 '14 at 12:50
  • thanks , helped but not solved yet :( Something goes wrong for me. – Davut Gürbüz May 30 '14 at 16:01
  • To continue the saga: We were testing new devices that we connected to the Relay Controller (RC) that I mentioned above. The RC (device my software is communicating with) simply switches a relay on/off allowing or not allowing electricity to flow through it. It seems that these new type of devices sent way too much electricity load to the RC so it would just shut itself down, throwing the same error. We had to install contactors, connect the devices to them and then connect the contactors to the RC to make it work. Different issue but hopefully this information might somehow be useful to you. – mmvsbg Jul 21 '14 at 11:16
  • I seem to be running into a similar issue when connecting to an i.MX28. In the second stage of an update one has to talk to a mock USB Mass Storage Device (Bulk Only Transfer), which is implemented by a Linux image running on the target. The very first command sequense (Command Block Wrapper and then CommandStatusWrapper). The status signals there's Sense Data, but the Request Sense (6) fails with this `GetOverlappedResult` error, even though the data is transferred just fine. I'm stuck on this, even after trying all (SW) suggestions mentioned above. – Magnus Aug 18 '14 at 14:27

2 Answers2

1

NOT an answer! (This is just a workaround to another problem. It fixes the given error while closing the app)

I'm writing this here because it won't be readable as a comment.(for code)

I just commented out the code on dispose as seen below.

    #region IDisposable Members

    /// <summary>
    /// Cancels any pending transfer and frees resources.
    /// </summary>
    public virtual void Dispose()
    {
        if (!IsCancelled) Cancel();

        //I just commented here.
        //int dummy; 
        //if (!mHasWaitBeenCalled) Wait(out dummy);

        if (mPinnedHandle != null) mPinnedHandle.Dispose();
        mPinnedHandle = null;
    }

    #endregion

    ~UsbTransfer() { Dispose(); }

and I couldn't get rid of getting this annoying error, I can send the first message but even I reconnect successfully to device there is no cure :(

EndPoint 0x0x1 is me end endpoint 0x81 is device but after getting this error ???? I don't understand why there isn't a managed lib for usb.

         05 FA 28 81 02 00 08 94 32 Win32Error:GetOverlappedResult Ep 0x81 
        31:
        Win32Error:PipeTransferSubmit Ep 0x01 
        22:
        Win32Error:DeviceIoControl code 00222058 failed: LibUsbDriverIO 
        22:
        Win32Error:PipeTransferSubmit Ep 0x01 
        22:
        Win32Error:DeviceIoControl code 00222058 failed: LibUsbDriverIO 
        22:
        Win32Error:PipeTransferSubmit Ep 0x01 
        22:
        Win32Error:DeviceIoControl code 00222058 failed: LibUsbDriverIO 
        22:
Davut Gürbüz
  • 5,526
  • 4
  • 47
  • 83
1

I also encountered the error:

Win32Error:PipeTransferSubmit Ep 0x02
87:The parameter is incorrect.

I found out that I was using the wrong WriteEndpointId. Refer to the API documentation.

goodbuoy
  • 543
  • 3
  • 6
  • As far as I remember (as this is an old issue now), I've tried using different WriteEndPointIds and I would occasionally get an error on all of them. Are you positive that you are not going to run into the issue after awhile with changing the WriteEndpointId? – mmvsbg Jul 30 '15 at 11:24
  • 1
    I used [usbview](https://msdn.microsoft.com/en-us/library/windows/hardware/ff560019(v=vs.85).aspx) to determine the correct WriteEndpointId. – goodbuoy Aug 07 '15 at 06:49