Android Host Host Communication - программирование
Подтвердить что ты не робот

Android Host Host Communication

Я работаю над проектом, который использует возможности USB Host в Android 3.2. Я страдаю от плачевного недостатка знаний и таланта в отношении USB/последовательной связи в целом. Я также не могу найти хороший пример кода для того, что мне нужно сделать.

Мне нужно прочитать с USB-устройства связи.
Пример: Когда я подключаюсь через Putty (на моем ПК), я ввожу:

>GO

И устройство начинает извергать данные для меня. Pitch/Roll/Temp/Контрольная сумма.

Пример:

$R1.217P-0.986T26.3*60
$R1.217P-0.986T26.3*60
$R1.217P-0.987T26.3*61
$R1.217P-0.986T26.3*60
$R1.217P-0.985T26.3*63

Я могу отправить начальную команду "GO" с устройства Android, и в это время я получаю эхо "GO".

Тогда ничего больше при последующих чтениях.

Как я могу: 1) Отправьте команду "идти". 2) Прочитайте в потоке данных, которые будут получены.

Устройство USB, с которым я работаю, имеет следующие интерфейсы (конечные точки).

Класс устройства: устройство связи (0x2)

Интерфейсы:

ИнтерфейС# 0 Класс: устройство связи (0x2) Конечная точка # 0 Направление: входящий (0x80) Тип: Intrrupt (0x3) Интервал опроса: 255 Максимальный размер пакета: 32 Атрибуты: 000000011

ИнтерфейС# 1 Класс: Класс устройства связи (CDC) (0xa) Конечная точка # 0 Адрес: 129 Номер 1 Направление: входящий (0x80) Тип: Навальный (0x2) Интервал опроса (0) Максимальный размер пакета: 32 Атрибуты: 000000010

Конечная точка №1 Адрес 2 Номер 2 Направление: Исходящий (0x0) Тип: Навальный (0x2) Интервал опроса (0) Максимальный размер пакета: 32 Атрибуты: 000000010

Я могу справиться с разрешением, подключиться к устройству, найти правильный интерфейс и назначить конечные точки. Мне просто трудно понять, какой метод использовать для отправки исходной команды, считывая последующие данные. Я пробовал разные комбинации bulkTransfer и controlTransfer без везения.

Спасибо.

Я использую интерфейС# 1, как показано ниже:

public AcmDevice(UsbDeviceConnection usbDeviceConnection, UsbInterface usbInterface) {
    Preconditions.checkState(usbDeviceConnection.claimInterface(usbInterface, true));
    this.usbDeviceConnection = usbDeviceConnection;

    UsbEndpoint epOut = null;
    UsbEndpoint epIn = null;
    // look for our bulk endpoints
    for (int i = 0; i < usbInterface.getEndpointCount(); i++) {
      UsbEndpoint ep = usbInterface.getEndpoint(i);
     Log.d(TAG, "EP " + i + ": " + ep.getType());
      if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
        if (ep.getDirection() == UsbConstants.USB_DIR_OUT) {
          epOut = ep;

        } else if (ep.getDirection() == UsbConstants.USB_DIR_IN) {
          epIn = ep;
        }

      }
    }
    if (epOut == null || epIn == null) {
      throw new IllegalArgumentException("Not all endpoints found.");
    }

    AcmReader acmReader = new AcmReader(usbDeviceConnection, epIn);
    AcmWriter acmWriter = new AcmWriter(usbDeviceConnection, epOut);
    reader = new BufferedReader(acmReader);
    writer = new BufferedWriter(acmWriter);
  }
4b9b3361

Ответ 1

Ненавижу отвечать на свой вопрос, но... Я понял. Я просто смешивал свои чтения и записи. Кроме того, устройству не понравился "\n", который я использовал в конце моих команд. Похоже, что он лучше сочетается с '\ r'.

