365 lines
8.3 KiB
Java
365 lines
8.3 KiB
Java
package org.hwo.io.NewSerialPort;
|
|
|
|
import java.io.File;
|
|
import java.io.FilenameFilter;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.OutputStream;
|
|
import java.util.ArrayList;
|
|
import java.util.LinkedList;
|
|
import java.util.List;
|
|
|
|
import org.hwo.StringHelper;
|
|
import org.hwo.io.NativeSerialPort;
|
|
import org.hwo.io.SerialPortExeption;
|
|
import org.hwo.io.SerialPortWINDOWS;
|
|
import org.hwo.platform.Platform;
|
|
import org.hwo.platform.natives.NativeLoader;
|
|
|
|
public class NewSerialPort {
|
|
|
|
public static long nsp_RET_OK = 0; // Kein Fehler
|
|
public static long nsp_RET_NOTFOUND = -1; // Port konnte nicht geöffnet werden
|
|
public static long nsp_RET_PARAM = -2; // Parameter ungültig
|
|
public static long nsp_RET_SHORTREAD = -3;
|
|
public static long nsp_RET_TIMEOUT = -4;
|
|
public static long nsp_RET_NOTOPEN = -5;
|
|
|
|
public static long nsp_RET_OTHER = -99; // Unbekannter Fehler
|
|
|
|
|
|
String portName;
|
|
int baudRate;
|
|
int databits;
|
|
boolean stopbit2;
|
|
HandShake handShake;
|
|
Parity parity;
|
|
|
|
int timeout;
|
|
|
|
long nsp;
|
|
|
|
boolean wasOpened;
|
|
boolean autoOpen;
|
|
|
|
private NewSerialPortInputStream inputStream;
|
|
private NewSerialPortOutputStream outputStream;
|
|
|
|
private List<NewSerialPortListener> serialPortListeners;
|
|
|
|
public NewSerialPort(String portName) {
|
|
|
|
this.nsp = nsp_alloc();
|
|
|
|
serialPortListeners = new LinkedList<NewSerialPortListener>();
|
|
|
|
setPortName(portName);
|
|
|
|
setBaudRate(9600);
|
|
setDatabits(8);
|
|
setStopBit2(false);
|
|
|
|
setHandShake(HandShake.NONE);
|
|
setParity(Parity.NONE);
|
|
|
|
setTimeOut(0);
|
|
|
|
this.inputStream = new NewSerialPortInputStream();
|
|
this.outputStream = new NewSerialPortOutputStream();
|
|
}
|
|
|
|
@Override
|
|
protected void finalize() throws Throwable {
|
|
nsp_free(this.nsp);
|
|
|
|
super.finalize();
|
|
}
|
|
|
|
public void addNewSerialPortListener(NewSerialPortListener listener){
|
|
serialPortListeners.add(listener);
|
|
}
|
|
public void removeNewSerialPortListener(NewSerialPortListener listener){
|
|
serialPortListeners.remove(listener);
|
|
}
|
|
|
|
private void fireConnectionStateChanged(){
|
|
for (NewSerialPortListener l: serialPortListeners)
|
|
l.connectionStateChanged(this, isOpen());
|
|
}
|
|
|
|
|
|
public NewSerialPortInputStream getInputStream() {
|
|
return inputStream;
|
|
}
|
|
public NewSerialPortOutputStream getOutputStream() {
|
|
return outputStream;
|
|
}
|
|
|
|
public boolean isAutoOpen(){
|
|
return autoOpen;
|
|
}
|
|
public void setAutoOpen(boolean autoOpen){
|
|
this.autoOpen = autoOpen;
|
|
}
|
|
|
|
public String getPortName() {
|
|
return portName;
|
|
}
|
|
public void setPortName(String portName) {
|
|
this.portName = portName;
|
|
nsp_set_portname(nsp, portName);
|
|
}
|
|
|
|
public int getBaudRate() {
|
|
return baudRate;
|
|
}
|
|
public void setBaudRate(int baudRate) {
|
|
this.baudRate = baudRate;
|
|
nsp_setup_baudrate(nsp, baudRate);
|
|
}
|
|
public void setBaudRate(BaudRate baudRate) {
|
|
setBaudRate(baudRate.getValue());
|
|
}
|
|
public BaudRate getBaudRate2(){
|
|
return BaudRate.fromInt(this.baudRate);
|
|
}
|
|
|
|
public int getDatabits() {
|
|
return databits;
|
|
}
|
|
public void setDatabits(int databits) {
|
|
this.databits = databits;
|
|
nsp_setup_bits(nsp, databits, this.stopbit2 ? 2 : 1);
|
|
}
|
|
|
|
public HandShake getHandShake() {
|
|
return handShake;
|
|
}
|
|
public void setHandShake(HandShake handShake) {
|
|
this.handShake = handShake;
|
|
nsp_setup_handshake(nsp, handShake.getValue());
|
|
}
|
|
|
|
public Parity getParity() {
|
|
return parity;
|
|
}
|
|
public void setParity(Parity parity) {
|
|
this.parity = parity;
|
|
nsp_setup_parity(nsp, parity.getValue());
|
|
}
|
|
|
|
public boolean getStopBit2(){
|
|
return this.stopbit2;
|
|
}
|
|
public void setStopBit2(boolean sb2){
|
|
this.stopbit2 = sb2;
|
|
nsp_setup_bits(nsp, databits, this.stopbit2 ? 2 : 1);
|
|
}
|
|
|
|
public int getTimeOut(){
|
|
return this.timeout;
|
|
}
|
|
public void setTimeOut(int timeout){
|
|
this.timeout = timeout;
|
|
nsp_setup_timeout(nsp, timeout);
|
|
}
|
|
|
|
public boolean open(){
|
|
int r = nsp_open(nsp);
|
|
wasOpened = (r == 0);
|
|
|
|
System.err.println(String.format("nsp_open(): %d",r));
|
|
|
|
fireConnectionStateChanged();
|
|
|
|
return wasOpened;
|
|
}
|
|
public void close(){
|
|
nsp_close(nsp);
|
|
wasOpened = false;
|
|
fireConnectionStateChanged();
|
|
}
|
|
|
|
public boolean isOpen(){
|
|
return wasOpened;
|
|
}
|
|
|
|
/*
|
|
* getSettings(...)
|
|
*
|
|
* Erstelle eine Text-Repräsentation der aktuellen Port Einstellungen
|
|
*
|
|
*/
|
|
public String getSettings(boolean includePortName){
|
|
List<String> tokens = new LinkedList<String>();
|
|
|
|
if (includePortName){
|
|
tokens.add(String.format("PN=%s",this.portName));
|
|
}
|
|
|
|
tokens.add(String.format("B=%d",this.baudRate));
|
|
tokens.add(String.format("P=%s",this.parity.getLetter()));
|
|
tokens.add(String.format("H=%s", this.handShake.getLetter()));
|
|
tokens.add(String.format("SB=%d", (this.stopbit2) ? 2 : 1 ));
|
|
|
|
return StringHelper.join(tokens, ";");
|
|
}
|
|
|
|
public boolean parseSettings(String settings){
|
|
String[] tokens = settings.split(";");
|
|
|
|
for (String token: tokens){
|
|
String[] st = token.split("=", 2);
|
|
|
|
if (st.length == 2){
|
|
if (st[0].equals("PN")){
|
|
this.setPortName(st[1]);
|
|
}
|
|
if (st[0].equals("B")){
|
|
this.setBaudRate(Integer.parseInt(st[1]));
|
|
}
|
|
if (st[0].equals("P")){
|
|
this.setParity( Parity.fromLetter(st[1]));
|
|
}
|
|
if (st[0].equals("H")){
|
|
this.setHandShake( HandShake.fromLetter(st[1]));
|
|
}
|
|
if (st[0].equals("SB")){
|
|
this.setStopBit2( st[1].equals("2"));
|
|
}
|
|
}
|
|
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
private static native synchronized long nsp_alloc();
|
|
private static native synchronized int nsp_free(long msp);
|
|
|
|
private static native synchronized int nsp_set_portname(long nsp,String portName);
|
|
private static native synchronized int nsp_setup_baudrate(long nsp,int baudRate);
|
|
private static native synchronized int nsp_setup_bits(long nsp,int dataBits,int stopBits);
|
|
private static native synchronized int nsp_setup_parity(long nsp,int parity);
|
|
private static native synchronized int nsp_setup_handshake(long nsp,int handshake);
|
|
private static native synchronized int nsp_setup_timeout(long nsp,int timeout);
|
|
|
|
private static native int nsp_open(long nsp);
|
|
private static native int nsp_close(long nsp);
|
|
|
|
private static native int nsp_read(long nsp);
|
|
private static native int nsp_write(long nsp,int ch);
|
|
|
|
static {
|
|
NativeLoader.loadLibrary("nsp");
|
|
}
|
|
|
|
|
|
public class NewSerialPortInputStream extends InputStream
|
|
{
|
|
@Override
|
|
public int read() throws IOException {
|
|
if (autoOpen && !isOpen())
|
|
open();
|
|
|
|
int ch = nsp_read(nsp);
|
|
if (ch < 0){
|
|
if (ch == nsp_RET_TIMEOUT)
|
|
return -1;
|
|
throw new IOException(String.format("nsp_read()=%d", ch));
|
|
};
|
|
return ch;
|
|
}
|
|
}
|
|
|
|
public class NewSerialPortOutputStream extends OutputStream
|
|
{
|
|
@Override
|
|
public void write(int arg0) throws IOException{
|
|
int r;
|
|
|
|
if (autoOpen && !isOpen())
|
|
open();
|
|
|
|
r = nsp_write(nsp, arg0);
|
|
if (r<0){
|
|
throw new IOException(String.format("nsp_write()=%d", r));
|
|
}
|
|
}
|
|
}
|
|
|
|
static public String[] getPortNames(){
|
|
switch (Platform.getOperatingSystem()){
|
|
case LINUX:
|
|
return getPortNamesLIN();
|
|
case WINDOWS:
|
|
return getPortNamesWIN();
|
|
case OSX:
|
|
return getPortNamesOSX();
|
|
default:
|
|
return new String[0];
|
|
}
|
|
}
|
|
static public String[] getPortNamesWIN()
|
|
{
|
|
ArrayList<String> portNames = new ArrayList<String>();
|
|
|
|
NewSerialPort sp = new NewSerialPort("");
|
|
|
|
for (int i = 1; i < 32; i++)
|
|
{
|
|
sp.setPortName(String.format("COM%d:",i));
|
|
if (sp.open())
|
|
{
|
|
portNames.add(String.format("COM%d:",i));
|
|
sp.close();
|
|
}
|
|
}
|
|
|
|
return portNames.toArray(new String[0]);
|
|
}
|
|
static public String[] getPortNamesLIN()
|
|
{
|
|
ArrayList<String> portNames = new ArrayList<String>();
|
|
|
|
File devDir = new File("/dev");
|
|
File[] list = devDir.listFiles(new FilenameFilter() {
|
|
|
|
@Override
|
|
public boolean accept(File arg0, String arg1) {
|
|
if (arg1.startsWith("ttyS") || arg1.startsWith("ttyACM"))
|
|
return true;
|
|
return false;
|
|
}
|
|
});
|
|
|
|
for (File file:list)
|
|
portNames.add("/dev/" + file.getName());
|
|
|
|
return portNames.toArray(new String[0]);
|
|
}
|
|
static public String[] getPortNamesOSX()
|
|
{
|
|
ArrayList<String> portNames = new ArrayList<String>();
|
|
|
|
File devDir = new File("/dev");
|
|
File[] list = devDir.listFiles(new FilenameFilter() {
|
|
|
|
@Override
|
|
public boolean accept(File arg0, String arg1) {
|
|
if (arg1.startsWith("tty.") || arg1.startsWith("ttyS"))
|
|
return true;
|
|
return false;
|
|
}
|
|
});
|
|
|
|
for (File file:list)
|
|
portNames.add("/dev/" + file.getName());
|
|
|
|
return portNames.toArray(new String[0]);
|
|
}
|
|
|
|
|
|
}
|