1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.channel.rxtx;
17
18 import gnu.io.CommPort;
19 import gnu.io.CommPortIdentifier;
20 import gnu.io.SerialPort;
21 import io.netty.channel.ChannelFuture;
22 import io.netty.channel.ChannelPromise;
23 import io.netty.channel.oio.OioByteStreamChannel;
24
25 import java.net.SocketAddress;
26 import java.util.concurrent.TimeUnit;
27
28 import static io.netty.channel.rxtx.RxtxChannelOption.BAUD_RATE;
29 import static io.netty.channel.rxtx.RxtxChannelOption.DATA_BITS;
30 import static io.netty.channel.rxtx.RxtxChannelOption.DTR;
31 import static io.netty.channel.rxtx.RxtxChannelOption.PARITY_BIT;
32 import static io.netty.channel.rxtx.RxtxChannelOption.READ_TIMEOUT;
33 import static io.netty.channel.rxtx.RxtxChannelOption.RTS;
34 import static io.netty.channel.rxtx.RxtxChannelOption.STOP_BITS;
35 import static io.netty.channel.rxtx.RxtxChannelOption.WAIT_TIME;
36
37
38
39
40
41
42 @Deprecated
43 public class RxtxChannel extends OioByteStreamChannel {
44
45 private static final RxtxDeviceAddress LOCAL_ADDRESS = new RxtxDeviceAddress("localhost");
46
47 private final RxtxChannelConfig config;
48
49 private boolean open = true;
50 private RxtxDeviceAddress deviceAddress;
51 private SerialPort serialPort;
52
53 public RxtxChannel() {
54 super(null);
55
56 config = new DefaultRxtxChannelConfig(this);
57 }
58
59 @Override
60 public RxtxChannelConfig config() {
61 return config;
62 }
63
64 @Override
65 public boolean isOpen() {
66 return open;
67 }
68
69 @Override
70 protected AbstractUnsafe newUnsafe() {
71 return new RxtxUnsafe();
72 }
73
74 @Override
75 protected void doConnect(SocketAddress remoteAddress, SocketAddress localAddress) throws Exception {
76 RxtxDeviceAddress remote = (RxtxDeviceAddress) remoteAddress;
77 final CommPortIdentifier cpi = CommPortIdentifier.getPortIdentifier(remote.value());
78 final CommPort commPort = cpi.open(getClass().getName(), 1000);
79 commPort.enableReceiveTimeout(config().getOption(READ_TIMEOUT));
80 deviceAddress = remote;
81
82 serialPort = (SerialPort) commPort;
83 }
84
85 protected void doInit() throws Exception {
86 serialPort.setSerialPortParams(
87 config().getOption(BAUD_RATE),
88 config().getOption(DATA_BITS).value(),
89 config().getOption(STOP_BITS).value(),
90 config().getOption(PARITY_BIT).value()
91 );
92 serialPort.setDTR(config().getOption(DTR));
93 serialPort.setRTS(config().getOption(RTS));
94
95 activate(serialPort.getInputStream(), serialPort.getOutputStream());
96 }
97
98 @Override
99 public RxtxDeviceAddress localAddress() {
100 return (RxtxDeviceAddress) super.localAddress();
101 }
102
103 @Override
104 public RxtxDeviceAddress remoteAddress() {
105 return (RxtxDeviceAddress) super.remoteAddress();
106 }
107
108 @Override
109 protected RxtxDeviceAddress localAddress0() {
110 return LOCAL_ADDRESS;
111 }
112
113 @Override
114 protected RxtxDeviceAddress remoteAddress0() {
115 return deviceAddress;
116 }
117
118 @Override
119 protected void doBind(SocketAddress localAddress) throws Exception {
120 throw new UnsupportedOperationException();
121 }
122
123 @Override
124 protected void doDisconnect() throws Exception {
125 doClose();
126 }
127
128 @Override
129 protected void doClose() throws Exception {
130 open = false;
131 try {
132 super.doClose();
133 } finally {
134 if (serialPort != null) {
135 serialPort.removeEventListener();
136 serialPort.close();
137 serialPort = null;
138 }
139 }
140 }
141
142 @Override
143 protected boolean isInputShutdown() {
144 return !open;
145 }
146
147 @Override
148 protected ChannelFuture shutdownInput() {
149 return newFailedFuture(new UnsupportedOperationException("shutdownInput"));
150 }
151
152 private final class RxtxUnsafe extends AbstractUnsafe {
153 @Override
154 public void connect(
155 final SocketAddress remoteAddress,
156 final SocketAddress localAddress, final ChannelPromise promise) {
157 if (!promise.setUncancellable() || !ensureOpen(promise)) {
158 return;
159 }
160
161 try {
162 final boolean wasActive = isActive();
163 doConnect(remoteAddress, localAddress);
164
165 int waitTime = config().getOption(WAIT_TIME);
166 if (waitTime > 0) {
167 eventLoop().schedule(new Runnable() {
168 @Override
169 public void run() {
170 try {
171 doInit();
172 safeSetSuccess(promise);
173 if (!wasActive && isActive()) {
174 pipeline().fireChannelActive();
175 }
176 } catch (Throwable t) {
177 safeSetFailure(promise, t);
178 closeIfClosed();
179 }
180 }
181 }, waitTime, TimeUnit.MILLISECONDS);
182 } else {
183 doInit();
184 safeSetSuccess(promise);
185 if (!wasActive && isActive()) {
186 pipeline().fireChannelActive();
187 }
188 }
189 } catch (Throwable t) {
190 safeSetFailure(promise, t);
191 closeIfClosed();
192 }
193 }
194 }
195 }