mik3y / usb-serial-for-android

Android USB host serial driver library for CDC, FTDI, Arduino and other devices.
MIT License
4.94k stars 1.6k forks source link

Communication ISSUE #574

Open nadeem-agva opened 7 months ago

nadeem-agva commented 7 months ago

I am using two USBs in my device and two different SerialInputOutputManager Classes one of the USBs stops working randomly and no data is received on that and when I restart the application it starts working. USB 1 is always working and USB2 is not working randomly, it stops reading data at any point in time.

nadeem-agva commented 7 months ago

//here is the class for the another USB..

`package com.mmm.chk.callback;

import android.os.Process; import android.util.Log;

import com.hoho.android.usbserial.driver.UsbSerialPort;

import java.io.IOException; import java.nio.ByteBuffer;

public class SerialInputOutputHIDManager implements Runnable {

public enum State {
    STOPPED,
    RUNNING,
    STOPPING
}

public static boolean DEBUG = false;

private static final String TAG = "HID_CONNECT";
private static final int BUFSIZ = 4096;

/**
 * default read timeout is infinite, to avoid data loss with bulkTransfer API
 */

private int mReadTimeout = 0;
private int mWriteTimeout = 0;

private final Object mReadBufferLock = new Object();
private final Object mWriteBufferLock = new Object();

private ByteBuffer mReadBuffer; // default size = getReadEndpoint().getMaxPacketSize()
private ByteBuffer mWriteBuffer = ByteBuffer.allocate(BUFSIZ);

private int mThreadPriority = Process.THREAD_PRIORITY_URGENT_AUDIO;
private SerialInputOutputHIDManager.State mState = SerialInputOutputHIDManager.State.STOPPED; // Synchronized by 'this'
private SerialInputOutputHIDManager.Listener mListener; // Synchronized by 'this'
private final UsbSerialPort mSerialPort;

public interface Listener {
    /**
     * Called when new incoming data is available.
     */

    void onNewHIDData(byte[] data);

    /**
     * Called when {@link SerialInputOutputHIDManager#run()} aborts due to an error.
     */
    void onRunErrorHID(Exception e);
}

public SerialInputOutputHIDManager(UsbSerialPort serialPort) {
    mSerialPort = serialPort;
    mReadBuffer = ByteBuffer.allocate(serialPort.getReadEndpoint().getMaxPacketSize());
}

public SerialInputOutputHIDManager(UsbSerialPort serialPort, SerialInputOutputHIDManager.Listener listener) {
    mSerialPort = serialPort;
    mListener = listener;
    mReadBuffer = ByteBuffer.allocate(serialPort.getReadEndpoint().getMaxPacketSize());
}

public synchronized void setListener(SerialInputOutputHIDManager.Listener listener) {
    mListener = listener;
}

public synchronized SerialInputOutputHIDManager.Listener getListener() {
    return mListener;
}

/**
 * setThreadPriority. By default a higher priority than UI thread is used to prevent data loss
 *
 * @param threadPriority  see {@link Process#setThreadPriority(int)}
 * */

public void setThreadPriority(int threadPriority) {
    if (mState != SerialInputOutputHIDManager.State.STOPPED)
        throw new IllegalStateException("threadPriority only configurable before SerialInputOutputHIDManager is started");
    mThreadPriority = threadPriority;
}

/**
 * read/write timeout
 */

public void setReadTimeout(int timeout) {
    // when set if already running, read already blocks and the new value will not become effective now
    if(mReadTimeout == 0 && timeout != 0 && mState != SerialInputOutputHIDManager.State.STOPPED)
        throw new IllegalStateException("readTimeout only configurable before SerialInputOutputHIDManager is started");
    mReadTimeout = timeout;
}

public int getReadTimeout() {
    return mReadTimeout;
}

public void setWriteTimeout(int timeout) {
    mWriteTimeout = timeout;
}

public int getWriteTimeout() {
    return mWriteTimeout;
}

/**
 * read/write buffer size
 */
public void setReadBufferSize(int bufferSize) {
    if (getReadBufferSize() == bufferSize)
        return;
    synchronized (mReadBufferLock) {
        mReadBuffer = ByteBuffer.allocate(bufferSize);
    }
}

public int getReadBufferSize() {
    return mReadBuffer.capacity();
}

public void setWriteBufferSize(int bufferSize) {
    if(getWriteBufferSize() == bufferSize)
        return;
    synchronized (mWriteBufferLock) {
        ByteBuffer newWriteBuffer = ByteBuffer.allocate(bufferSize);
        if(mWriteBuffer.position() > 0)
            newWriteBuffer.put(mWriteBuffer.array(), 0, mWriteBuffer.position());
        mWriteBuffer = newWriteBuffer;
    }
}

public int getWriteBufferSize() {
    return mWriteBuffer.capacity();
}

/**
 * when using writeAsync, it is recommended to use readTimeout != 0,
 * else the write will be delayed until read data is available
 */
public void writeAsync(byte[] data) {
    synchronized (mWriteBufferLock) {
        mWriteBuffer.put(data);
    }
}

/**
 * start SerialInputOutputHIDManager in separate thread
 */
public void start() {
    if(mState != SerialInputOutputHIDManager.State.STOPPED)
        throw new IllegalStateException("already started");
    new Thread(this, this.getClass().getSimpleName()).start();
}

/**
 * stop SerialInputOutputHIDManager thread
 * when using readTimeout == 0 (default), additionally use usbSerialPort.close() to
 * interrupt blocking read
 */

public synchronized void stop() {
    if (getState() == SerialInputOutputHIDManager.State.RUNNING) {
        Log.i(TAG, "Stop requested");
        mState = SerialInputOutputHIDManager.State.STOPPING;
    }
}

public synchronized SerialInputOutputHIDManager.State getState() {
    return mState;
}

/**
 * Continuously services the read and write buffers until {@linkstop()} is
 * called, or until a driver exception is raised.
 */
@Override
public void run() {
    synchronized (this) {
        if (getState() != SerialInputOutputHIDManager.State.STOPPED) {
            throw new IllegalStateException("Already running");
        }
        mState = SerialInputOutputHIDManager.State.RUNNING;
    }
    Log.i(TAG, "Running ...");
    try {
        if(mThreadPriority != Process.THREAD_PRIORITY_DEFAULT)
            Process.setThreadPriority(mThreadPriority);
        while (true) {
            if (getState() != SerialInputOutputHIDManager.State.RUNNING) {
                Log.i(TAG, "Stopping mState=" + getState());
                break;
            }
            step();
        }
    } catch (Exception e) {
        Log.w(TAG, "Run ending due to exception: " + e.getMessage(), e);
        final SerialInputOutputHIDManager.Listener listener = getListener();
        if (listener != null) {
            listener.onRunErrorHID(e);
        }
    } finally {
        synchronized (this) {
            mState = SerialInputOutputHIDManager.State.STOPPED;
            Log.i(TAG, "Stopped");
        }
    }
}

private void step() throws IOException {
    // Handle incoming data.
    byte[] buffer;
    synchronized (mReadBufferLock) {
        buffer = mReadBuffer.array();
    }
    int len = mSerialPort.read(buffer, mReadTimeout);
    if (len > 0) {
        if (DEBUG) {
            Log.d(TAG, "Read data len=" + len);
        }
        final SerialInputOutputHIDManager.Listener listener = getListener();
        if (listener != null) {
            final byte[] data = new byte[len];
            System.arraycopy(buffer, 0, data, 0, len);
            listener.onNewHIDData(data);
        }
    }

    // Handle outgoing data.
    buffer = null;
    synchronized (mWriteBufferLock) {
        len = mWriteBuffer.position();
        if (len > 0) {
            buffer = new byte[len];
            mWriteBuffer.rewind();
            mWriteBuffer.get(buffer, 0, len);
            mWriteBuffer.clear();
        }
    }
    if (buffer != null) {
        if (DEBUG) {
            Log.d(TAG, "Writing data len=" + len);
        }
        mSerialPort.write(buffer, mWriteTimeout);
    }
}

} `

kai-morich commented 7 months ago

maybe power supplied from android is to weak for the second device

nadeem-agva commented 7 months ago

but this is only working after rebooting the android device else it is not working even when the app is destroyed and again re created.

nadeem-agva commented 7 months ago

is there any way possible to restart the communication of that USB port.

kai-morich commented 7 months ago

please check https://github.com/mik3y/usb-serial-for-android/wiki/FAQ#user-content-Can_I_open_multiple_connections_in_one_application for multiple connections

nadeem-agva commented 4 months ago

yeah i do checked this but still one of the USB went non-responsive applied all the tactics you provided but still the same issue in one of the USB's