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); }