netty5/transport-rxtx/src/main/java/io/netty/channel/rxtx/RxtxChannel.java

175 lines
5.3 KiB
Java
Raw Normal View History

2013-01-09 11:40:38 +01:00
/*
* Copyright 2013 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package io.netty.channel.rxtx;
2013-01-09 11:40:38 +01:00
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import io.netty.channel.ChannelPromise;
import io.netty.channel.oio.OioByteStreamChannel;
2013-01-09 11:40:38 +01:00
import java.net.SocketAddress;
import java.util.concurrent.TimeUnit;
2013-01-09 11:40:38 +01:00
import static io.netty.channel.rxtx.RxtxChannelOption.*;
2013-01-09 11:40:38 +01:00
/**
* A channel to a serial device using the RXTX library.
*/
public class RxtxChannel extends OioByteStreamChannel {
private static final RxtxDeviceAddress LOCAL_ADDRESS = new RxtxDeviceAddress("localhost");
2013-01-09 11:40:38 +01:00
private final RxtxChannelConfig config;
2013-01-09 11:40:38 +01:00
private boolean open = true;
2013-01-09 11:40:38 +01:00
private RxtxDeviceAddress deviceAddress;
private SerialPort serialPort;
public RxtxChannel() {
super(null);
2013-01-09 11:40:38 +01:00
config = new DefaultRxtxChannelConfig(this);
2013-01-09 11:40:38 +01:00
}
@Override
public RxtxChannelConfig config() {
2013-01-09 11:40:38 +01:00
return config;
}
@Override
public boolean isOpen() {
return open;
2013-01-09 11:40:38 +01:00
}
@Override
protected AbstractUnsafe newUnsafe() {
return new RxtxUnsafe();
}
2013-01-09 11:40:38 +01:00
@Override
protected void doConnect(SocketAddress remoteAddress, SocketAddress localAddress) throws Exception {
RxtxDeviceAddress remote = (RxtxDeviceAddress) remoteAddress;
2013-01-17 07:06:46 +01:00
final CommPortIdentifier cpi = CommPortIdentifier.getPortIdentifier(remote.value());
2013-01-09 11:40:38 +01:00
final CommPort commPort = cpi.open(getClass().getName(), 1000);
commPort.enableReceiveTimeout(config().getOption(READ_TIMEOUT));
2013-01-09 11:40:38 +01:00
deviceAddress = remote;
serialPort = (SerialPort) commPort;
}
protected void doInit() throws Exception {
2013-01-09 11:40:38 +01:00
serialPort.setSerialPortParams(
config().getOption(BAUD_RATE),
config().getOption(DATA_BITS).value(),
config().getOption(STOP_BITS).value(),
config().getOption(PARITY_BIT).value()
2013-01-09 11:40:38 +01:00
);
serialPort.setDTR(config().getOption(DTR));
serialPort.setRTS(config().getOption(RTS));
activate(serialPort.getInputStream(), serialPort.getOutputStream());
2013-01-09 11:40:38 +01:00
}
@Override
public RxtxDeviceAddress localAddress() {
return (RxtxDeviceAddress) super.localAddress();
}
@Override
public RxtxDeviceAddress remoteAddress() {
return (RxtxDeviceAddress) super.remoteAddress();
2013-01-09 11:40:38 +01:00
}
@Override
protected RxtxDeviceAddress localAddress0() {
return LOCAL_ADDRESS;
}
@Override
protected RxtxDeviceAddress remoteAddress0() {
2013-01-09 11:40:38 +01:00
return deviceAddress;
}
@Override
protected void doBind(SocketAddress localAddress) throws Exception {
throw new UnsupportedOperationException();
}
@Override
protected void doDisconnect() throws Exception {
doClose();
}
@Override
protected void doClose() throws Exception {
open = false;
2013-01-09 11:40:38 +01:00
try {
super.doClose();
} finally {
if (serialPort != null) {
serialPort.removeEventListener();
serialPort.close();
serialPort = null;
2013-01-09 11:40:38 +01:00
}
}
}
private final class RxtxUnsafe extends AbstractUnsafe {
@Override
public void connect(
final SocketAddress remoteAddress,
final SocketAddress localAddress, final ChannelPromise promise) {
if (!promise.setUncancellable() || !ensureOpen(promise)) {
return;
}
try {
final boolean wasActive = isActive();
doConnect(remoteAddress, localAddress);
int waitTime = config().getOption(WAIT_TIME);
if (waitTime > 0) {
eventLoop().schedule(new Runnable() {
@Override
public void run() {
try {
doInit();
safeSetSuccess(promise);
if (!wasActive && isActive()) {
pipeline().fireChannelActive();
}
} catch (Throwable t) {
safeSetFailure(promise, t);
closeIfClosed();
}
}
}, waitTime, TimeUnit.MILLISECONDS);
} else {
doInit();
safeSetSuccess(promise);
if (!wasActive && isActive()) {
pipeline().fireChannelActive();
}
}
} catch (Throwable t) {
safeSetFailure(promise, t);
closeIfClosed();
}
}
}
2013-01-09 11:40:38 +01:00
}