📄 atengineimpl.java
字号:
package com.jzl.sirius.at.impl;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.Queue;
import java.util.TooManyListenersException;
import java.util.concurrent.ConcurrentLinkedQueue;
/*import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;*/
import org.apache.log4j.Logger;
import com.jzl.sirius.at.ATCommand;
import com.jzl.sirius.at.ATEngine;
import com.jzl.sirius.at.ATEvent;
import com.jzl.sirius.at.ATException;
import com.jzl.sirius.at.ATResponse;
/**
* @author xujian
* @version 2.0
* @see com.jzl.sirius.at.ATEngine
*/
public class ATEngineImpl implements ATEngine, SerialPortEventListener {
private Logger logger = Logger.getLogger(ATEngineImpl.class);
private Queue<WaitResponse> queue = new ConcurrentLinkedQueue<WaitResponse>() ;
private final Object lock = new Object();
private final Object readReadyMonitor = new Object();
private SerialPort serialPort;
private InputStream inputStream;
private OutputStream outputStream;
private String applicationName = "";
private String portName = "COM1";
private int baudrate = 9600;
private int dataBits = 8;
private int stopBits = 1;
private int parity = 0;
private int flowControlMode = 0;
private int receiveThreshold = -1;
private int receiveTimeout = -1;
private int receiveFraming = -1;
private int id = -1;
private String loggerName = getClass().getName();
private long defaultATTimeout = 60000;
private boolean opened = false;
private boolean stopping = false;
private final Object closeLock = new Object();
private boolean stopped = true;
private Logger getLogger() {
return Logger.getLogger(ATEngineImpl.class);
}
public void write(String str) throws ATException {
if (getLogger().isDebugEnabled())
getLogger().debug(str);
try {
outputStream.write(str.getBytes());
outputStream.flush();
}
catch(IOException ex) {
throw new ATException(ex);
}
}
public synchronized void execute(ATCommand command) throws ATException {
execute(command, defaultATTimeout);
}
public synchronized void execute(ATCommand command, long timeout) throws ATException {
try {
synchronized(lock) {
WaitResponse response = new WaitResponse(command);
write(command.buildCommand());
response.startTime = System.currentTimeMillis();
queue.add(response);
lock.wait(timeout);
queue.remove(response);
}
}
catch(InterruptedException ex) {
}
}
public synchronized void waitfor(ATEvent event, long timeout) throws ATException {
try {
synchronized(lock) {
WaitResponse response = new WaitResponse(event);
response.startTime = System.currentTimeMillis();
queue.add(response);
lock.wait(timeout);
queue.remove(response);
}
}
catch(InterruptedException ex) {
}
}
public void open() {
opened = false;
try {
CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier(portName);
serialPort = (SerialPort) portId.open(applicationName, 2000);
serialPort.setSerialPortParams(baudrate, dataBits, stopBits, parity);
serialPort.notifyOnDataAvailable(true);
serialPort.setFlowControlMode(flowControlMode);
if (receiveThreshold == -1)
serialPort.disableReceiveThreshold();
else
serialPort.enableReceiveThreshold(receiveThreshold);
if (receiveTimeout == -1)
serialPort.disableReceiveTimeout();
else
serialPort.enableReceiveTimeout(receiveTimeout);
if (receiveFraming == -1)
serialPort.disableReceiveFraming();
else
serialPort.enableReceiveFraming(receiveFraming);
inputStream = serialPort.getInputStream();
outputStream = serialPort.getOutputStream();
opened = true;
}
catch(Exception ex) {
opened = false;
logger.error(ex.getMessage() + "\n");
if (serialPort != null)
serialPort.close();
}
}
public void close() {
try {
if (inputStream != null)
inputStream.close();
} catch (IOException e) {
}
try {
if (outputStream != null)
outputStream.close();
} catch (IOException e) {
}
if (serialPort != null)
serialPort.close();
opened = false;
}
public void start() {
ReadWorker w = new ReadWorker();
w.start();
try {
serialPort.addEventListener(this);
}
catch(TooManyListenersException ex) {
ex.printStackTrace();
}
}
public void stop() {
stopping = true;
synchronized (readReadyMonitor) {
readReadyMonitor.notifyAll();
}
synchronized (closeLock) {
try {
if (!stopped)
closeLock.wait();
}
catch(Exception ex) {
}
}
if (serialPort != null)
serialPort.removeEventListener();
}
public boolean isOpened() {
return opened;
}
public boolean isStopping() {
return stopping;
}
public void serialEvent(SerialPortEvent evt) {
if (evt.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
synchronized (readReadyMonitor) {
readReadyMonitor.notifyAll();
}
}
}
private class ReadWorker extends Thread {
public void run() {
synchronized(closeLock) {
try {
stopped = false;
stopping = false;
while(isOpened() && !isStopping()) {
synchronized (readReadyMonitor) {
try {
readReadyMonitor.wait();
} catch (InterruptedException e) {
}
if (isStopping() || !isOpened()) {
break;
}
int dataSize;
try {
dataSize = inputStream.available();
byte[] data = new byte[dataSize];
int readBytes = inputStream.read(data);
long readDataTime = System.currentTimeMillis();
if (readBytes > 0) {
if (getLogger().isDebugEnabled()) {
getLogger().debug(new String(data, 0, readBytes));
}
ByteBuffer buffer = ByteBuffer.wrap(data, 0, readBytes);
buffer.put(data, 0, readBytes);
buffer.flip();
for (;;) {
synchronized(lock) {
if (!queue.isEmpty()) {
WaitResponse response = queue.peek();
if (response.startTime > readDataTime)
break;
int oldRemaining = buffer.remaining();
if (response.response.readResponse(buffer)){
response.response.finish();
queue.poll();
lock.notify();
}
if (buffer.hasRemaining()) {
if (buffer.remaining() >= oldRemaining){
buffer.clear();
break;
}
buffer.compact();
}
else{
buffer.clear();
break;
}
}
else
break;
}
}
}
}
catch(IOException ex) {
}
}
}
}
catch(Exception ex) {
}
finally {
stopped = true;
closeLock.notifyAll();
}
}
}
}
private class WaitResponse {
ATResponse response;
long startTime;
WaitResponse(ATResponse response) {
this.response = response;
}
}
public InputStream getInputStream() {
return inputStream;
}
public void setInputStream(InputStream inputStream) {
this.inputStream = inputStream;
}
public OutputStream getOutputStream() {
return outputStream;
}
public void setOutputStream(OutputStream outputStream) {
this.outputStream = outputStream;
}
public String getApplicationName() {
return applicationName;
}
public void setApplicationName(String applicationName) {
this.applicationName = applicationName;
}
public int getBaudrate() {
return baudrate;
}
public void setBaudrate(int baudrate) {
this.baudrate = baudrate;
}
public int getDataBits() {
return dataBits;
}
public void setDataBits(int dataBits) {
this.dataBits = dataBits;
}
public int getFlowControlMode() {
return flowControlMode;
}
public void setFlowControlMode(int flowControlMode) {
this.flowControlMode = flowControlMode;
}
public int getParity() {
return parity;
}
public void setParity(int parity) {
this.parity = parity;
}
public String getPortName() {
return portName;
}
public void setPortName(String portName) {
this.portName = portName;
}
public int getStopBits() {
return stopBits;
}
public void setStopBits(int stopBits) {
this.stopBits = stopBits;
}
public void setStopping(boolean stopping) {
this.stopping = stopping;
}
public long getDefaultATTimeout() {
return defaultATTimeout;
}
public void setDefaultATTimeout(long defaultATTimeout) {
this.defaultATTimeout = defaultATTimeout;
}
public int getId() {
return id;
}
public void setId(int id) {
loggerName = getClass().getName() + (id == -1 ? "" : id);
this.id = id;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -