Click here to Skip to main content
15,175,525 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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

C#
/// <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
C#
/// <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

C#
/// <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
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;

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

C#
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

C#
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.
   
I have the same problem and I expect an answer to this problem:) Thanks
   

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




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900