Author Topic: Safe handle closed on FeatureReportReads  (Read 18782 times)

jglawrence

  • Member
  • ***
  • Posts: 13
Safe handle closed on FeatureReportReads
« on: December 19, 2011, 11:45:57 am »
I'm basing a project off of your C# 5.0 version of the HID code.  Instead of reading byte-by-byte I've tried to setup a system that sends a command and then reads the entire response.  This requires multiple calls to GetFeatureReport(...) since the responses can be more than 64 bytes.

I also have a repeat feature that calls my commands to be sent X amount of times.  This is executed using a timer set to 10ms timeouts.  Whenever I use this feature is when I get the error below, I always send and receive the first command okay but after that the program locks up and about 30 secs later my debugger tells me the error below.

The error I'm getting is the following:
ObjectDisposedException was unhandled by user code
Safe handle has been closed

The code I am using is below, also I am using Visual C# 2010 Express:
Code: [Select]
private void ExchangeFeatureReports(ref String command)
        {            
            String byteValue = null;
            Int32 count = 0;
            Byte[] commandBufferTemp = null;
            Byte[] inFeatureReportBuffer = null;
            Byte[] fullFeatureReportBuffer = null;
            Byte[] outFeatureReportBuffer = null;
            Boolean success = false;
            int j = 0;
            
            try
            {  
                //inFeatureReportBuffer = null;
                
                if ( ( MyHid.Capabilities.FeatureReportByteLength > 0 ) )
                {                    
                    //  The HID has a Feature report.

                    commandBufferTemp = new Byte[command.Length];

                    for (int i = 0; i < command.Length; i++)
                    {
                        commandBufferTemp[i] = Convert.ToByte(command[i]);
                    }
                    
                    //  Set the size of the Feature report buffer.
                    //  Subtract 1 from the value in the Capabilities structure because
                    //  the array begins at index 0.
                    outFeatureReportBuffer = new Byte[ MyHid.Capabilities.FeatureReportByteLength ];
                    
                    //  Store the report ID in the buffer:
                    outFeatureReportBuffer[ 0 ] = 0;
                    
                    //  Store the report data following the report ID.
                    //  Use the data in the combo boxes on the form.
                    commandBufferTemp.CopyTo(outFeatureReportBuffer, 1);
                    
                    //  Write a report to the device
                    success = MyHid.SendFeatureReport(hidHandle, outFeatureReportBuffer);

if (success)
{
lstResults.Items.Add("A Feature report has been written.");
}
else
{
CloseCommunications();
lstResults.Items.Add("The attempt to send a Feature report failed.");
}
                                       
                    //  Read a report from the device.
                    
                    //  Set the size of the Feature report buffer.
                    //  Subtract 1 from the value in the Capabilities structure because
                    //  the array begins at index 0.
                    if ( ( MyHid.Capabilities.FeatureReportByteLength > 0 ) )
                    {
                        inFeatureReportBuffer = new Byte[ MyHid.Capabilities.FeatureReportByteLength ];
                        fullFeatureReportBuffer = new Byte[2048];
                    }
                    
                    //  Read a report.
                    do
                    {
                        success = MyHid.GetFeatureReport(hidHandle, ref inFeatureReportBuffer);

                        if ((success) && (inFeatureReportBuffer[1] != '\0'))
                        {
                            lstResults.Items.Add("A Feature report has been read.");

                            for (int i = 1; i < inFeatureReportBuffer.Length; i++, j++)
                            {
                                fullFeatureReportBuffer[j] = inFeatureReportBuffer[i];
                            }
                        }
                        else
                        {
                            CloseCommunications();
                            lstResults.Items.Add("The attempt to read a Feature report failed.");
                            break;
                        }
                        System.Threading.Thread.Sleep(100);
                    } while (inFeatureReportBuffer[1] != '\0');

                    if (success)
                    {
                        DisplayFeatureReport(ref fullFeatureReportBuffer);
                    }
                }
                else
                {
                    lstResults.Items.Add( "The HID doesn't have a Feature report." );
                }
                
                ScrollToBottomOfListBox();                
                cmdSend.Enabled = true;                
            }
            catch ( Exception ex )
            {
                DisplayException( this.Name, ex );
                throw ;
            }            
        }
        
        void DisplayFeatureReport(ref Byte[] FeatureReport)
        {
            String response = System.Text.Encoding.ASCII.GetString(FeatureReport);
            response = response.Replace('\0', ' ').TrimEnd();
            txtBytesReceived.AppendText(response);
            txtBytesReceived.AppendText(Environment.NewLine);
        }
