public async Task WriteAsync(byte[] data) { await Task.Run(async() => { try { //TODO: Perhaps we should implement Batch Begin/Complete so that the UsbRequest is not created again and again. This will be expensive var request = new UsbRequest(); var endpoint = ((AndroidUsbEndpoint)WriteEndpoint).UsbEndpoint; request.Initialize(_UsbDeviceConnection, endpoint); var byteBuffer = ByteBuffer.Wrap(data); Tracer?.Trace(true, data); #pragma warning disable CS0618 request.Queue(byteBuffer, data.Length); #pragma warning restore CS0618 await _UsbDeviceConnection.RequestWaitAsync(); } catch (Exception ex) { Logger?.Log(Messages.WriteErrorMessage, nameof(AndroidUsbInterface), ex, LogLevel.Error); throw new IOException(Messages.WriteErrorMessage, ex); } }); }
//TODO: Make async properly public async Task <byte[]> ReadAsync() { try { var byteBuffer = ByteBuffer.Allocate(ReadBufferLength); var request = new UsbRequest(); request.Initialize(_UsbDeviceConnection, _ReadEndpoint); request.Queue(byteBuffer, ReadBufferLength); await _UsbDeviceConnection.RequestWaitAsync(); var buffers = new byte[ReadBufferLength]; byteBuffer.Rewind(); for (var i = 0; i < ReadBufferLength; i++) { buffers[i] = (byte)byteBuffer.Get(); } //Marshal.Copy(byteBuffer.GetDirectBufferAddress(), buffers, 0, ReadBufferLength); Tracer?.Trace(false, buffers); return(buffers); } catch (Exception ex) { Logger.Log(Helpers.ReadErrorMessage, ex, LogSection); throw new IOException(Helpers.ReadErrorMessage, ex); } }
public override int Read(byte[] dest, int timeoutMillis) { if (ENABLE_ASYNC_READS) { var request = new UsbRequest(); try { request.Initialize(mConnection, mReadEndpoint); var buf = ByteBuffer.Wrap(dest); if (!request.Queue(buf, dest.Length)) { throw new IOException("Error queuing request"); } var response = mConnection.RequestWait(); if (response == null) { throw new IOException("Null response"); } var nread = buf.Position(); return(nread > 0 ? nread : 0); } finally { request.Close(); } } int numBytesRead; lock (mReadBufferLock) { var 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 == int.MaxValue) { // Hack: Special case "~infinite timeout" as an error. return(-1); } return(0); } Array.Copy(mReadBuffer, 0, dest, 0, numBytesRead); } return(numBytesRead); }
protected override int ReadInternal(byte[] dest, int timeoutMillis) { UsbEndpoint endpoint = UsbDevice.GetInterface(0).GetEndpoint(0); if (ENABLE_ASYNC_READS) { int readAmt; lock (mInternalReadBufferLock) { // mReadBuffer is only used for maximum read size. readAmt = Math.Min(dest.Length, mInternalReadBuffer.Length); } UsbRequest request = new UsbRequest(); request.Initialize(Connection, endpoint); ByteBuffer buf = ByteBuffer.Wrap(dest); if (!request.Queue(buf, readAmt)) { throw new IOException("Error queueing request."); } UsbRequest response = Connection.RequestWait(); if (response == null) { throw new IOException("Null response"); } int payloadBytesRead = buf.Position() - MODEM_STATUS_HEADER_LENGTH; if (payloadBytesRead > 0) { //Log.Debug(TAG, HexDump.DumpHexString(dest, 0, Math.Min(32, dest.Length))); return(payloadBytesRead); } else { return(0); } } else { int totalBytesRead; lock (mInternalReadBufferLock) { int readAmt = Math.Min(dest.Length, mInternalReadBuffer.Length); totalBytesRead = Connection.BulkTransfer(endpoint, mInternalReadBuffer, readAmt, timeoutMillis); if (totalBytesRead < MODEM_STATUS_HEADER_LENGTH) { throw new IOException("Expected at least " + MODEM_STATUS_HEADER_LENGTH + " bytes"); } return(FilterStatusBytes(mInternalReadBuffer, dest, totalBytesRead, endpoint.MaxPacketSize)); } } }
public override int Read(byte[] dest, int timeoutMilliseconds) { if (_enableAsyncReads) { var request = new UsbRequest(); try { request.Initialize(_connection, _readEndpoint); var buf = ByteBuffer.Wrap(dest); if (!request.Queue(buf, dest.Length)) //TODO: Must fix this { throw new UsbSerialException("Error queueing request."); } UsbRequest response = _connection.RequestWait(); if (response == null) { throw new UsbSerialException("Null response"); } int nread = buf.Position(); if (nread > 0) { return(nread); } else { return(0); } } finally { request.Close(); } } int numBytesRead; lock (_readBufferLock) { int readAmt = Math.Min(dest.Length, _readBuffer.Length); numBytesRead = _connection.BulkTransfer(_readEndpoint, _readBuffer, readAmt, timeoutMilliseconds); if (numBytesRead < 0) { if (timeoutMilliseconds == int.MaxValue) { return(-1); } return(0); } Array.Copy(_readBuffer, 0, dest, 0, numBytesRead); } return(numBytesRead); }
public override int Read(byte[] dest, int timeoutMilliseconds) { UsbEndpoint endpoint = _driver.Device.GetInterface(0).GetEndpoint(0); if (ENABLE_ASYNC_READS) { int readAmt; lock (_readBufferLock) { readAmt = Math.Min(dest.Length, _readBuffer.Length); } var request = new UsbRequest(); request.Initialize(_connection, endpoint); var buf = ByteBuffer.Wrap(dest); if (!request.Queue(buf, readAmt)) //TODO: Must fix this { throw new UsbSerialException("Error queueing request."); } UsbRequest response = _connection.RequestWait(); if (response == null) { throw new UsbSerialException("Null response"); } int payloadBytesRead = buf.Position() - MODEM_STATUS_HEADER_LENGTH; if (payloadBytesRead > 0) { Log.Debug(nameof(FtdiSerialDriver), HexDump.DumpHexString(dest, 0, Math.Min(32, dest.Length))); return(payloadBytesRead); } else { return(0); } } else { lock (_readBufferLock) { int readAmt = Math.Min(dest.Length, _readBuffer.Length); int totalBytesRead = _connection.BulkTransfer(endpoint, _readBuffer, readAmt, timeoutMilliseconds); if (totalBytesRead < MODEM_STATUS_HEADER_LENGTH) { throw new UsbSerialException($"Expected at least {MODEM_STATUS_HEADER_LENGTH} bytes"); } return(FilterStatusBytes(_readBuffer, dest, totalBytesRead, endpoint.MaxPacketSize)); } } }
protected override int ReadInternal() { if (EnableAsyncReads) { UsbRequest request = new UsbRequest(); try { request.Initialize(Connection, ReadEndpoint); ByteBuffer buf = ByteBuffer.Wrap(TempReadBuffer); if (!request.Queue(buf, TempReadBuffer.Length)) { throw new IOException("Error queueing request."); } UsbRequest response = Connection.RequestWait(); if (response == null) { throw new IOException("Null response"); } int nread = buf.Position(); if (nread > 0) { //Log.Debug(Tag, HexDump.DumpHexString(TempReadBuffer, 0, Math.Min(32, TempReadBuffer.Length))); return(nread); } else { return(0); } } finally { request.Close(); } } numberOfBytesRead = Connection.BulkTransfer(ReadEndpoint, TempReadBuffer, TempReadBuffer.Length, DEFAULT_READ_TIMEOUT_MILLISEC); //Log.Info(Tag, "Data Length : " + DateTime.Now.ToString("HH:mm:ss.fff") + ":" + numberOfBytesRead.ToString() + "\n"); if (numberOfBytesRead < 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 (DEFAULT_READ_TIMEOUT_MILLISEC == int.MaxValue) { // Hack: Special case "~infinite timeout" as an error. return(-1); } return(0); } return(numberOfBytesRead); }
public override void OnReceive(Context context, Intent intent) { String action = intent.Action; if (!IsReady && ACTION_USB_PERMISSION.Equals(action)) { lock (this) { Device = (UsbDevice)intent.GetParcelableExtra(UsbManager.ExtraDevice); if (intent.GetBooleanExtra(UsbManager.ExtraPermissionGranted, false)) { if (Device != null) { DeviceConnection = Manager.OpenDevice(Device); if (DeviceConnection.ClaimInterface(Interface, true)) { OutputRequest = new UsbRequest(); OutputRequest.Initialize(DeviceConnection, OutputEndpoint); InputRequest = new UsbRequest(); InputRequest.Initialize(DeviceConnection, InputEndpoint); HasPermission = true; IsReady = true; } } } } } else if (!IsReady && /*!HasPermission &&*/ USB_DEVICE_ATTACHED.Equals(action)) { // Parse for usb devices: ParseForUsbDevices(); // Hook up USB : PendingIntent pendingIntent = PendingIntent.GetBroadcast(MainActivity, 0, new Intent(ACTION_USB_PERMISSION), 0); IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION); filter.AddAction(USB_DEVICE_ATTACHED); MainActivity.RegisterReceiver(this, filter); if (Device != null && Interface != null && OutputEndpoint != null && InputEndpoint != null) { Manager.RequestPermission(Device, pendingIntent); HasPermission = Manager.HasPermission(Device); } } else if (USB_DEVICE_DETACHED.Equals(action)) { IsReady = false; } }
/// <summary> /// /// </summary> public virtual void OpenDevice(UsbDevice device) { // if ((m_UsbIntf = FindInterface(device)) == null) { Log.e("UsbStream", "Can't find the UsbInterface" + device.ToString() + "."); OnOpenFailure(); return; } // m_UsbConnection = m_UsbMgr.OpenDevice(m_UsbDevice = device); m_UsbConnection.ClaimInterface(m_UsbIntf, true); // m_UsbReqIn = new UsbRequest(); m_UsbReqIn.Initialize(m_UsbConnection, m_UsbIntf.intIn); // Check read buffer size. if (m_SizeRead == -1) { Log.i("UsbStream", "Use default read buffer size:" + (m_SizeRead = 64).ToString()); } #if USB_HANDLER_IN_UNITY // m_UsbBufferIn = ByteBuffer.Allocate(m_SizeRead); // m_ReadThread = new NativeThread(ReadThread_Step); //Looper m_ReadThread.StartLoop(); // #elif USB_HANDLER_IN_ANDROID AndroidJavaObject handler = new AndroidJavaObject ("android.unity.SafeUsbHandler", m_UsbConnection.m_SealedPtr, m_UsbReqIn.m_SealedPtr, m_SizeRead); handler.Call("setCallback", new CallbackProxy(this)); m_ReadThread = new NativeThread(handler); m_ReadThread.Start2(); #endif // UsbManager.main.onUsbDeviceDetached += OnUsbDeviceDetached; if (m_OpenCallback != null) { m_OpenCallback.OnStreamOpenSuccess(this); } // m_IsOpen = true; }
//TODO: Perhaps we should implement Batch Begin/Complete so that the UsbRequest is not created again and again. This will be expensive public async Task WriteAsync(byte[] data) { try { var request = new UsbRequest(); request.Initialize(_UsbDeviceConnection, _WriteEndpoint); var byteBuffer = ByteBuffer.Wrap(data); Tracer?.Trace(true, data); request.Queue(byteBuffer, data.Length); await _UsbDeviceConnection.RequestWaitAsync(); } catch (Exception ex) { Logger.Log(Helpers.WriteErrorMessage, ex, LogSection); throw new IOException(Helpers.WriteErrorMessage, ex); } }
public async Task <ReadResult> ReadAsync(uint bufferLength) { return(await Task.Run(async() => { try { var byteBuffer = ByteBuffer.Allocate((int)bufferLength); var request = new UsbRequest(); var endpoint = ((AndroidUsbEndpoint)ReadEndpoint).UsbEndpoint; request.Initialize(_UsbDeviceConnection, endpoint); #pragma warning disable CS0618 request.Queue(byteBuffer, (int)bufferLength); #pragma warning restore CS0618 await _UsbDeviceConnection.RequestWaitAsync(); //TODO: Get the actual length of the data read instead of just returning the length of the array var buffers = new ReadResult(new byte[bufferLength], bufferLength); byteBuffer.Rewind(); //Ouch. Super nasty for (var i = 0; i < bufferLength; i++) { buffers.Data[i] = (byte)byteBuffer.Get(); } //Marshal.Copy(byteBuffer.GetDirectBufferAddress(), buffers, 0, ReadBufferLength); Tracer?.Trace(false, buffers); return buffers; } catch (Exception ex) { Logger?.Log(Messages.ErrorMessageRead, nameof(AndroidUsbInterfaceManager), ex, LogLevel.Error); throw new IOException(Messages.ErrorMessageRead, ex); } })); }
public void Write(byte[] buffer, uint cbToWrite) { if (Connection != null) { if (EndpointWrite != null) { if (buffer.Length < cbToWrite) { byte[] temp = new byte[cbToWrite]; buffer.CopyTo(temp, 0); buffer = temp; } if (buffer[0] == 0) { cbToWrite--; byte[] temp = new byte[cbToWrite]; for (int x = 0; x < cbToWrite; x++) { temp[x] = buffer[x + 1]; } buffer = temp; } UsbRequest request = new UsbRequest(); ByteBuffer bytes644 = ByteBuffer.Wrap(buffer); request.Initialize(Connection, EndpointWrite); while (!request.Queue(bytes644, buffer.Length)) { Thread.Sleep(40); } if (Connection.RequestWait() == request) { Console.WriteLine("Changed Wavelength"); } } } }
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(); } } 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); }
public override int Read(byte[] dest, int timeoutMillis) { var endpoint = mDevice.GetInterface(0).GetEndpoint(0); if (ENABLE_ASYNC_READS) { int readAmt; lock (mReadBufferLock) { // mReadBuffer is only used for maximum read size. readAmt = Math.Min(dest.Length, mReadBuffer.Length); } var request = new UsbRequest(); request.Initialize(mConnection, endpoint); var buf = ByteBuffer.Wrap(dest); if (!request.Queue(buf, readAmt)) { throw new IOException("Error queueing request."); } var response = mConnection.RequestWait(); if (response == null) { throw new IOException("Null response"); } var payloadBytesRead = buf.Position() - MODEM_STATUS_HEADER_LENGTH; if (payloadBytesRead > 0) { // CJM: This differs from the Java implementation. The dest buffer was // not getting the data back. Buffer.BlockCopy(buf.ToByteArray(), 0, dest, 0, dest.Length); Log.Debug(TAG, HexDump.DumpHexString(dest, 0, Math.Min(32, dest.Length))); return(payloadBytesRead); } return(0); } int totalBytesRead; lock (mReadBufferLock) { var readAmt = Math.Min(dest.Length, mReadBuffer.Length); // todo: replace with async call totalBytesRead = mConnection.BulkTransfer(endpoint, mReadBuffer, readAmt, timeoutMillis); if (totalBytesRead < MODEM_STATUS_HEADER_LENGTH) { throw new IOException( "Expected at least " + MODEM_STATUS_HEADER_LENGTH + " bytes"); } return(FilterStatusBytes(mReadBuffer, dest, totalBytesRead, endpoint.MaxPacketSize)); } }
protected override int ReadInternal(byte[] dest, int timeoutMillis) { if (mEnableAsyncReads) { UsbRequest request = new UsbRequest(); try { request.Initialize(Connection, mReadEndpoint); ByteBuffer buf = ByteBuffer.Wrap(dest); if (!request.Queue(buf, dest.Length)) { throw new IOException("Error queueing request."); } UsbRequest response = Connection.RequestWait(); if (response == null) { throw new IOException("Null response"); } int nread = buf.Position(); if (nread > 0) { //Log.Debug(Tag, HexDump.DumpHexString(dest, 0, Math.Min(32, dest.Length))); return(nread); } else { return(0); } } finally { request.Close(); } } int numBytesRead; lock (mInternalReadBufferLock) { int readAmt = Math.Min(dest.Length, mInternalReadBuffer.Length); numBytesRead = Connection.BulkTransfer(mReadEndpoint, mInternalReadBuffer, 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 == int.MaxValue) { // Hack: Special case "~infinite timeout" as an error. return(-1); } return(0); } Array.Copy(mInternalReadBuffer, 0, dest, 0, numBytesRead); } return(numBytesRead); }
protected override int ReadInternal() { if (ENABLE_ASYNC_READS) { int readAmt; // MainReadBuffer is only used for maximum read size. readAmt = Math.Min(TempReadBuffer.Length, InternalReadBuffer.Length); UsbRequest request = new UsbRequest(); request.Initialize(Connection, readEndpoint); ByteBuffer buf = ByteBuffer.Wrap(TempReadBuffer); if (!request.Queue(buf, readAmt)) { throw new IOException("Error queueing request."); } UsbRequest response = Connection.RequestWait(); if (response == null) { throw new IOException("Null response"); } int payloadBytesRead = buf.Position() - MODEM_STATUS_HEADER_LENGTH; if (payloadBytesRead > 0) { //Log.Debug(TAG, HexDump.DumpHexString(TempReadBuffer, 0, Math.Min(32, TempReadBuffer.Length))); return(payloadBytesRead); } else { return(0); } } else { // Nexus5:データが読みだされるバッファが 256 の倍数以外では 57600bps 以上で Connection.BulkTransfer() が -1 を返す。原因は不明 totalBytesRead = Connection.BulkTransfer(readEndpoint, InternalReadBuffer, DEFAULT_INTERNAL_READ_BUFFER_SIZE, DEFAULT_READ_TIMEOUT_MILLISEC); if (totalBytesRead < MODEM_STATUS_HEADER_LENGTH) { throw new IOException("Expected at least " + MODEM_STATUS_HEADER_LENGTH + " bytes"); } //以下は FilterStatusBytes() として別関数だったものを組み込んだ //関数呼び出しの際に引数として渡されるオブジェクトを生成しないための処置 srcPtr = MODEM_STATUS_HEADER_LENGTH; destPtr = 0; validDataCount = maxPacketSize - MODEM_STATUS_HEADER_LENGTH; rawDataCount = 0; while (totalBytesRead > 0) { if (totalBytesRead > maxPacketSize) { validDataCountInPacket = validDataCount; totalBytesRead -= maxPacketSize; } else { validDataCountInPacket = totalBytesRead - MODEM_STATUS_HEADER_LENGTH; totalBytesRead = 0; } Array.Copy(InternalReadBuffer, srcPtr, TempReadBuffer, destPtr, validDataCountInPacket); srcPtr += maxPacketSize; destPtr += validDataCount; rawDataCount += validDataCountInPacket; } return(rawDataCount); } }