Это мой первый опыт работы с USB-интерфейсом и приложением для Android.
Я использую https://github.com/felHR85/UsbSerial, чтобы создать приложение, которое позволит планшетам / телефонам использовать USB OTG в качествехост и общение с аксессуаром.Я дошел до того, что я использую SerialInputStreams и SerialOutputStreams для отправки и получения с устройством.
Это максимальный размер пакета, который USB может отправлять, - 64 байта с кабелем, который я использую.В моем приложении аксессуар отправляет данные размером более 64 байт.Если у аксессуара нет кода, который отправляет данные в 64-байтовых пакетах, а вместо этого все сразу.Будут ли потеряны данные, поступающие после 64 байтов?
Я получаю первые 64 байта сообщения от дополнительного устройства к хосту, а затем время ожидания хоста, поскольку оно не получает полное сообщение и повторно отправляет дополнительное устройство.Первые 64 байта сообщения всегда отображаются, поэтому я знаю, что другие части сообщения не ожидают опроса.
РЕДАКТИРОВАТЬ
Устройство, к которому я подключаюсь, представляет собой регистратор данных, который считается устройством CDC.Я знаю, что для используемого соединения максимальный размер пакета составляет 64.
USBConnectActivity происходит всякий раз, когда подключено USB-устройство, и проходит фильтр, который я настроил, а интерфейс и конечные точки верны.
public class USBConnectActivity extends Activity
{
public UsbDevice device = null;
public UsbManager manager = null;
public UsbDeviceConnection usbDeviceConnection = null;
public UsbSerialDevice serialPort = null;
public String deviceID = "";
public boolean isUSBConnected = false;
private PendingIntent mPermissionIntent;
private final String ACTION_USB_PERMISSION =
"com.android.example.USB_PERMISSION";
private final BroadcastReceiver usbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
stopUsbConnection();
unregisterReceiver(usbReceiver);
}
if(ACTION_USB_PERMISSION.equals(action))
{
setupCom();
}
}
};
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
manager = (UsbManager) getSystemService(Context.USB_SERVICE);
USBConnection.getInstance().setManager(manager);
mPermissionIntent = PendingIntent.getBroadcast(
this,0,new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter mfilter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(usbReceiver,mfilter);
IntentFilter filter = new IntentFilter(UsbManager.ACTION_USB_DEVICE_DETACHED);
registerReceiver(usbReceiver, filter);
findDevice(mPermissionIntent);
finish();
}
private void findDevice(PendingIntent i)
{
UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
boolean found = false;
UsbDevice xDevice = null;
while (deviceIterator.hasNext()) {
UsbDevice tDevice = deviceIterator.next();
// Loop through the interfaces of the attached USB device
for (int count = 0; count < tDevice.getInterfaceCount(); count++) {
if (found) break;
// Use temp variables to check and then match with the private variables
UsbInterface inter = tDevice.getInterface(count);
UsbEndpoint tOut = null;
UsbEndpoint tIn = null;
if (inter.getEndpointCount() >= 2) {
for (int end_count = 0; end_count < inter.getEndpointCount(); end_count++) {
UsbEndpoint end = inter.getEndpoint(end_count);
if (end.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
if (end.getDirection() == UsbConstants.USB_DIR_OUT) tOut = end;
else if (end.getDirection() == UsbConstants.USB_DIR_IN) tIn = end;
}
}
}
if (tOut != null && tIn != null) {
device = tDevice; manager.requestPermission(device, i); found = true;
isUSBConnected = true;
USBConnection.getInstance().setDevice(device);
USBConnection.getInstance().attach();
}
}
}
if(usbDeviceConnection == null) setupCom();
}
@Override
protected void onStop()
{
super.onStop();
unregisterReceiver(usbReceiver);
}
private void setupCom()
{
deviceID = device.getDeviceName();
if(usbDeviceConnection == null) usbDeviceConnection = manager.openDevice(device);
if(serialPort == null)
{
serialPort = UsbSerialDevice.createUsbSerialDevice(device, usbDeviceConnection);
if(serialPort != null && serialPort.open())
{
serialPort.setBaudRate(115200);
serialPort.setDataBits(UsbSerialInterface.DATA_BITS_8);
serialPort.setStopBits(UsbSerialInterface.STOP_BITS_1);
serialPort.setParity(UsbSerialInterface.PARITY_NONE);
serialPort.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
USBConnection.getInstance().setSerialPort(serialPort);
USBConnection.getInstance().setUsbDeviceConnection(usbDeviceConnection);
}
}
}
private void stopUsbConnection(){
manager = null;
device = null;
isUSBConnected = false;
USBConnection.getInstance().detach();
deviceID = "";
try
{
if(serialPort != null)
serialPort.close();
if(usbDeviceConnection != null)
usbDeviceConnection.close();
}
finally
{
serialPort = null;
usbDeviceConnection = null;
}
}
}
Этот класс содержит всю информацию USB
public class USBConnection
{
// USB information
public boolean isConnected;
public UsbDevice device;
public UsbManager manager;
public UsbSerialDevice serialPort;
public UsbDeviceConnection usbDeviceConnection;
public String deviceName;
public boolean waitForReading;
private static USBConnection instance;
public static USBConnection getInstance()
{
if(instance == null)
instance = new USBConnection();
return instance;
}
public void setDevice(UsbDevice device_)
{
device = device_;
deviceName = device.getDeviceName();
}
public void setManager(UsbManager manager_)
{
manager = manager_;
}
public void attach()
{
isConnected = true;
}
public void detach()
{
isConnected = false;
}
public void setSerialPort(UsbSerialDevice serialPort_)
{
serialPort = serialPort_;
}
public void setUsbDeviceConnection(UsbDeviceConnection usbDeviceConnection_)
{
usbDeviceConnection = usbDeviceConnection_;
}
public void writing() {
waitForReading = true;
}
public void reading(){
waitForReading = false;
}
public boolean waitingForRead()
{
return waitForReading;
}
}
Этот код я использую для настройки потоков ввода и вывода
else if(USBConnection.getInstance().isConnected) // check if usb is connected
{
manager = USBConnection.getInstance().manager;
device = USBConnection.getInstance().device;
// Attempt at setting up a USB input and output stream
if (manager != null) {
if(usbDeviceConnection == null) usbDeviceConnection = manager.openDevice(device);
if(serialPort == null)
{
serialPort = UsbSerialDevice.createUsbSerialDevice(device, usbDeviceConnection);
if(serialPort != null && serialPort.open())
{
serialPort.setBaudRate(115200);
serialPort.setDataBits(UsbSerialInterface.DATA_BITS_8);
serialPort.setStopBits(UsbSerialInterface.STOP_BITS_1);
serialPort.setParity(UsbSerialInterface.PARITY_NONE);
serialPort.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
input = new SerialInputStream(serialPort);
output = new SerialOutputStream(serialPort);
Log.d("Direct", "Connected to the USB socket");
}
}
}
} // else there is no usb connected
Этов felHR85 UsbSerialDevice, в его ReadThread, и то, что я закомментировал, это то, что я включил, думая, что он будет захватывать данные, если он будет больше, чем 64 байта
int numberBytes, bytes;
if(inEndpoint != null) {
bytes = numberBytes = connection.bulkTransfer(inEndpoint, serialBuffer.getBufferCompatible(),
SerialBuffer.DEFAULT_READ_BUFFER_SIZE, 100);
}/*while(numberBytes >= 64) {
numberBytes = connection.bulkTransfer(inEndpoint, serialBuffer.getBufferCompatible(), bytes,
124, 100);
bytes += numberBytes;
Log.i("Bytes", " : " + bytes);
}*/
else
bytes = numberBytes = 0;
Это в его WriteThread
while(working.get())
{
byte[] data = serialBuffer.getWriteBuffer();
if(data.length > 0)
connection.bulkTransfer(outEndpoint, data, data.length, USB_TIMEOUT);
}
РЕДАКТИРОВАТЬ
Это решило мою проблему, но я все еще не уверен, что ответ на мой оригинальный вопрос
if(serialPort == null)
{
usbDeviceConnection.claimInterface(USBConnection.getInstance().usbInterface, true);
usbDeviceConnection.controlTransfer(64,0,1,0,null,0,0); // clear tx
usbDeviceConnection.controlTransfer(64,0,2,0,null,0,0); // clear rx
serialPort = UsbSerialDevice.createUsbSerialDevice(device, usbDeviceConnection);