I'm trying to communicate with NV9 USB+ device by an android app ( who search the usb device), I get the device by D2xxManager but I don't know how to send instructions to it, how can I send instructions and get de result of it ?
My android version is Android 11 and sdk is 33.
This is my code:
MainActivity
public class MainActivity extends AppCompatActivity {
private static ITLDeviceCom deviceCom;
private static D2xxManager ftD2xx = null;
@SuppressLint("StaticFieldLeak")
private static FT_Device ftDev = null;
private static final int MY_PERMISSIONS_REQUEST_READ_STORAGE = 0;
private final long SSP_KEY = 0123456701234567L;
BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "Starting onReceive");
String action = intent.getAction();
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
// never come here(when attached, go to onNewIntent)
System.out.println("ACTION_USB_DEVICE_ATTACHED");
openDevice();
} else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
System.out.println("ACTION_USB_DEVICE_DETACHED");
closeDevice();
}
Log.i(TAG, "Ending onReceive");
}
};
@SuppressLint("UnspecifiedRegisterReceiverFlag")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i(TAG, "Starting onCreate");
UsbManager usbManager = (UsbManager) this.getSystemService(Context.USB_SERVICE);
// Obtener una lista de dispositivos USB conectados
HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
for (UsbDevice device : deviceList.values()) {
String deviceName = device.getDeviceName();
String serial = device.getSerialNumber();
int productId = device.getProductId();
int vendorId = device.getVendorId();
String manufacturerName = device.getManufacturerName();
Log.i(TAG,"Device name: " + deviceName + " | Product id: " + productId + " | Vendor id: " + vendorId + " | Serial number: " + serial + " | Manufacturer Name: " + manufacturerName);
}
try {
ftD2xx = D2xxManager.getInstance(this);
Log.i(TAG, "Setting VID and PID");
ftD2xx.setVIDPID(0x191c, 0x4104);
} catch (D2xxManager.D2xxException ex) {
Log.e("SSP FTmanager", ex.toString());
}
Log.i(TAG, "Inicilice registerReceiver");
IntentFilter filter = new IntentFilter();
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
filter.setPriority(500);
this.registerReceiver(mUsbReceiver, filter);
deviceCom = new ITLDeviceCom();
openDevice();
if (ftDev != null) {
Log.i(TAG, "ftDev != null => Calling to setup and start");
deviceCom.setup(ftDev, 0, false, false, SSP_KEY);
deviceCom.start();
Log.i(TAG, "Escrow mode => true");
deviceCom.SetEscrowMode(true);
Log.i(TAG, "Device mode => true");
deviceCom.SetDeviceEnable(true);
Log.i(TAG, "Escrow action => Accept");
deviceCom.SetEscrowAction(SSPSystem.BillAction.Accept);
}
Log.i(TAG, "Ending onCreate");
}
@Override
protected void onDestroy() {
Log.i(TAG, "Starting onDestroy");
this.unregisterReceiver(mUsbReceiver);
super.onDestroy();
}
/********** USB functions ******************************************/
private void openDevice() {
Log.i(TAG, "Starting openDevice");
if (ftDev != null && ftDev.isOpen()) {
Log.i(TAG, "if the device is connected and open, we restart the thread task");
SetConfig(9600, (byte) 8, (byte) 2, (byte) 0, (byte) 0);
ftDev.purge((byte) (D2xxManager.FT_PURGE_TX | D2xxManager.FT_PURGE_RX));
ftDev.restartInTask();
return;
}
int devCount = 0;
if (ftD2xx != null) {
// Get the connected USB FTDI devices
devCount = ftD2xx.createDeviceInfoList(this);
} else {
Log.w(TAG, "ftD2xx == null");
return;
}
D2xxManager.FtDeviceInfoListNode[] deviceList = new D2xxManager.FtDeviceInfoListNode[devCount];
ftD2xx.getDeviceInfoList(devCount, deviceList);
if (devCount <= 0) {
System.out.println("none detected devices");
Log.w(TAG, "devCount <= 0");
return;
}
if (ftDev == null) {
System.out.println("ftDev is null, getting position " + (devCount - 1));
ftDev = ftD2xx.openByIndex(this, devCount -1);
} else {
synchronized (ftDev) {
System.out.println("ftDev is NOT null, synchronicing position " + (devCount - 1));
ftDev = ftD2xx.openByIndex(this, devCount -1);
}
}
// run thread
if (ftDev.isOpen()) {
SetConfig(9600, (byte) 8, (byte) 2, (byte) 0, (byte) 0);
ftDev.purge((byte) (D2xxManager.FT_PURGE_TX | D2xxManager.FT_PURGE_RX));
ftDev.restartInTask();
}
Log.i(TAG, "Ending openDevice");
}
private static void closeDevice() {
Log.i(TAG, "Starting closeDevice");
if (ftDev != null) {
deviceCom.Stop();
ftDev.close();
Log.i(TAG, "Device closed");
}
Log.i(TAG, "Ending closeDevice");
}
public static void SetConfig(int baud, byte dataBits, byte stopBits, byte parity, byte flowControl) {
Log.i(TAG, "Starting SetConfig");
if (!ftDev.isOpen()) {
Log.i(TAG, "Starting SetConfig");
return;
}
// configure our port
// reset to UART mode for 232 devices
ftDev.setBitMode((byte) 0, D2xxManager.FT_BITMODE_RESET);
ftDev.setBaudRate(baud);
switch (dataBits) {
case 7:
dataBits = D2xxManager.FT_DATA_BITS_7;
break;
case 8:
dataBits = D2xxManager.FT_DATA_BITS_8;
break;
default:
dataBits = D2xxManager.FT_DATA_BITS_8;
break;
}
switch (stopBits) {
case 1:
stopBits = D2xxManager.FT_STOP_BITS_1;
break;
case 2:
stopBits = D2xxManager.FT_STOP_BITS_2;
break;
default:
stopBits = D2xxManager.FT_STOP_BITS_1;
break;
}
switch (parity) {
case 0:
parity = D2xxManager.FT_PARITY_NONE;
break;
case 1:
parity = D2xxManager.FT_PARITY_ODD;
break;
case 2:
parity = D2xxManager.FT_PARITY_EVEN;
break;
case 3:
parity = D2xxManager.FT_PARITY_MARK;
break;
case 4:
parity = D2xxManager.FT_PARITY_SPACE;
break;
default:
parity = D2xxManager.FT_PARITY_NONE;
break;
}
ftDev.setDataCharacteristics(dataBits, stopBits, parity);
short flowCtrlSetting;
switch (flowControl) {
case 0:
flowCtrlSetting = D2xxManager.FT_FLOW_NONE;
break;
case 1:
flowCtrlSetting = D2xxManager.FT_FLOW_RTS_CTS;
break;
case 2:
flowCtrlSetting = D2xxManager.FT_FLOW_DTR_DSR;
break;
case 3:
flowCtrlSetting = D2xxManager.FT_FLOW_XON_XOFF;
break;
default:
flowCtrlSetting = D2xxManager.FT_FLOW_NONE;
break;
}
ftDev.setFlowControl(flowCtrlSetting, (byte) 0x0b, (byte) 0x0d);
Log.i(TAG, "Ending SetConfig");
}
public static void DisplaySetUp(SSPDevice dev)
{
Log.i(TAG, "Starting DisplaySetUp");
// check for type comapable
if(dev.type != SSPDeviceType.BillValidator){
return;
}
/* device details */
System.out.println(" " + dev.firmwareVersion);
System.out.println(" " + dev.headerType.toString());
System.out.println(" " + dev.serialNumber);
System.out.println(" " + dev.datasetVersion);
/* display the channel info */
for (ItlCurrency itlCurrency : dev.currency) {
@SuppressLint("DefaultLocale") String v = itlCurrency.country + " " + String.format("%.2f", itlCurrency.realvalue);
System.out.println(v);
}
// if device has barcode hardware
if (dev.barCodeReader.hardWareConfig != SSPDevice.BarCodeStatus.None) {
// send new configuration
BarCodeReader cfg = new BarCodeReader();
cfg.barcodeReadEnabled = true;
cfg.billReadEnabled = true;
cfg.numberOfCharacters = 18;
cfg.format = SSPDevice.BarCodeFormat.Interleaved2of5;
cfg.enabledConfig = SSPDevice.BarCodeStatus.Both;
deviceCom.SetBarcocdeConfig(cfg);
}
Log.i(TAG, "Ending DisplaySetUp");
}
@SuppressLint("DefaultLocale")
public static void DisplayEvents(DeviceEvent ev) {
Log.i(TAG, "Starting DisplayEvents");
switch (ev.event) {
case CommunicationsFailure:
System.out.println("CommunicationsFailure");
break;
case Ready:
System.out.println("Ready");
break;
case BillRead:
System.out.println("Reading");
break;
case BillEscrow:
System.out.println("Bill Escrow: " + ev.currency + " " + String.format("%.2f", ev.value));
break;
case BillStacked:
System.out.println("BillStacked");
break;
case BillReject:
System.out.println("Bill Reject");
break;
case BillJammed:
System.out.println("Bill jammed");
break;
case BillFraud:
System.out.println("Bill Fraud: " + ev.currency + " " + String.format("%.2f", ev.value));
break;
case BillCredit:
System.out.println("Bill Credit: " + ev.currency + " " + String.format("%.2f", ev.value));
break;
case Full:
System.out.println("Bill Cashbox full");
break;
case Initialising:
System.out.println("Initialising");
break;
case Disabled:
System.out.println("Disabled");
break;
case SoftwareError:
System.out.println("Software error");
break;
case AllDisabled:
System.out.println("All channels disabled");
break;
case CashboxRemoved:
System.out.println("Cashbox removed");
break;
case CashboxReplaced:
System.out.println("Cashbox replaced");
break;
case NotePathOpen:
System.out.println("Note path open");
break;
case BarCodeTicketEscrow:
System.out.println("Barcode ticket escrow:");
break;
case BarCodeTicketStacked:
System.out.println("Barcode ticket stacked");
break;
}
Log.i(TAG, "Ending DisplayEvents");
}
}
ITLDeviceCom
public class ITLDeviceCom extends Thread implements DeviceSetupListener, DeviceEventListener, DeviceFileUpdateListener {
private static boolean isrunning = false;
private static SSPSystem sspSystem;
private FT_Device ftDev = null;
static final int READBUF_SIZE = 256;
static final int WRITEBUF_SIZE = 4096;
byte[] rbuf = new byte[READBUF_SIZE];
byte[] wbuf = new byte[WRITEBUF_SIZE];
int mReadSize = 0;
private SSPDevice sspDevice = null;
public ITLDeviceCom(){
sspSystem = new SSPSystem();
sspSystem.setOnDeviceSetupListener(this);
sspSystem.setOnEventUpdateListener(this);
sspSystem.setOnDeviceFileUpdateListener(this);
}
public void setup(FT_Device ftdev, int address, boolean escrow, boolean essp, long key){
ftDev = ftdev;
/** void SetAddress(int address)
* Description: Sets the SSP address for the device to connect to.
* Parameters: [address: the address of the device (0x00 – 0x7E)].
* Default: the address is set to 0x00
* */
sspSystem.SetAddress(address);
/** void EscrowMode(boolean mode)
* Description: Enables or disables escrow mode for bill acceptance.
* Parameters: [mode: true to enable escrow mode, false to disable].
* Default: The object will be set to escrow disabled at start-up
* */
sspSystem.EscrowMode(escrow); // enable for escrow mode
/** void SetESSPMode
* Description: sets the object eSSP mode state.
* Parameters: [Boolean mode: true –> enable eSSP, false -> disable eSSP, long key -> the eSSP fixed key for the device e.g 0x0123456701234567].
* Default: eSSP disabled.
* */
sspSystem.SetESSPMode(essp, key);
sspSystem.SetBillEscrowAction(SSPSystem.BillAction.Accept);
}
@Override
public void run(){
long startTimeRead = SystemClock.uptimeMillis();
long timeOutTime = 10000;
int readSize = 0;
sspSystem.Run();
isrunning = true;
while(isrunning){
synchronized (ftDev) {
// poll for transmit data
int newdatalen = sspSystem.GetNewData(wbuf);
if (newdatalen > 0) {
if(sspSystem.GetDownloadState() != SSPSystem.DownloadSetupState.active) {
ftDev.purge((byte) 1);
}
ftDev.write(wbuf, newdatalen);
sspSystem.SetComsBufferWritten(true);
}
// poll for received
readSize = ftDev.getQueueStatus();
if (readSize > 0) {
mReadSize = readSize;
if (mReadSize > READBUF_SIZE) {
mReadSize = READBUF_SIZE;
}
readSize = ftDev.read(rbuf,mReadSize );
sspSystem.ProcessResponse(rbuf, readSize);
}
}// end of synchronized
// coms config changes
final SSPComsConfig cfg = sspSystem.GetComsConfig();
if(cfg.configUpdate == SSPComsConfig.ComsConfigChangeState.ccNewConfig){
cfg.configUpdate = SSPComsConfig.ComsConfigChangeState.ccUpdating;
MainActivity.SetConfig(cfg.baud,cfg.dataBits,cfg.stopBits,cfg.parity,cfg.flowControl);
cfg.configUpdate = SSPComsConfig.ComsConfigChangeState.ccUpdated;
}
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public void OnNewDeviceSetup(SSPDevice dev) {
// set local device object
Log.i(TAG, "OnNewDeviceSetup");
sspDevice = dev;
// call to Main UI
MainActivity.DisplaySetUp(dev);
}
@Override
public void OnDeviceDisconnect(final SSPDevice dev) { Log.i(TAG, "OnDeviceDisconnect"); }
@Override
public void OnDeviceEvent(final DeviceEvent ev) { MainActivity.DisplayEvents(ev); }
void Stop()
{
sspSystem.Close();
isrunning = false;
}
void SetEscrowMode(boolean mode){ if(sspSystem != null) sspSystem.EscrowMode(mode); }
void SetDeviceEnable(boolean en) {
if (sspSystem != null) {
if (en) {
sspSystem.EnableDevice();
}else {
sspSystem.DisableDevice();
}
}
}
void SetEscrowAction(SSPSystem.BillAction action){ if(sspSystem != null) sspSystem.SetBillEscrowAction(action); }
void SetBarcocdeConfig(BarCodeReader cfg) { if(sspSystem != null) sspSystem.SetBarCodeConfiguration(cfg); }
int GetDeviceCode()
{
if(sspSystem != null){
return sspDevice.headerType.getValue();
}else{
return -1;
}
}
@Override
public void OnFileUpdateStatus(SSPUpdate sspUpdate) {
}
}