« Last Edit: December 19, 2011, 11:53:28 am by jglawrence »

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Safe handle closed on FeatureReportReads
« Reply #1 on: December 19, 2011, 12:13:49 pm »
So the host sends a command using an Output or Feature report and then tries to read multiple Feature reports but fails with a closed handle after the first one?

Have you tried setting a breakpoint after receiving the first report and stepping through to see if you can trigger the error and find out where it's happening?

Jan

jglawrence

  • Member
  • ***
  • Posts: 13
Re: Safe handle closed on FeatureReportReads
« Reply #2 on: December 19, 2011, 01:01:23 pm »
Yes, the host is sending a feature report. I guess I should explain my process.
say I type the following commands to send
id
Repeat: 1

When I click "Send" a bool flag is set to true that the timer's timeout event handler looks for, if it is true then the event handler runs a parsing function.
The parsing function either sends the command ("id") to ExchangeFeatureReports via reference or see's a "Repeat" and does what is necessary to keep the "Send" flag true and go back to the first command ("id" in this case, 1 time).

So I have a loop that is looking for the "Send" flag and a parsing function that calls ExchangeFeatureReports.

On the first call to ExchangeFeatureReports I always get a full report back but after I execute "Repeat" and call ExchangeFeatureReports again, I get the Safe handle error.

ExchangeFeatureReports is basically the same function as yours except I convert a String to a byte-array to send and I receive until I get a null report.  Could this be a bad way to do this?  I notice in the log it says "The attempt to read a Feature report failed."  Perhaps getting reports up until the null report is causing the handle to close?

Here is my looping code specifically, I declared another byte array to hold the total amount of data:
Code: [Select]
//  Read a report.
                    do
                    {
                        success = MyHid.GetFeatureReport(hidHandle, ref inFeatureReportBuffer);

                        if ((success) && (inFeatureReportBuffer[1] != '\0'))
                        {
                            lstResults.Items.Add("A Feature report has been read.");

                            for (int i = 1; i < inFeatureReportBuffer.Length; i++, j++)
                            {
                                fullFeatureReportBuffer[j] = inFeatureReportBuffer[i];
                            }
                        }
                        else
                        {
                            CloseCommunications();
                            lstResults.Items.Add("The attempt to read a Feature report failed.");
                            break;
                        }
                        System.Threading.Thread.Sleep(100);
                    } while (inFeatureReportBuffer[1] != '\0');

jglawrence

  • Member
  • ***
  • Posts: 13
Re: Safe handle closed on FeatureReportReads
« Reply #3 on: December 19, 2011, 01:02:21 pm »
I should also note that clicking "Send" from the GUI over and over again works fine and slowing the timer down does not make a difference.

The problem seems to reside in letting the code repeat the statement from some reason.

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Safe handle closed on FeatureReportReads
« Reply #4 on: December 19, 2011, 01:15:08 pm »
Does the device have a Feature report to send or is it NAKing the Data stage of the request?

Jan

jglawrence

  • Member
  • ***
  • Posts: 13
Re: Safe handle closed on FeatureReportReads
« Reply #5 on: December 19, 2011, 01:44:18 pm »
It should be NAKing but that's something I can double-check.

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Safe handle closed on FeatureReportReads
« Reply #6 on: December 19, 2011, 02:41:34 pm »
If it's NAKing, the transfer will fail (time out).

Jan

jglawrence

  • Member
  • ***
  • Posts: 13
Re: Safe handle closed on FeatureReportReads
« Reply #7 on: December 19, 2011, 03:06:51 pm »
Oh okay, that makes sense.
I "fixed" the issue by running the FindTheHID() function every time the timer calls if the hidHandle is invalid or myDeviceDetected is false.  This isn't ideal though in my opinion.

Do you have any suggestions for knowing how many Feature reports to read before reading a NAK report and timing out the transfer?

Thanks!

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Safe handle closed on FeatureReportReads
« Reply #8 on: December 19, 2011, 03:19:01 pm »
There is no way to know in advance except for vendor-specific protocols (for example, if the device always sends three reports).

Instead of gathering data in multiple reports, you could define a longer report and have the device pad it with zeroes or other data when there is less data.

The application doesn't have to close the handle if the device doesn't return a report. Just accept the timeout and continue.

Jan