Author Topic: Read second packet with NativeMethods.WinUsb_ReadPipe func  (Read 7458 times)

Kukoracha

  • Member
  • ***
  • Posts: 4
Read second packet with NativeMethods.WinUsb_ReadPipe func
« on: December 24, 2015, 04:40:04 am »
Hi Jan,

I saw similar question in your forum, but link with code example does not exist any more, so I decided to ask again.

My usb device connected to PC through winUsb and working in bulk mode. I'm using your code example (thank you very-very much for it) to transfer data.
When I send one request packet and get one response packet, all works fine. The problem is when I'm trying to receive more than one response packet,
first packet is caught by NativeMethods.WinUsb_ReadPipe function, but second call to NativeMethods.WinUsb_ReadPipe function cause its to disappear. I know that the device has sent two packages.

Any advice?


Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Read second packet with NativeMethods.WinUsb_ReadPipe func
« Reply #1 on: December 24, 2015, 11:48:41 am »
If I recall correctly, WinUsb_ReadPipe will return as many data packets as will fit in the buffer provided. To read multiple packets (when available), increase the buffer size. (Try it to confirm.)

If the missing example code was at lvr.com, replace lvr.com with janaxelson.com. I thought I had fixed all of the URLs on this site, but I may have missed one.

I'm not sure what you mean by "second call to NativeMethods.WinUsb_ReadPipe function cause its to disappear." Are you saying that the second call returns no data when you know the device had sent another packet?

Kukoracha

  • Member
  • ***
  • Posts: 4
Re: Read second packet with NativeMethods.WinUsb_ReadPipe func
« Reply #2 on: December 28, 2015, 07:24:50 am »
Hi Jan,
thank you very much for your answer.

1. Increase the buffer size doesn't help me, because in my scenario I don't know the number of packets that device will send.


2. I debugged the code more and found out follow:
This is my code, based on your example:

   int circle = 0;
   int error;
  success = true;
   if (!(winUsbHandle.IsInvalid))
         {
                        while (success)
                        {
                            success = NativeMethods.WinUsb_ReadPipe
                                (winUsbHandle,
                                 myDeviceInfo.BulkInPipe,
                                 dataBuffer,
                                 bytesToRead,
                                 ref bytesRead,
                                 IntPtr.Zero);
                   
                            circle++;
                        }
                      error = Marshal.GetLastWin32Error();

      }

My device send to the PC X packets. And when NativeMethods.WinUsb_ReadPipe called in X+1 time, and I suppose it will turn back after TimeOut with "false", it just dissapeares and I get back the frmMain(WinUsb Demo). When I close the form, I get error=0x3E3.
 
ERROR_OPERATION_ABORTED
995 (0x3E3)
The I/O operation has been aborted because of either a thread exit or an application request.



Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Read second packet with NativeMethods.WinUsb_ReadPipe func
« Reply #3 on: December 28, 2015, 04:15:14 pm »
You don't have to know the expected number of packets or bytes. The function will return multiple packets if they are available and will fit in the buffer (as I recall). Using a larger buffer can reduce the number of read operations.

In the code you posted, on failure to read data, the while loop ends. If you expect more data to arrive, you can structure the loop to continue until the amount of data you want has been received or an application-specified timeout has occurred.

Kukoracha

  • Member
  • ***
  • Posts: 4
Re: Read second packet with NativeMethods.WinUsb_ReadPipe func
« Reply #4 on: December 29, 2015, 03:06:43 am »
That's exactly the point, in the code I posted, there is no failure to read data and the while loop don't ends. When there is no data to read or less than in Read Buffer size function WinUsb_ReadPipe stucks, and only when I manually stop the process (by closing form WinUsb Demo), the WinUsb_ReadPipe function returns with false result.

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Read second packet with NativeMethods.WinUsb_ReadPipe func
« Reply #5 on: December 29, 2015, 11:17:06 am »
The documentation says that the default timeout for bulk pipes is zero, but perhaps that means "none." Try a larger value.

https://msdn.microsoft.com/en-us/library/windows/hardware/ff728833%28v=vs.85%29.aspx

Kukoracha

  • Member
  • ***
  • Posts: 4
Re: Read second packet with NativeMethods.WinUsb_ReadPipe func
« Reply #6 on: December 30, 2015, 08:40:41 am »
Hi Jan,

I added GetPipePolicy function to the project and checked the POLICY_TYPE.PIPE_TRANSFER_TIMEOUT value in different places in the code.
In _myWinUs Communications.Initialize Device after SetPipePolicy I call to GetPipePolicy, the function returned with success result and I get the same TimeOut value, as I set in previous function.
But in ReceiveDataViaBulkTransfer function GetPipePolicy returns with true and the POLICY_TYPE.PIPE_TRANSFER_TIMEOUT value was 0!

This code return after timeout expired:

if (!(winUsbHandle.IsInvalid))
               {
                     //   while (success)
                     //   {
                        byte timeout = 0x01;
                        bool result = GetPipePolicy
                                      (winUsbHandle,
                                       myDeviceInfo.BulkInPipe,
                                       Convert.ToUInt32(NativeMethods.POLICY_TYPE.PIPE_TRANSFER_TIMEOUT),
                                       timeout); // timeout=0 !
                        const uint pipeTimeout = 1000;
                        result = SetPipePolicy
                                            (winUsbHandle,
                                             myDeviceInfo.BulkInPipe,
                                             Convert.ToUInt32(NativeMethods.POLICY_TYPE.PIPE_TRANSFER_TIMEOUT),
                                             pipeTimeout);
                        while (success)
                              {

                        success = NativeMethods.WinUsb_ReadPipe
                            (winUsbHandle,
                             myDeviceInfo.BulkInPipe,
                             dataBuffer,
                             bytesToRead,
                             ref bytesRead,
                             IntPtr.Zero);
       
                   
                            circle++;
                       }
                      error = Marshal.GetLastWin32Error();

Any ideas why it happens?

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Read second packet with NativeMethods.WinUsb_ReadPipe func
« Reply #7 on: December 30, 2015, 10:22:05 am »
Try

const ULONG pipeTimeout = 1000;
« Last Edit: December 30, 2015, 11:03:44 am by Jan Axelson »