2022-04-25 14:42:06 +02:00
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 ;
2022-04-25 17:11:58 +02:00
import java.util.concurrent.BlockingQueue ;
2022-04-25 14:42:06 +02:00
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 ;
2022-04-25 17:11:58 +02:00
private BlockingQueue < Byte > dataBytesQueue = null ;
2022-04-25 14:42:06 +02:00
private boolean connected = false ;
2022-04-25 22:55:07 +02:00
private int deviceVendorId ;
private int productID ;
2022-04-25 14:42:06 +02:00
2022-04-25 17:11:58 +02:00
public SerialUSB ( MainActivity mainActivity , BlockingQueue < Byte > dataBytesQueue ) {
2022-04-25 14:42:06 +02:00
this . mainActivity = mainActivity ;
2022-04-25 17:11:58 +02:00
this . dataBytesQueue = dataBytesQueue ;
}
2022-04-25 14:42:06 +02:00
2022-04-25 17:11:58 +02:00
public boolean isConnected ( ) {
return connected ;
}
2022-04-25 22:55:07 +02:00
public int getDeviceId ( ) {
return this . deviceId ;
}
public int getBaudRate ( ) {
return this . baudRate ;
}
public int getUsbDeviceVendorId ( ) {
return this . deviceVendorId ;
}
2022-04-25 17:11:58 +02:00
public boolean findSerialDevice ( ) {
2022-04-25 14:42:06 +02:00
// Find all available drivers from attached devices.
UsbManager usbManager = ( UsbManager ) this . mainActivity . getSystemService ( Context . USB_SERVICE ) ;
UsbSerialProber usbDefaultProber = UsbSerialProber . getDefaultProber ( ) ;
2022-04-25 17:11:58 +02:00
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! " ) ;
2022-04-25 14:42:06 +02:00
this . deviceId = device . getDeviceId ( ) ;
2022-04-25 22:55:07 +02:00
this . deviceVendorId = device . getVendorId ( ) ;
2022-04-25 17:11:58 +02:00
deviceFound = true ;
2022-04-25 14:42:06 +02:00
}
2022-04-25 17:11:58 +02:00
} else
{
Log . e ( " SerialUSB " , " no serial device connected " ) ;
deviceFound = false ;
}
return deviceFound ;
2022-04-25 14:42:06 +02:00
}
2022-04-25 17:11:58 +02:00
public void connect ( int baudRate , int portNum ) {
this . baudRate = baudRate ;
this . portNum = portNum ;
2022-04-25 14:42:06 +02:00
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 ) ;
2022-04-25 22:55:07 +02:00
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 ( ) ) ;
2022-04-25 14:42:06 +02:00
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 ;
}
2022-04-25 22:55:07 +02:00
2022-04-25 14:42:06 +02:00
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 ( ) ;
}
}
2022-04-25 17:11:58 +02:00
public void disconnect ( ) {
2022-04-25 14:42:06 +02:00
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 ) {
2022-04-25 17:11:58 +02:00
//Log.i("connect", "received data: " + data.length);
//Log.i("connect", new String(data, StandardCharsets.US_ASCII) );
for ( byte rawByte : data ) {
this . dataBytesQueue . add ( rawByte ) ;
}
2022-04-25 14:42:06 +02:00
}
@Override
public void onRunError ( Exception e ) {
Log . e ( " SerialUSB " , " runtime error: " + e . getMessage ( ) ) ;
this . disconnect ( ) ;
}
}