Click here to Skip to main content
12,767,912 members (44,329 online)
Rate this:
 
Please Sign up or sign in to vote.
See more: C# USB/HID
I'm writing an application to read a USB Cardreader. I'm using the FileStream.BeginRead Async method to read the usb CardReader. but it doesn't seem to return. I was wondering what I am doing wrong here? The PC sees the cardreader as a keybord hid device, I wonder if that is the problem. Can Someone explain to me?

The Callback function only returns if I pull it out of the PC

/// <summary>
        /// Initialises the device
        /// </summary>
        /// <param name="strPath">Path to the device</param>
        private void Initialise(String strPath)
        {
            // Create the file from the device path
            MySafeHandle = CreateFile(strPath, FileAccess.ReadWrite, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, 
                EFileAttributes.Overlapped, IntPtr.Zero);
            if (!MySafeHandle.IsInvalid)   // if the open worked...
            {
                IntPtr lpData;
                if (HidD_GetPreparsedData(MySafeHandle, out lpData))
                    // get windows to read the device data into an internal buffer
                {
                    try
                    {
                        HidCaps hidCaps;
                        HidP_GetCaps(lpData, out hidCaps); // extract the device capabilities from the internal buffer
                        InputReportLength = hidCaps.InputReportByteLength; // get the input...
                        OutputReportLength = hidCaps.OutputReportByteLength; // ... and output report lengths
                        MyFileStream = new FileStream((SafeFileHandle) MySafeHandle, FileAccess.ReadWrite, InputReportLength,
                                                    true); // wrap the file handle in a .Net file stream
                        BeginAsyncRead(); // kick off the first asynchronous read
                    }
                    finally
                    {
                        HidD_FreePreparsedData(ref lpData);
                            // before we quit the funtion, we must free the internal buffer reserved in GetPreparsedData
                    }
                }
                else // GetPreparsedData failed? Chuck an exception
                    throw HidDeviceException.GenerateWithWinError("GetPreparsedData failed");
            }
            else  // File open failed? Chuck an exception
            {
                MySafeHandle.Dispose();
                throw HidDeviceException.GenerateWithWinError("Failed to create device file");
            }
        }


Here is the BeginRead
/// <summary>
        /// Kicks off an asynchronous read which completes when data is read or when the device
        /// is disconnected. Uses a callback.
        /// </summary>
        private void BeginAsyncRead()
        {
            Byte[] buffer = new Byte[InputReportLength];
            // put the buff we used to receive the stuff as the async state then we can get at it when the read completes
            IAsyncResult result = MyFileStream.BeginRead(buffer, 0, InputReportLength, ReadCompleted, buffer);
        }


This is the Callback function

/// <summary>
        /// Callback for above. Care with this as it will be called on the background thread from the async read
        /// </summary>
        /// <param name="iResult">Async result parameter</param>
        private void ReadCompleted(IAsyncResult iResult)
        {
            Byte[] buffer = (Byte[])iResult.AsyncState; // retrieve the read buffer
            try
            {
                MyFileStream.EndRead(iResult); // call end read : this throws any exceptions that happened during the read
                try
                {
                    HandleDataReceived(buffer);    // pass the new input report on to the higher level handler
                }
                finally
                {
                    BeginAsyncRead();   // when all that is done, kick off another read for the next report
                }
            }
            catch (IOException)  // if we got an IO exception, the device was removed
            {
                HandleDeviceRemoved();
                if (OnDeviceRemoved != null)
                    OnDeviceRemoved(this, new EventArgs());
                Dispose();
            }
        }
Posted 11-Feb-13 1:00am
Updated 11-Feb-13 5:26am
v5
Comments
Alan N 11-Feb-13 11:01am
   
Just thinking. Have you tried doing a synchronous read, just a few bytes, to find out if you can read from the device?
Transitional 13-Feb-13 10:26am
   
Yes I am reading it with de LibUsb library this is written in C. But I would Like to write my own using C#
Saurabh_Damle 14-Feb-13 2:55am
   
Not sure but is it possible that every time
MyFileStream.BeginRead(buffer, 0, InputReportLength, ReadCompleted, buffer); starts at position 0 and reads upto InputReportLength. As InputReportLength value is not changed anywhere or the starting position for reading is always 0; the program every time reads same never seem to find end of input?
Transitional 14-Feb-13 4:05am
   
The InputReportLength gets its value from the host

public HidpCaps Capabilities;

Int32 result = Hid.HidP_GetCaps(preparsedData, ref deviceInformation.Capabilities); // The HidP_getCaps returns the infromation to HisCaps class.

Debug.WriteLine("usbGenericHidCommunication:queryDeviceCapabilities() -> Input Report Byte Length: {0}", deviceInformation.Capabilities.InputReportByteLength); The InputReportByLength is 48


[StructLayout(LayoutKind.Sequential)]
public struct HidpCaps
{
public System.UInt16 Usage; // USHORT
public System.UInt16 UsagePage; // USHORT
public System.UInt16 InputReportByteLength;
public System.UInt16 OutputReportByteLength;
public System.UInt16 FeatureReportByteLength;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
public System.UInt16[] Reserved; // USHORT Reserved[17];
public System.UInt16 NumberLinkCollectionNodes;
public System.UInt16 NumberInputButtonCaps;
public System.UInt16 NumberInputValueCaps;
public System.UInt16 NumberInputDataIndices;
public System.UInt16 NumberOutputButtonCaps;
public System.UInt16 NumberOutputValueCaps;
public System.UInt16 NumberOutputDataIndices;
public System.UInt16 NumberFeatureButtonCaps;
public System.UInt16 NumberFeatureValueCaps;
public System.UInt16 NumberFeatureDataIndices;
}
}
I wonder if canseek could be the problem, my filestream.canseek = false;
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 1

I ran into similar problem. Here is the snippet of problem code.

static void Main(string[] args)
       {
           FileStream stream = new FileStream("test.txt",FileMode.Open);
           byte[] data = new byte[2];
           var result = stream.BeginRead(data, 0, 2, ReadSuccess, data);
           stream.Close();
           Console.ReadLine();
       }

       static void ReadSuccess(IAsyncResult result)
       {
           Console.WriteLine("Result {0}",(result.AsyncState as byte[])[0]);
       }


I had AB in the file, and was expecting 65 in the console.Writeline.

It turns out that stream is closed immediately after I called BeginRead. Simple arrangement is to call Console.ReadLine before I close the stream

static void Main(string[] args)
        {
            FileStream stream = new FileStream("test.txt",FileMode.Open);
            byte[] data = new byte[2];
            var result = stream.BeginRead(data, 0, 2, ReadSuccess, data);
            Console.ReadLine();
            stream.Close();
        }


Even in your case BeginRead moved past just like in this case.
  Permalink  
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 2

I have the same problem and I expect an answer to this problem:) Thanks
  Permalink  

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

    Print Answers RSS
Top Experts
Last 24hrsThis month


Advertise | Privacy | Mobile
Web02 | 2.8.170217.1 | Last Updated 5 Dec 2014
Copyright © CodeProject, 1999-2017
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100