В итоге я использовал android bulkTransfer для чтения и записи. Мои записи выглядели так.

    try {
            device.getWriter().write(command + "\r");
            device.getWriter().flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

И мой переопределенный метод записи для моего BufferedWriter:

@Override

  public void write(char[] buf, int offset, int count) throws IOException {
    byte[] buffer = new String(buf, offset, count).getBytes(Charset.forName("US-ASCII"));
    int byteCount = connection.bulkTransfer(endpoint, buffer, buffer.length, TIMEOUT);
  }

Чтения были похожи:

    char[] buffer = new char[BUF_SIZE];
    try {
        BufferedReader reader = device.getReader();

        int readBytes = reader.read(buffer);
        Log.d(TAG, "BYTES READ: " + readBytes);

    } catch (IOException e) {
        throw new RuntimeException(e);
    }
    String strBuf = new String(buffer).trim();
    if (DEBUG) {
        Log.d(TAG, "Read: " + strBuf);
    }

и

@Override
  public int read(char[] buf, int offset, int count) throws IOException {
    byte[] buffer = new byte[count];
    int byteCount = connection.bulkTransfer(endpoint, buffer, buffer.length, TIMEOUT);

    if (byteCount < 0) {
      throw new IOException();
    }
    char[] charBuffer = new String(buffer, Charset.forName("US-ASCII")).toCharArray();
    System.arraycopy(charBuffer, 0, buf, offset, byteCount);
    return byteCount;
  }

Все это только что началось в потоке:

new Thread() {
    @Override
public void run() {

    String command = "go";
    write(command);

    while (true) {
        String coords = read(); 
        }
}
}.start();

Очевидно, что это всего лишь комм-материал, и мне нужно будет что-то сделать с ним (поставьте его в службу, которая может отчитываться перед действительностью UI верхнего уровня с помощью обработчика). Но эта часть его понятна.

Огромное спасибо людям, которые работают над rosjava (http://code.google.com/p/rosjava/)... Они собрали много замечательных проекты и их код были очень полезны.

Добавление класса моего устройства, чтобы помочь прояснить ситуацию.

import com.google.common.base.Preconditions;

import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.util.Log;

import java.io.BufferedReader;
import java.io.BufferedWriter;

/* This class represents a USB device that supports the adb protocol. */
public class BKDevice {

// private static final int TIMEOUT = 3000;

private final UsbDeviceConnection usbDeviceConnection;
private final BufferedReader reader;
private final BufferedWriter writer;
public static final String TAG = "AcmDevice";

public BKDevice(UsbDeviceConnection usbDeviceConnection,
        UsbInterface usbInterface) {
    Preconditions.checkState(usbDeviceConnection.claimInterface(
            usbInterface, true));
    this.usbDeviceConnection = usbDeviceConnection;

    UsbEndpoint epOut = null;
    UsbEndpoint epIn = null;
    // look for our bulk endpoints
    for (int i = 0; i < usbInterface.getEndpointCount(); i++) {
        UsbEndpoint ep = usbInterface.getEndpoint(i);
        Log.d(TAG, "EP " + i + ": " + ep.getType());

        if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
            if (ep.getDirection() == UsbConstants.USB_DIR_OUT) {
                epOut = ep;

            } else if (ep.getDirection() == UsbConstants.USB_DIR_IN) {
                epIn = ep;

            }
        }
    }
    if (epOut == null || epIn == null) {
        throw new IllegalArgumentException("Not all endpoints found.");
    }

    BKReader acmReader = new BKReader(usbDeviceConnection, epIn);
    BKWriter acmWriter = new BKWriter(usbDeviceConnection, epOut);

    reader = new BufferedReader(acmReader);
    writer = new BufferedWriter(acmWriter);
}

public BufferedReader getReader() {
    return reader;
}

public BufferedWriter getWriter() {
    return writer;
}
}

Добавление кода BKReader:

import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.util.Log;

import java.io.IOException;
import java.io.Reader;
import java.nio.charset.Charset;

public class BKReader extends Reader {

    private static final int TIMEOUT = 1000;

    private final UsbDeviceConnection connection;
    private final UsbEndpoint endpoint;

    public BKReader(UsbDeviceConnection connection, UsbEndpoint endpoint) {
        this.connection = connection;
        this.endpoint = endpoint;
    }

    @Override
    public int read(char[] buf, int offset, int count) throws IOException {
        byte[] buffer = new byte[count];
        int byteCount = connection.bulkTransfer(endpoint, buffer, buffer.length, TIMEOUT);

        if (byteCount < 0) {
          throw new IOException();
        }
        char[] charBuffer = new String(buffer, Charset.forName("US-ASCII")).toCharArray();
        System.arraycopy(charBuffer, 0, buf, offset, byteCount);
        return byteCount;
    }

    @Override
    public void close() throws IOException {
    }

}