Пример #1
0
            public override int Read(byte[] dest, int timeoutMillis)
            {
                if (mEnableAsyncReads)
                {
                    UsbRequest request = new UsbRequest();

                    try
                    {
                        request.Initialize(mConnection, mReadEndpoint);

                        // CJM: Xamarin bug:  ByteBuffer.Wrap is supposed to be a two way update
                        // Changes made to one buffer should reflect in the other.  It's not working
                        // As a work around, I added a new method as an extension that uses JNI to turn
                        // a new byte[] array.  I then used BlockCopy to copy the bytes back the original array
                        // see https://forums.xamarin.com/discussion/comment/238396/#Comment_238396
                        //
                        // Old work around:
                        // as a work around, we populate dest with a call to buf.Get()
                        // see https://bugzilla.xamarin.com/show_bug.cgi?id=20772
                        // and https://bugzilla.xamarin.com/show_bug.cgi?id=31260

                        ByteBuffer buf = ByteBuffer.Wrap(dest);
                        if (!request.Queue(buf, dest.Length))
                        {
                            throw new IOException("Error queueing request.");
                        }

                        UsbRequest response = mConnection.RequestWait();
                        if (response == null)
                        {
                            throw new IOException("Null response");
                        }

                        int nread = buf.Position();
                        if (nread > 0)
                        {
                            // CJM: This differs from the Java implementation.  The dest buffer was
                            // not getting the data back.

                            // 1st work around, no longer used
                            //buf.Rewind();
                            //buf.Get(dest, 0, dest.Length);
                            System.Buffer.BlockCopy(buf.ToByteArray(), 0, dest, 0, dest.Length);

                            //Log.Debug(TAG, HexDump.DumpHexString(dest, 0, Math.Min(32, dest.Length)));
                            return(nread);
                        }
                        else
                        {
                            return(0);
                        }
                    }
                    finally
                    {
                        request.Close();
                        request.Dispose();//richard: dispose request
                    }
                }

                int numBytesRead;

                lock (mReadBufferLock)
                {
                    int readAmt = Math.Min(dest.Length, mReadBuffer.Length);
                    numBytesRead = mConnection.BulkTransfer(mReadEndpoint, mReadBuffer, readAmt,
                                                            timeoutMillis);
                    if (numBytesRead < 0)
                    {
                        // This sucks: we get -1 on timeout, not 0 as preferred.
                        // We *should* use UsbRequest, except it has a bug/api oversight
                        // where there is no way to determine the number of bytes read
                        // in response :\ -- http://b.android.com/28023
                        if (timeoutMillis == Integer.MaxValue)
                        {
                            // Hack: Special case "~infinite timeout" as an error.
                            return(-1);
                        }
                        return(0);
                    }
                    System.Buffer.BlockCopy(mReadBuffer, 0, dest, 0, numBytesRead);
                }
                return(numBytesRead);
            }