Click here to Skip to main content
Rate this: bad
good
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 0:00am
Edited 11-Feb-13 4:26am
v5
Comments
Alan N at 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 at 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 at 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 at 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;

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

  Print Answers RSS
0 OriginalGriff 310
1 Sergey Alexandrovich Kryukov 166
2 PhilLenoir 164
3 Richard MacCutchan 160
4 Sharmanuj 146
0 Sergey Alexandrovich Kryukov 6,081
1 OriginalGriff 5,115
2 CPallini 2,473
3 Richard MacCutchan 1,597
4 Abhinav S 1,505


Advertise | Privacy | Mobile
Web02 | 2.8.140814.1 | Last Updated 11 Feb 2013
Copyright © CodeProject, 1999-2014
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