172 lines
6.3 KiB
Java
172 lines
6.3 KiB
Java
package hendrikschutter.com.externgnss;
|
|
|
|
import android.app.PendingIntent;
|
|
import android.content.BroadcastReceiver;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.hardware.usb.UsbDevice;
|
|
import android.hardware.usb.UsbDeviceConnection;
|
|
import android.hardware.usb.UsbManager;
|
|
import android.util.Log;
|
|
|
|
import com.hoho.android.usbserial.driver.UsbSerialDriver;
|
|
import com.hoho.android.usbserial.driver.UsbSerialPort;
|
|
import com.hoho.android.usbserial.driver.UsbSerialProber;
|
|
import com.hoho.android.usbserial.util.SerialInputOutputManager;
|
|
|
|
import java.io.IOException;
|
|
import java.util.concurrent.BlockingQueue;
|
|
|
|
public class SerialUSB implements SerialInputOutputManager.Listener{
|
|
private MainActivity mainActivity = null;
|
|
private enum UsbPermission { Unknown, Requested, Granted, Denied }
|
|
private static final String INTENT_ACTION_GRANT_USB = BuildConfig.APPLICATION_ID + ".GRANT_USB";
|
|
private int deviceId, portNum, baudRate;
|
|
private BroadcastReceiver broadcastReceiver = null;
|
|
private SerialInputOutputManager usbIoManager;
|
|
private UsbSerialPort usbSerialPort;
|
|
private UsbPermission usbPermission = UsbPermission.Unknown;
|
|
private BlockingQueue<Byte> dataBytesQueue = null;
|
|
private boolean connected = false;
|
|
private int deviceVendorId;
|
|
private int productID;
|
|
|
|
public SerialUSB(MainActivity mainActivity, BlockingQueue<Byte> dataBytesQueue){
|
|
this.mainActivity = mainActivity;
|
|
this.dataBytesQueue = dataBytesQueue;
|
|
}
|
|
|
|
public boolean isConnected(){
|
|
return connected;
|
|
}
|
|
|
|
public int getDeviceId(){
|
|
return this.deviceId;
|
|
}
|
|
|
|
public int getBaudRate(){
|
|
return this.baudRate;
|
|
}
|
|
|
|
public int getUsbDeviceVendorId(){
|
|
return this.deviceVendorId;
|
|
}
|
|
|
|
public boolean findSerialDevice(){
|
|
// Find all available drivers from attached devices.
|
|
UsbManager usbManager = (UsbManager) this.mainActivity.getSystemService(Context.USB_SERVICE);
|
|
UsbSerialProber usbDefaultProber = UsbSerialProber.getDefaultProber();
|
|
boolean deviceFound = false;
|
|
|
|
//check of at least one device is present
|
|
if (usbManager.getDeviceList().values().size() > 0){
|
|
//get fist device
|
|
UsbDevice device = (UsbDevice) usbManager.getDeviceList().values().toArray()[0];
|
|
UsbSerialDriver driver = usbDefaultProber.probeDevice(device);
|
|
if(driver == null) {
|
|
Log.e("SerialUSB", "driver is null");
|
|
}
|
|
if(driver != null) {
|
|
Log.i("SerialUSB", "ExternGNSS: device/driver found!");
|
|
this.deviceId = device.getDeviceId();
|
|
this.deviceVendorId = device.getVendorId();
|
|
deviceFound = true;
|
|
}
|
|
} else
|
|
{
|
|
Log.e("SerialUSB", "no serial device connected");
|
|
deviceFound = false;
|
|
}
|
|
return deviceFound;
|
|
}
|
|
|
|
public void connect(int baudRate, int portNum) {
|
|
this.baudRate = baudRate;
|
|
this.portNum = portNum;
|
|
Log.i("connect", "starting to connect ...");
|
|
UsbDevice device = null;
|
|
UsbManager usbManager = (UsbManager) this.mainActivity.getSystemService(Context.USB_SERVICE);
|
|
for(UsbDevice v : usbManager.getDeviceList().values())
|
|
if(v.getDeviceId() == deviceId)
|
|
device = v;
|
|
if(device == null) {
|
|
Log.i("connect", "connection failed: device not found");
|
|
return;
|
|
}
|
|
UsbSerialDriver driver = UsbSerialProber.getDefaultProber().probeDevice(device);
|
|
if(driver == null) {
|
|
Log.i("connect", "connection failed: no driver for device");
|
|
return;
|
|
}
|
|
if(driver.getPorts().size() < portNum) {
|
|
Log.i("connect", "connection failed: not enough ports at device");
|
|
return;
|
|
}
|
|
usbSerialPort = driver.getPorts().get(portNum);
|
|
UsbDeviceConnection usbConnection = null;
|
|
|
|
try {
|
|
usbConnection = usbManager.openDevice(driver.getDevice());
|
|
} catch (Exception e){
|
|
usbPermission = UsbPermission.Requested;
|
|
PendingIntent usbPermissionIntent = PendingIntent.getBroadcast(this.mainActivity, 0, new Intent(INTENT_ACTION_GRANT_USB), 0);
|
|
usbManager.requestPermission(driver.getDevice(), usbPermissionIntent);
|
|
}
|
|
|
|
usbConnection = usbManager.openDevice(driver.getDevice());
|
|
if(usbConnection == null && usbPermission == UsbPermission.Unknown && !usbManager.hasPermission(driver.getDevice())) {
|
|
usbPermission = UsbPermission.Requested;
|
|
PendingIntent usbPermissionIntent = PendingIntent.getBroadcast(this.mainActivity, 0, new Intent(INTENT_ACTION_GRANT_USB), 0);
|
|
usbManager.requestPermission(driver.getDevice(), usbPermissionIntent);
|
|
return;
|
|
}
|
|
|
|
if(usbConnection == null) {
|
|
if (!usbManager.hasPermission(driver.getDevice()))
|
|
Log.i("connect", "connection failed: permission denied");
|
|
else
|
|
Log.i("connect", "connection failed: open failed");
|
|
return;
|
|
}
|
|
try {
|
|
usbSerialPort.open(usbConnection);
|
|
usbSerialPort.setParameters(baudRate, 8, 1, UsbSerialPort.PARITY_NONE);
|
|
usbIoManager = new SerialInputOutputManager(usbSerialPort, this);
|
|
usbIoManager.start();
|
|
Log.i("connect", "connected");
|
|
connected = true;
|
|
} catch (Exception e) {
|
|
Log.i("connect", "connection failed: " + e.getMessage());
|
|
disconnect();
|
|
}
|
|
}
|
|
|
|
public void disconnect() {
|
|
connected = false;
|
|
if(usbIoManager != null) {
|
|
usbIoManager.setListener(null);
|
|
usbIoManager.stop();
|
|
}
|
|
usbIoManager = null;
|
|
try {
|
|
usbSerialPort.close();
|
|
} catch (IOException ignored) {}
|
|
usbSerialPort = null;
|
|
}
|
|
|
|
@Override
|
|
public void onNewData(byte[] data) {
|
|
//Log.i("connect", "received data: " + data.length);
|
|
//Log.i("connect", new String(data, StandardCharsets.US_ASCII) );
|
|
for (byte rawByte : data) {
|
|
this.dataBytesQueue.add(rawByte);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onRunError(Exception e) {
|
|
Log.e("SerialUSB", "runtime error: " + e.getMessage());
|
|
this.disconnect();
|
|
}
|
|
}
|