1

Anybody have any ideas as to why requestWait() or queue() might stop receiving information (payloads) from an external device (aggboard) after the device has been disconnected and then reconnected? If I use the bulktransfer() method (which is commented out) with otherwise the same code, the communication resumes, but bulktransfer() is dropping payloads, which is why we have tried refactoring to requestWait() and queue(). Any advice??

public class PayloadTask extends AsyncTask<Payload, Void, Payload> {

    private UsbInterface usbInterface;
    private UsbDeviceConnection usbConnection;
    private UsbEndpoint usbToAggBoard;
    private UsbEndpoint usbFromAggBoard;
    private AggBoard owner;
    private UsbRequest request = new UsbRequest();

    PayloadTask(AggBoard owner, UsbInterface intf, UsbDeviceConnection connection) {
        usbConnection = connection;
        usbInterface = intf;
        /*synchronized (intf)*/ {
            usbToAggBoard = intf.getEndpoint(1);
            usbFromAggBoard = intf.getEndpoint(0);
        }
        this.owner = owner;
    }

    @Override
    protected Payload doInBackground(Payload... payloads) {

        if (payloads != null) {
            if (payloads.length > 1) {
                Log.d("PayloadTask", "There was more than one payload. Going to have to iterate.");
                int i = 0;
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                for (Payload payload : payloads) {
                    byte[] buffer = payload.getBytes();

                    while (AndroidUnityPlayerActivity.aggBoard == null)
                    {
                        try {
                            Log.d("PayloadTask", "Waiting for AndroidUnityPlayerActivity.aggboard to not be null");
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                    ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);
                    byteBuffer.rewind();
                    try {
                        request.initialize(usbConnection, usbToAggBoard);
                        if (!request.queue(byteBuffer, buffer.length)) {
                            throw new IOException("Error queueing USB request.");
                        }
                        usbConnection.requestWait();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        if(usbConnection != null) {
                            int sent = request.hashCode();
                            request.close();
                        }
                        else{
                            Log.d("PayloadTask", "Request not received by usbConnection");
                        }
                    }
//  int sent = usbConnection.bulkTransfer(usbToAggBoard, buffer, buffer.length, 1500);
                    busyWaitMicros(20);

                    if (++i % 1024 == 0) {
                        Log.e(AndroidUnityPlayerActivity.TAG, new Integer(i / 1024 * 8).toString() + "KB sent");
                    }
                    AggBoard.percentInstalled = i * 100 / payloads.length;
                   // Log.w(AndroidUnityPlayerActivity.TAG, new Float((float)i /payloads.length).toString());

                }
                Log.d("PayloadTask", "Finished iterating over the payloads.");
                // rk3188 doesn't seem to see the success/fail message.. so let's fake one :/
                if (AggBoard.encryptedBytes != null) {
                    Log.d("PayloadTask", "Aggboard.encryptedBytes was null. Creating some kind of success response payload??");
                    byte[] response = new byte [] { (byte)Payload.BOOTLOAD_STATUS,
                                                    (byte)BootloadStatusPayload.AGGREGATOR,
                                                    (byte)BootloadStatusPayload.SUCCESS,
                                                    0, 0, 0, 0,
                                                    (byte)Payload.AGGREGATOR_TAIL };
                    if (AggBoard.percentInstalled < 100) {
                        response[2] = (byte)BootloadStatusPayload.ERROR ;
                    }
                    Log.d("PayloadTask", "Creating bootload status SUCCESS task");
                    return Payload.CreatePayload(response);
                }
            } else if (payloads.length == 1 && payloads[0] != null) {
                Log.d("PayloadTask", "There was only one payload. Running it");
                byte[] buffer = payloads[0].getBytes();
                if (AndroidUnityPlayerActivity.aggBoard != null) {
                    Log.d("PayloadTask", "Only one payload, beginning bulk transfer");
                    
                   /* if (Payload.START_SENDING_DATA == buffer[0]) {
                        AndroidUnityPlayerActivity.hasAggBoard = true;
                    }*/
                   
                    ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);
                    byteBuffer.rewind();
                    try {
                        request.initialize(usbConnection, usbToAggBoard);
                        if (!request.queue(byteBuffer, buffer.length)) {
                            throw new IOException("Error queueing USB request.");
                        }
                        usbConnection.requestWait();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        if(usbConnection != null) {
                            request.close();
                        }
                        else{
                            Log.d("PayloadTask", "Request not received by usbConnection");
                        }
                    }
//  usbConnection.bulkTransfer(usbToAggBoard, buffer, buffer.length, 1000);
                }
                else{
                    Log.d("PayloadTask", "AndroidUnityPlayerActivity's aggboard was null. Can't perform bulk transfer of payload.");
                }
            }
        } else {
            try {
                Thread.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        byte[] response = new byte[64];
        int result = 0;
        int tries = 0;

        while (result < 1){
            if (tries > 5) {
                Log.d("PayloadTask", "PayloadTask Timed Out.");
                return null;
            } else if (isCancelled()) {
                Log.w("PayloadTask", "PayloadTask Cancelled!");
                return null;
            }

            /*synchronized (usbConnection)*/
            //if (usbConnection != null) {
                ByteBuffer byteBuffer = ByteBuffer.wrap(response);
                byteBuffer.rewind();
                try {
                    request.initialize(usbConnection, usbFromAggBoard);
                    if (!request.queue(byteBuffer, response.length)) {
                        throw new IOException("Error queueing USB request.");
                    }
                    usbConnection.requestWait();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if(usbConnection != null) {
                        result = request.hashCode();
                        request.close();
                        //result += 1;
                    }
                    else{
                        Log.d("PayloadTask", "Request not received by usbConnection");
                    }
                }
//  result = usbConnection.bulkTransfer(usbFromAggBoard, response, response.length, 1000);
            tries += 1;
        }
        Log.i("PayloadTask", new Integer(response.length).toString() + " bytes received: ");
        Log.d("PayloadTask", "doInBackground returning some payload from the aggboard.");
        return Payload.CreatePayload(response);
    }

    @Override
    protected void onPostExecute(Payload payload) {
        owner.handlePayload(payload);
    }

    @Override
    protected void onCancelled() {
        Log.d("PayloadTask", "thread canceled");
        super.onCancelled();
    }

    @Override
    protected void onPreExecute() {
        Log.d("PayloadTask", "started thread");
        if (!usbConnection.claimInterface(usbInterface, true)) {
                Log.w("PayloadTask", "Failed to claim interface!");
            }
        else{
            Log.w("PayloadTask", "Claimed interface!");
        }
    }

    public static void busyWaitMicros(long micros){
        long waitUntil = System.nanoTime() + (micros * 1000);
        while(waitUntil > System.nanoTime()){

        }
    }
}

0 Answers0