Android O connects the peripherals of the USB3.0 interface

the following process works fine on phones that are not in the Android O system version, and works well when Android O connects to USB2.0, only when Android O connects to USB3.0/3.1 The sending and receiving of the first instruction is normal, but the second instruction fails. Return-1. I have tried to modify the third parameter of the bulkTransfer method (that is, the data length) to the MaXPacketSize of EndPoint, and the third parameter of the bulkTransfer method to the size of the received data, which is 0x0c in my use, so that the second instruction can be sent and received normally. But the third instruction will still fail, which may have something to do with this, but at most two instructions have been sent successfully

< H2 > looking for USB devices < / H2 >
    val usbManager = context.getSystemService(Context.USB_SERVICE) as UsbManager
    //this method just filter the vendorId of device
    val dev = lookupCompatibleDevice(usbManager) ?: return

< H2 > apply for permission < / H2 >
    if (usbManager.hasPermission(dev)){
        //if has permission already
        connect(context, dev)
    }else {
        //request permission and connect device in receiver
        registerPermissionReceiver(context)
        val mPermissionIntent = PendingIntent.getBroadcast(context, 0, Intent(
                ACTION_USB_PERMISSION), 0)
        usbManager.requestPermission(dev, mPermissionIntent)
    }
< H2 > get EndPoint < / H2 >
fun connect(context: Context, device: UsbDevice){
    val usbManager = context.getSystemService(Context.USB_SERVICE) as UsbManager
    var intf : UsbInterface? = null
    (0 until (device.interfaceCount)).forEach {
        val i = device.getInterface(it)
        if (i.interfaceClass == UsbConstants.USB_CLASS_STILL_IMAGE){
            intf = i
        }
    }
    if (intf == null){
        //PTP interface not found
        connectListener.onConnectStateChange(ConnectState.NO_PTP_INTERFACE)
        return
    }

    if (device.interfaceCount > 1){
        connectListener.onConnectStateChange(ConnectState.MULTI_INTERFACE)
        return
    }

    val conn = usbManager.openDevice(device) ?: return
    if (conn.claimInterface(intf, true)){
        Log.i(TAG, "claim interface successful")
    }else {
        Log.i(TAG, "claim interface failure")
    }
    var bulkIn: UsbEndpoint? = null
    var bulkOut: UsbEndpoint? = null

    (0 until (intf!!.endpointCount)).forEach {
        val endpoint = intf!!.getEndpoint(it)
        Log.d(TAG, "connect: endpoint type: " + endpoint.type + "direction: " + endpoint.direction)
        if (endpoint.type == UsbConstants.USB_ENDPOINT_XFER_BULK) {
            if (endpoint.direction == UsbConstants.USB_DIR_IN) {
                bulkIn = endpoint
            } else if (endpoint.direction == UsbConstants.USB_DIR_OUT) {
                bulkOut = endpoint
            }
        }
    }
    if (bulkIn == null || bulkOut == null) {
        //
        connectListener.onConnectStateChange(ConnectState.BULK_NOT_ENOUGH)
        return
    }
    if (AppConfig.LOG) {
        Log.i(TAG, "Found compatible USB interface")
        Log.i(TAG, "Interface class " + intf?.interfaceClass)
        Log.i(TAG, "Interface subclass " + intf?.interfaceSubclass)
        Log.i(TAG, "Interface protocol " + intf?.interfaceProtocol)
        Log.i(TAG, "Bulk out max size " + bulkOut?.maxPacketSize)
        Log.i(TAG, "Bulk in max size " + bulkIn?.maxPacketSize)
    }
    val connection = UsbConnection(context.applicationContext, device.vendorId, conn, bulkOut!!, bulkIn!!, object : Connection.ConnectStateListener {
        override fun onConnectStateChange(state: ConnectState) {
            connectListener.onConnectStateChange(state)
            if (state.state < ConnectState.WIFI_ACKNOWLEDGED.state){
              
                CameraHolder.disconnectCamera(context)
            }
        }
    })

    when(device.vendorId){
        CanonVendorId -> { camera = CanonCamera(context, connection, cameraListener) }
        NikonVendorId -> { camera = NikonCamera(context, connection, cameraListener) }
        SonyVendorId -> { camera = SonyCamera(context, connection, cameraListener) }
        else -> { camera = Camera(context, connection, cameraListener) }
    }
    connectListener.onConnectStateChange(ConnectState.USB_CONNECTED)
}

the UsbConnection class just pack the EndPoints

< H2 > send instructions < / H2 >
fun send(): Int {
    if (AppConfig.LOG_PACKETS){
        PacketUtil.logHexdump(TAG, byteBuffer.array(), byteBuffer.position(), byteBuffer.limit())
    }
    val res = connection.bulkTransfer(bulkOut, byteBuffer.array(), byteBuffer.limit(), timeout)
    return res
}

the bytebuffer contains the data that needs to be send

< H2 > receive instructions < / H2 >
res = connection.bulkTransfer(bulkIn, `in`.array(), maxPacketSize, AppConfig.USB_TRANSFER_TIMEOUT)

Any help will be appreciated..

Jun.14,2022
Menu