|
@@ -0,0 +1,625 @@
|
|
|
+package com.melihyarikkaya.rnserialport;
|
|
|
+
|
|
|
+import android.app.PendingIntent;
|
|
|
+
|
|
|
+import android.content.BroadcastReceiver;
|
|
|
+import android.content.Context;
|
|
|
+import android.content.Intent;
|
|
|
+import android.content.IntentFilter;
|
|
|
+
|
|
|
+import com.facebook.react.bridge.Callback;
|
|
|
+import com.facebook.react.bridge.Promise;
|
|
|
+import com.facebook.react.bridge.ReactApplicationContext;
|
|
|
+import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
|
+import com.facebook.react.bridge.Arguments;
|
|
|
+import com.facebook.react.bridge.ReactMethod;
|
|
|
+import com.facebook.react.bridge.WritableArray;
|
|
|
+import com.facebook.react.bridge.WritableMap;
|
|
|
+import com.facebook.react.modules.core.DeviceEventManagerModule;
|
|
|
+import com.facebook.react.bridge.WritableNativeArray;
|
|
|
+
|
|
|
+import android.util.Base64;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+import com.google.common.primitives.UnsignedBytes;
|
|
|
+
|
|
|
+import android.hardware.usb.UsbDevice;
|
|
|
+import android.hardware.usb.UsbDeviceConnection;
|
|
|
+import android.hardware.usb.UsbManager;
|
|
|
+
|
|
|
+import com.felhr.usbserial.UsbSerialDevice;
|
|
|
+import com.felhr.usbserial.UsbSerialInterface;
|
|
|
+
|
|
|
+public class RNSerialportModule extends ReactContextBaseJavaModule {
|
|
|
+
|
|
|
+ private final ReactApplicationContext reactContext;
|
|
|
+ public RNSerialportModule(ReactApplicationContext reactContext) {
|
|
|
+ super(reactContext);
|
|
|
+ this.reactContext = reactContext;
|
|
|
+ fillDriverList();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String getName() {
|
|
|
+ return "RNSerialport";
|
|
|
+ }
|
|
|
+
|
|
|
+ private final String ACTION_USB_READY = "com.felhr.connectivityservices.USB_READY";
|
|
|
+ private final String ACTION_USB_ATTACHED = "android.hardware.usb.action.USB_DEVICE_ATTACHED";
|
|
|
+ private final String ACTION_USB_DETACHED = "android.hardware.usb.action.USB_DEVICE_DETACHED";
|
|
|
+ private final String ACTION_USB_NOT_SUPPORTED = "com.felhr.usbservice.USB_NOT_SUPPORTED";
|
|
|
+ private final String ACTION_NO_USB = "com.felhr.usbservice.NO_USB";
|
|
|
+ private final String ACTION_USB_PERMISSION_GRANTED = "com.felhr.usbservice.USB_PERMISSION_GRANTED";
|
|
|
+ private final String ACTION_USB_PERMISSION_NOT_GRANTED = "com.felhr.usbservice.USB_PERMISSION_NOT_GRANTED";
|
|
|
+ private final String ACTION_USB_DISCONNECTED = "com.felhr.usbservice.USB_DISCONNECTED";
|
|
|
+ private final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
|
|
|
+ private final String ACTION_USB_NOT_OPENED = "com.melihyarikkaya.rnserialport.USB_NOT_OPENED";
|
|
|
+ private final String ACTION_USB_CONNECT = "com.melihyarikkaya.rnserialport.USB_CONNECT";
|
|
|
+
|
|
|
+ //react-native events
|
|
|
+ private final String onErrorEvent = "onError";
|
|
|
+ private final String onConnectedEvent = "onConnected";
|
|
|
+ private final String onDisconnectedEvent = "onDisconnected";
|
|
|
+ private final String onDeviceAttachedEvent = "onDeviceAttached";
|
|
|
+ private final String onDeviceDetachedEvent = "onDeviceDetached";
|
|
|
+ private final String onServiceStarted = "onServiceStarted";
|
|
|
+ private final String onServiceStopped = "onServiceStopped";
|
|
|
+ private final String onReadDataFromPort = "onReadDataFromPort";
|
|
|
+ private final String onUsbPermissionGranted = "onUsbPermissionGranted";
|
|
|
+
|
|
|
+ //SUPPORTED DRIVER LIST
|
|
|
+
|
|
|
+ private List<String> driverList;
|
|
|
+
|
|
|
+ private UsbManager usbManager;
|
|
|
+ private UsbDevice device;
|
|
|
+ private UsbDeviceConnection connection;
|
|
|
+ private UsbSerialDevice serialPort;
|
|
|
+ private boolean serialPortConnected;
|
|
|
+
|
|
|
+ //Connection Settings
|
|
|
+ private int DATA_BIT = UsbSerialInterface.DATA_BITS_8;
|
|
|
+ private int STOP_BIT = UsbSerialInterface.STOP_BITS_1;
|
|
|
+ private int PARITY = UsbSerialInterface.PARITY_NONE;
|
|
|
+ private int FLOW_CONTROL = UsbSerialInterface.FLOW_CONTROL_OFF;
|
|
|
+ private int BAUD_RATE = 9600;
|
|
|
+
|
|
|
+
|
|
|
+ private boolean autoConnect = false;
|
|
|
+ private String autoConnectDeviceName;
|
|
|
+ private int autoConnectBaudRate = 9600;
|
|
|
+ private int portInterface = -1;
|
|
|
+ private int returnedDataType = Definitions.RETURNED_DATA_TYPE_INTARRAY;
|
|
|
+ private String driver = "AUTO";
|
|
|
+
|
|
|
+
|
|
|
+ private boolean usbServiceStarted = false;
|
|
|
+
|
|
|
+ private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
|
|
|
+ @Override
|
|
|
+ public void onReceive(Context arg0, Intent arg1) {
|
|
|
+ Intent intent;
|
|
|
+ switch (arg1.getAction()) {
|
|
|
+ case ACTION_USB_CONNECT:
|
|
|
+ eventEmit(onConnectedEvent, null);
|
|
|
+ break;
|
|
|
+ case ACTION_USB_DISCONNECTED:
|
|
|
+ eventEmit(onDisconnectedEvent, null);
|
|
|
+ break;
|
|
|
+ case ACTION_USB_NOT_SUPPORTED:
|
|
|
+ eventEmit(onErrorEvent, createError(Definitions.ERROR_DEVICE_NOT_SUPPORTED, Definitions.ERROR_DEVICE_NOT_SUPPORTED_MESSAGE));
|
|
|
+ break;
|
|
|
+ case ACTION_USB_NOT_OPENED:
|
|
|
+ eventEmit(onErrorEvent, createError(Definitions.ERROR_COULD_NOT_OPEN_SERIALPORT, Definitions.ERROR_COULD_NOT_OPEN_SERIALPORT_MESSAGE));
|
|
|
+ break;
|
|
|
+ case ACTION_USB_ATTACHED:
|
|
|
+ eventEmit(onDeviceAttachedEvent, null);
|
|
|
+ if(autoConnect && chooseFirstDevice()) {
|
|
|
+ connectDevice(autoConnectDeviceName, autoConnectBaudRate);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case ACTION_USB_DETACHED:
|
|
|
+ eventEmit(onDeviceDetachedEvent, null);
|
|
|
+ if(serialPortConnected) {
|
|
|
+ stopConnection();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case ACTION_USB_PERMISSION :
|
|
|
+ boolean granted = arg1.getExtras().getBoolean(UsbManager.EXTRA_PERMISSION_GRANTED);
|
|
|
+ startConnection(granted);
|
|
|
+ break;
|
|
|
+ case ACTION_USB_PERMISSION_GRANTED:
|
|
|
+ eventEmit(onUsbPermissionGranted, null);
|
|
|
+ break;
|
|
|
+ case ACTION_USB_PERMISSION_NOT_GRANTED:
|
|
|
+ eventEmit(onErrorEvent, createError(Definitions.ERROR_USER_DID_NOT_ALLOW_TO_CONNECT, Definitions.ERROR_USER_DID_NOT_ALLOW_TO_CONNECT_MESSAGE));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ private void eventEmit(String eventName, Object data) {
|
|
|
+ try {
|
|
|
+ if(reactContext.hasActiveCatalystInstance()) {
|
|
|
+ reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName, data);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Exception error) {}
|
|
|
+ }
|
|
|
+
|
|
|
+ private WritableMap createError(int code, String message) {
|
|
|
+ WritableMap err = Arguments.createMap();
|
|
|
+ err.putBoolean("status", false);
|
|
|
+ err.putInt("errorCode", code);
|
|
|
+ err.putString("errorMessage", message);
|
|
|
+
|
|
|
+ return err;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void setFilters() {
|
|
|
+ IntentFilter filter = new IntentFilter();
|
|
|
+ filter.addAction(ACTION_USB_PERMISSION_GRANTED);
|
|
|
+ filter.addAction(ACTION_NO_USB);
|
|
|
+ filter.addAction(ACTION_USB_CONNECT);
|
|
|
+ filter.addAction(ACTION_USB_DISCONNECTED);
|
|
|
+ filter.addAction(ACTION_USB_NOT_SUPPORTED);
|
|
|
+ filter.addAction(ACTION_USB_PERMISSION_NOT_GRANTED);
|
|
|
+ filter.addAction(ACTION_USB_PERMISSION);
|
|
|
+ filter.addAction(ACTION_USB_ATTACHED);
|
|
|
+ filter.addAction(ACTION_USB_DETACHED);
|
|
|
+ reactContext.registerReceiver(mUsbReceiver, filter);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void fillDriverList() {
|
|
|
+ driverList = new ArrayList<>();
|
|
|
+ driverList.add("ftdi");
|
|
|
+ driverList.add("cp210x");
|
|
|
+ driverList.add("pl2303");
|
|
|
+ driverList.add("ch34x");
|
|
|
+ driverList.add("cdc");
|
|
|
+ }
|
|
|
+
|
|
|
+ /******************************* BEGIN PUBLIC SETTER METHODS **********************************/
|
|
|
+
|
|
|
+ @ReactMethod
|
|
|
+ public void setDataBit(int DATA_BIT) {
|
|
|
+ this.DATA_BIT = DATA_BIT;
|
|
|
+ }
|
|
|
+ @ReactMethod
|
|
|
+ public void setStopBit(int STOP_BIT) {
|
|
|
+ this.STOP_BIT = STOP_BIT;
|
|
|
+ }
|
|
|
+ @ReactMethod
|
|
|
+ public void setParity(int PARITY) {
|
|
|
+ this.PARITY = PARITY;
|
|
|
+ }
|
|
|
+ @ReactMethod
|
|
|
+ public void setFlowControl(int FLOW_CONTROL) {
|
|
|
+ this.FLOW_CONTROL = FLOW_CONTROL;
|
|
|
+ }
|
|
|
+
|
|
|
+ @ReactMethod
|
|
|
+ public void loadDefaultConnectionSetting() {
|
|
|
+ DATA_BIT = UsbSerialInterface.DATA_BITS_8;
|
|
|
+ STOP_BIT = UsbSerialInterface.STOP_BITS_1;
|
|
|
+ PARITY = UsbSerialInterface.PARITY_NONE;
|
|
|
+ FLOW_CONTROL = UsbSerialInterface.FLOW_CONTROL_OFF;
|
|
|
+ }
|
|
|
+ @ReactMethod
|
|
|
+ public void setAutoConnect(boolean autoConnect) {
|
|
|
+ this.autoConnect = autoConnect;
|
|
|
+ }
|
|
|
+ @ReactMethod
|
|
|
+ public void setAutoConnectBaudRate(int baudRate) {
|
|
|
+ this.autoConnectBaudRate = baudRate;
|
|
|
+ }
|
|
|
+ @ReactMethod
|
|
|
+ public void setInterface(int iFace) {
|
|
|
+ this.portInterface = iFace;
|
|
|
+ }
|
|
|
+ @ReactMethod
|
|
|
+ public void setReturnedDataType(int type) {
|
|
|
+ if(type == Definitions.RETURNED_DATA_TYPE_HEXSTRING || type == Definitions.RETURNED_DATA_TYPE_INTARRAY) {
|
|
|
+ this.returnedDataType = type;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @ReactMethod
|
|
|
+ public void setDriver(String driver) {
|
|
|
+ if(driver.isEmpty() || !driverList.contains(driver.trim())) {
|
|
|
+ eventEmit(onErrorEvent, createError(Definitions.ERROR_DRIVER_TYPE_NOT_FOUND, Definitions.ERROR_DRIVER_TYPE_NOT_FOUND_MESSAGE));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ this.driver = driver;
|
|
|
+ }
|
|
|
+
|
|
|
+ /********************************************* END **********************************************/
|
|
|
+
|
|
|
+ @ReactMethod
|
|
|
+ public void startUsbService() {
|
|
|
+ if(usbServiceStarted) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ setFilters();
|
|
|
+
|
|
|
+ usbManager = (UsbManager) reactContext.getSystemService(Context.USB_SERVICE);
|
|
|
+
|
|
|
+ usbServiceStarted = true;
|
|
|
+
|
|
|
+ //Return usb status when service is started.
|
|
|
+ WritableMap map = Arguments.createMap();
|
|
|
+
|
|
|
+ map.putBoolean("deviceAttached", !usbManager.getDeviceList().isEmpty());
|
|
|
+
|
|
|
+ eventEmit(onServiceStarted, map);
|
|
|
+
|
|
|
+ checkAutoConnect();
|
|
|
+ }
|
|
|
+
|
|
|
+ @ReactMethod
|
|
|
+ public void stopUsbService() {
|
|
|
+ if(serialPortConnected) {
|
|
|
+ eventEmit(onErrorEvent, createError(Definitions.ERROR_SERVICE_STOP_FAILED, Definitions.ERROR_SERVICE_STOP_FAILED_MESSAGE));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if(!usbServiceStarted) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ reactContext.unregisterReceiver(mUsbReceiver);
|
|
|
+ usbServiceStarted = false;
|
|
|
+ eventEmit(onServiceStopped, null);
|
|
|
+ }
|
|
|
+
|
|
|
+ @ReactMethod
|
|
|
+ public void getDeviceList(Promise promise) {
|
|
|
+ if(!usbServiceStarted) {
|
|
|
+ promise.reject(String.valueOf(Definitions.ERROR_USB_SERVICE_NOT_STARTED), Definitions.ERROR_USB_SERVICE_NOT_STARTED_MESSAGE);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ UsbManager manager = (UsbManager) reactContext.getSystemService(Context.USB_SERVICE);
|
|
|
+
|
|
|
+ HashMap<String, UsbDevice> devices = manager.getDeviceList();
|
|
|
+
|
|
|
+ if(devices.isEmpty()) {
|
|
|
+ //promise.reject(String.valueOf(Definitions.ERROR_DEVICE_NOT_FOUND), Definitions.ERROR_DEVICE_NOT_FOUND_MESSAGE);
|
|
|
+ promise.resolve(Arguments.createArray());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ WritableArray deviceList = Arguments.createArray();
|
|
|
+ for(Map.Entry<String, UsbDevice> entry: devices.entrySet()) {
|
|
|
+ UsbDevice d = entry.getValue();
|
|
|
+
|
|
|
+ WritableMap map = Arguments.createMap();
|
|
|
+ map.putString("name", d.getDeviceName());
|
|
|
+ map.putInt("vendorId", d.getVendorId());
|
|
|
+ map.putInt("productId", d.getProductId());
|
|
|
+
|
|
|
+ deviceList.pushMap(map);
|
|
|
+ }
|
|
|
+
|
|
|
+ promise.resolve(deviceList);
|
|
|
+ }
|
|
|
+
|
|
|
+ @ReactMethod
|
|
|
+ public void connectDevice(String deviceName, int baudRate) {
|
|
|
+ try {
|
|
|
+ if(!usbServiceStarted){
|
|
|
+ eventEmit(onErrorEvent, createError(Definitions.ERROR_USB_SERVICE_NOT_STARTED, Definitions.ERROR_USB_SERVICE_NOT_STARTED_MESSAGE));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(serialPortConnected) {
|
|
|
+ eventEmit(onErrorEvent, createError(Definitions.ERROR_SERIALPORT_ALREADY_CONNECTED, Definitions.ERROR_SERIALPORT_ALREADY_CONNECTED_MESSAGE));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(deviceName.isEmpty() || deviceName.length() < 0) {
|
|
|
+ eventEmit(onErrorEvent, createError(Definitions.ERROR_CONNECT_DEVICE_NAME_INVALID, Definitions.ERROR_CONNECT_DEVICE_NAME_INVALID_MESSAGE));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(baudRate < 1){
|
|
|
+ eventEmit(onErrorEvent, createError(Definitions.ERROR_CONNECT_BAUDRATE_EMPTY, Definitions.ERROR_CONNECT_BAUDRATE_EMPTY_MESSAGE));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!autoConnect) {
|
|
|
+ this.BAUD_RATE = baudRate;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!chooseDevice(deviceName)) {
|
|
|
+ eventEmit(onErrorEvent, createError(Definitions.ERROR_X_DEVICE_NOT_FOUND, Definitions.ERROR_X_DEVICE_NOT_FOUND_MESSAGE + deviceName));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ requestUserPermission();
|
|
|
+
|
|
|
+ } catch (Exception err) {
|
|
|
+ eventEmit(onErrorEvent, createError(Definitions.ERROR_CONNECTION_FAILED, Definitions.ERROR_CONNECTION_FAILED_MESSAGE + " Catch Error Message:" + err.getMessage()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @ReactMethod
|
|
|
+ public void disconnect() {
|
|
|
+ if(!usbServiceStarted){
|
|
|
+ eventEmit(onErrorEvent, createError(Definitions.ERROR_USB_SERVICE_NOT_STARTED, Definitions.ERROR_USB_SERVICE_NOT_STARTED_MESSAGE));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!serialPortConnected) {
|
|
|
+ eventEmit(onErrorEvent, createError(Definitions.ERROR_SERIALPORT_ALREADY_DISCONNECTED, Definitions.ERROR_SERIALPORT_ALREADY_DISCONNECTED_MESSAGE));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ stopConnection();
|
|
|
+ }
|
|
|
+
|
|
|
+ @ReactMethod
|
|
|
+ public void isOpen(Promise promise) {
|
|
|
+ promise.resolve(serialPortConnected);
|
|
|
+ }
|
|
|
+
|
|
|
+ @ReactMethod
|
|
|
+ public void isServiceStarted(Promise promise) {
|
|
|
+ promise.resolve(usbServiceStarted);
|
|
|
+ }
|
|
|
+
|
|
|
+ @ReactMethod
|
|
|
+ public void isSupported(String deviceName, Promise promise) {
|
|
|
+ if(!chooseDevice(deviceName)) {
|
|
|
+ promise.reject(String.valueOf(Definitions.ERROR_DEVICE_NOT_FOUND), Definitions.ERROR_DEVICE_NOT_FOUND_MESSAGE);
|
|
|
+ } else {
|
|
|
+ promise.resolve(UsbSerialDevice.isSupported(device));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @ReactMethod
|
|
|
+ public void writeBytes(byte[] bytes) {
|
|
|
+ if(!usbServiceStarted){
|
|
|
+ eventEmit(onErrorEvent, createError(Definitions.ERROR_USB_SERVICE_NOT_STARTED, Definitions.ERROR_USB_SERVICE_NOT_STARTED_MESSAGE));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if(!serialPortConnected || serialPort == null) {
|
|
|
+ eventEmit(onErrorEvent, createError(Definitions.ERROR_THERE_IS_NO_CONNECTION, Definitions.ERROR_THERE_IS_NO_CONNECTION_MESSAGE));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ serialPort.write(bytes);
|
|
|
+ }
|
|
|
+
|
|
|
+ @ReactMethod
|
|
|
+ public void writeString(String message) {
|
|
|
+ if(!usbServiceStarted){
|
|
|
+ eventEmit(onErrorEvent, createError(Definitions.ERROR_USB_SERVICE_NOT_STARTED, Definitions.ERROR_USB_SERVICE_NOT_STARTED_MESSAGE));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if(!serialPortConnected || serialPort == null) {
|
|
|
+ eventEmit(onErrorEvent, createError(Definitions.ERROR_THERE_IS_NO_CONNECTION, Definitions.ERROR_THERE_IS_NO_CONNECTION_MESSAGE));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ serialPort.write(message.getBytes());
|
|
|
+ }
|
|
|
+
|
|
|
+ @ReactMethod
|
|
|
+ public void writeBase64(String message) {
|
|
|
+ if(!usbServiceStarted){
|
|
|
+ eventEmit(onErrorEvent, createError(Definitions.ERROR_USB_SERVICE_NOT_STARTED, Definitions.ERROR_USB_SERVICE_NOT_STARTED_MESSAGE));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if(!serialPortConnected || serialPort == null) {
|
|
|
+ eventEmit(onErrorEvent, createError(Definitions.ERROR_THERE_IS_NO_CONNECTION, Definitions.ERROR_THERE_IS_NO_CONNECTION_MESSAGE));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ byte [] data = Base64.decode(message, Base64.DEFAULT);
|
|
|
+ serialPort.write(data);
|
|
|
+ }
|
|
|
+
|
|
|
+ @ReactMethod
|
|
|
+ public void writeHexString(String message) {
|
|
|
+ if(!usbServiceStarted){
|
|
|
+ eventEmit(onErrorEvent, createError(Definitions.ERROR_USB_SERVICE_NOT_STARTED, Definitions.ERROR_USB_SERVICE_NOT_STARTED_MESSAGE));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if(!serialPortConnected || serialPort == null) {
|
|
|
+ eventEmit(onErrorEvent, createError(Definitions.ERROR_THERE_IS_NO_CONNECTION, Definitions.ERROR_THERE_IS_NO_CONNECTION_MESSAGE));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(message.length() < 1) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ byte[] data = new byte[message.length() / 2];
|
|
|
+ for (int i = 0; i < data.length; i++) {
|
|
|
+ int index = i * 2;
|
|
|
+
|
|
|
+ String hex = message.substring(index, index + 2);
|
|
|
+
|
|
|
+ if(Definitions.hexChars.indexOf(hex.substring(0, 1)) == -1 || Definitions.hexChars.indexOf(hex.substring(1, 1)) == -1) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ int v = Integer.parseInt(hex, 16);
|
|
|
+ data[i] = (byte) v;
|
|
|
+ }
|
|
|
+ serialPort.write(data);
|
|
|
+ }
|
|
|
+
|
|
|
+ ///////////////////////////////////////////////USB SERVICE /////////////////////////////////////////////////////////
|
|
|
+ ///////////////////////////////////////////////USB SERVICE /////////////////////////////////////////////////////////
|
|
|
+
|
|
|
+ private boolean chooseDevice(String deviceName) {
|
|
|
+ HashMap<String, UsbDevice> usbDevices = usbManager.getDeviceList();
|
|
|
+ if(usbDevices.isEmpty()) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ boolean selected = false;
|
|
|
+
|
|
|
+ for (Map.Entry<String, UsbDevice> entry: usbDevices.entrySet()) {
|
|
|
+ UsbDevice d = entry.getValue();
|
|
|
+
|
|
|
+ if(d.getDeviceName().equals(deviceName)) {
|
|
|
+ device = d;
|
|
|
+ selected = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return selected;
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean chooseFirstDevice() {
|
|
|
+ HashMap<String, UsbDevice> usbDevices = usbManager.getDeviceList();
|
|
|
+ if(usbDevices.isEmpty()) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ boolean selected = false;
|
|
|
+
|
|
|
+ for (Map.Entry<String, UsbDevice> entry: usbDevices.entrySet()) {
|
|
|
+ UsbDevice d = entry.getValue();
|
|
|
+
|
|
|
+ int deviceVID = d.getVendorId();
|
|
|
+ int devicePID = d.getProductId();
|
|
|
+
|
|
|
+ if (deviceVID != 0x1d6b && (devicePID != 0x0001 && devicePID != 0x0002 && devicePID != 0x0003) && deviceVID != 0x5c6 && devicePID != 0x904c)
|
|
|
+ {
|
|
|
+ device = d;
|
|
|
+ autoConnectDeviceName = d.getDeviceName();
|
|
|
+ selected = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return selected;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void checkAutoConnect() {
|
|
|
+ if(!autoConnect || serialPortConnected)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if(chooseFirstDevice()) {
|
|
|
+ connectDevice(autoConnectDeviceName, autoConnectBaudRate);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ private class ConnectionThread extends Thread {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ try {
|
|
|
+ if(driver.equals("AUTO")) {
|
|
|
+ serialPort = UsbSerialDevice.createUsbSerialDevice(device, connection, portInterface);
|
|
|
+ } else {
|
|
|
+ serialPort = UsbSerialDevice.createUsbSerialDevice(driver, device, connection, portInterface);
|
|
|
+ }
|
|
|
+ if(serialPort == null) {
|
|
|
+ // No driver for given device
|
|
|
+ Intent intent = new Intent(ACTION_USB_NOT_SUPPORTED);
|
|
|
+ reactContext.sendBroadcast(intent);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!serialPort.open()){
|
|
|
+ Intent intent = new Intent(ACTION_USB_NOT_OPENED);
|
|
|
+ reactContext.sendBroadcast(intent);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ serialPortConnected = true;
|
|
|
+ int baud;
|
|
|
+ if(autoConnect){
|
|
|
+ baud = autoConnectBaudRate;
|
|
|
+ }else {
|
|
|
+ baud = BAUD_RATE;
|
|
|
+ }
|
|
|
+ serialPort.setBaudRate(baud);
|
|
|
+ serialPort.setDataBits(DATA_BIT);
|
|
|
+ serialPort.setStopBits(STOP_BIT);
|
|
|
+ serialPort.setParity(PARITY);
|
|
|
+ serialPort.setFlowControl(FLOW_CONTROL);
|
|
|
+ serialPort.read(mCallback);
|
|
|
+
|
|
|
+ Intent intent = new Intent(ACTION_USB_READY);
|
|
|
+ reactContext.sendBroadcast(intent);
|
|
|
+ intent = new Intent(ACTION_USB_CONNECT);
|
|
|
+ reactContext.sendBroadcast(intent);
|
|
|
+ } catch (Exception error) {
|
|
|
+ WritableMap map = createError(Definitions.ERROR_CONNECTION_FAILED, Definitions.ERROR_CONNECTION_FAILED_MESSAGE);
|
|
|
+ map.putString("exceptionErrorMessage", error.getMessage());
|
|
|
+ eventEmit(onErrorEvent, map);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void requestUserPermission() {
|
|
|
+ if(device == null)
|
|
|
+ return;
|
|
|
+ PendingIntent mPendingIntent = PendingIntent.getBroadcast(reactContext, 0 , new Intent(ACTION_USB_PERMISSION), 0);
|
|
|
+ usbManager.requestPermission(device, mPendingIntent);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void startConnection(boolean granted) {
|
|
|
+ if(granted) {
|
|
|
+ Intent intent = new Intent(ACTION_USB_PERMISSION_GRANTED);
|
|
|
+ reactContext.sendBroadcast(intent);
|
|
|
+ connection = usbManager.openDevice(device);
|
|
|
+ new ConnectionThread().start();
|
|
|
+ } else {
|
|
|
+ connection = null;
|
|
|
+ device = null;
|
|
|
+ Intent intent = new Intent(ACTION_USB_PERMISSION_NOT_GRANTED);
|
|
|
+ reactContext.sendBroadcast(intent);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void stopConnection() {
|
|
|
+ if (serialPortConnected) {
|
|
|
+ serialPort.close();
|
|
|
+ connection = null;
|
|
|
+ device = null;
|
|
|
+ Intent intent = new Intent(ACTION_USB_DISCONNECTED);
|
|
|
+ reactContext.sendBroadcast(intent);
|
|
|
+ serialPortConnected = false;
|
|
|
+ } else {
|
|
|
+ Intent intent = new Intent(ACTION_USB_DETACHED);
|
|
|
+ reactContext.sendBroadcast(intent);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() {
|
|
|
+ @Override
|
|
|
+ public void onReceivedData(byte[] bytes) {
|
|
|
+ try {
|
|
|
+
|
|
|
+ String payloadKey = "payload";
|
|
|
+
|
|
|
+ WritableMap params = Arguments.createMap();
|
|
|
+
|
|
|
+ if(returnedDataType == Definitions.RETURNED_DATA_TYPE_INTARRAY) {
|
|
|
+
|
|
|
+ WritableArray intArray = new WritableNativeArray();
|
|
|
+ for(byte b: bytes) {
|
|
|
+ intArray.pushInt(UnsignedBytes.toInt(b));
|
|
|
+ }
|
|
|
+ params.putArray(payloadKey, intArray);
|
|
|
+
|
|
|
+ } else if(returnedDataType == Definitions.RETURNED_DATA_TYPE_HEXSTRING) {
|
|
|
+ String hexString = Definitions.bytesToHex(bytes);
|
|
|
+ params.putString(payloadKey, hexString);
|
|
|
+ } else
|
|
|
+ return;
|
|
|
+
|
|
|
+ eventEmit(onReadDataFromPort, params);
|
|
|
+
|
|
|
+ } catch (Exception err) {
|
|
|
+ eventEmit(onErrorEvent, createError(Definitions.ERROR_NOT_READED_DATA, Definitions.ERROR_NOT_READED_DATA_MESSAGE + " System Message: " + err.getMessage()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+}
|