Android Open Accessory USB-связь не работает после отправки больших пакетов данных

У меня есть телефон Android, связывающийся с машиной Linux с помощью AOA. Linux-машина настроена на инициирование соединения, затем ожидание входящих данных и отправку их обратно на телефон без изменений. Это прекрасно работает для небольших пакетов данных (менее 1024 байтов) с телефона. Однако, если я отправляю ровно 1024 байта, он, кажется, работает со стороны Android, но компьютер никогда не видит пакет, только любые последующие, которые меньше. Если телефон пытается отправить пакеты размером более 1024, они все-таки принимаются компьютером, но телефон Android больше не сможет принимать пакеты от компьютера. Еще более запутывая проблему, это работало в прошлом, но откат к более ранним версиям кода передачи / приема на телефоне, похоже, не имел никакого эффекта. Код на компьютере не был изменен.

Приложение для Android проверяет наличие USB-аксессуара при запуске и, если оно найдено, запускает поток слушателя и отправителя. Поток отправителя ожидает в очереди блокировки исходящих пакетов и отправляет их, как только они будут получены. Поток слушателя постоянно пытается читать из входного потока, который блокируется, пока данные не станут доступны. Это код, который я использую для настройки и запуска потоков:

private boolean openUSB(){
    mUSBManager = (UsbManager) getSystemService(Context.USB_SERVICE);
    mAccessory = mUSBManager.getAccessoryList();
    if (mAccessory != null && mAccessory.length > 0) {
        mParcelFileDescriptor = mUSBManager.openAccessory(mAccessory[0]);
        mFileDescriptor = mParcelFileDescriptor.getFileDescriptor();

        mListener = new Thread() {
            public void run() {
                listenerThread();
            }

        };
        mListener.start();

        mSender = new Thread() {
            public void run() {
                senderThread();
            }

        };
        mSender.start();
        displayText("Connected to USB accessory");

        return true;
    } else {
        displayText("No USB accessory detected"); 
        return false;
    }
}

private void listenerThread(){

    byte packet[] = new byte[SDR_PREFIX_SIZE+SDR_HEADER_SIZE+SDR_MAX_PAYLOAD+SDR_CRC_SIZE];
    FileInputStream input = new FileInputStream(mFileDescriptor);
    try {
        ByteArrayOutputStream incoming = new ByteArrayOutputStream();
        displayText("Listener Started");
        while ( mFileDescriptor != null && input != null ) {
            int read = input.read(packet,0,packet.length);

            /* data in packet gets processed */
        }
    } catch ( Exception e) {
        displayText("Listener Exception - "+e.getMessage(),true);
    }
    displayText("Listener Exited");
}

private void senderThread(){

    displayText("sender started");
    FileOutputStream output=new FileOutputStream(mFileDescriptor);

    try {
        byte data[] = mTransmitQueue.take();
        while (data != null) {
            displayText("Sending packet " + packet + ", "+data.length + " bytes");
            output.write(data);

            data = mTransmitQueue.take();
        }

    } catch ( Exception e) {
        displayText("Sender Exception - "+e.getMessage(),true);
    }
}

В прошлом у меня были проблемы с работой слушателя и отправителя, пока я не обнаружил, что некоторые из промежуточных объектов, которые использовались для создания файловых потоков, собирались мусором, но все еще были необходимы. Теперь я сохраняю все эти промежуточные объекты для переменных-членов (mUSBManager, mAccessory, mParcelFileDescriptor, mFileDescriptor), чтобы обеспечить их постоянство. Я подозреваю, что эта проблема чем-то похожа, но я не смог добиться успеха. Я бьюсь головой об этой проблеме без какого-либо успеха, и очень надеюсь, что другие будут иметь некоторое представление о том, что вызывает это.

1 ответ

Я нашел обходной путь: расширение буфера, используемого для приема данных, похоже, решает проблему, хотя существующий буфер был достаточно большим для всех пакетов. Увеличение буфера с 1524 до 2524 исправило проблему с не полученными входящими пакетами. Это грязное решение, но оно работает.

Другие вопросы по тегам