diff --git a/protocol-cdt/src/main/java/wei/yigulu/cdt/netty/CDTMaster.java b/protocol-cdt/src/main/java/wei/yigulu/cdt/netty/CDTMaster.java index 7dfcc6aa5343ba7f2e277cf5788ed72651623d8c..6cedc07fe74c23ce90f02e0e4b8998ba124ef8b4 100644 --- a/protocol-cdt/src/main/java/wei/yigulu/cdt/netty/CDTMaster.java +++ b/protocol-cdt/src/main/java/wei/yigulu/cdt/netty/CDTMaster.java @@ -5,6 +5,7 @@ import io.netty.buffer.Unpooled; import io.netty.handler.codec.DelimiterBasedFrameDecoder; import lombok.Getter; import wei.yigulu.cdt.cdtframe.AbstractCDTDataHandler; +import wei.yigulu.jsc.JSerialCommChannel; import wei.yigulu.netty.AbstractRtuModeBuilder; import wei.yigulu.netty.ProtocolChannelInitializer; import wei.yigulu.purejavacomm.PureJavaCommChannel; @@ -32,9 +33,9 @@ public class CDTMaster extends AbstractRtuModeBuilder { @Override protected ProtocolChannelInitializer getOrCreateChannelInitializer() { - return new ProtocolChannelInitializer(this) { + return new ProtocolChannelInitializer(this) { @Override - protected void initChannel(PureJavaCommChannel ch) throws Exception { + protected void initChannel(JSerialCommChannel ch) throws Exception { ch.pipeline().addLast(new DelimiterBasedFrameDecoder(MAXLEN, Unpooled.copiedBuffer(HEAD))); ch.pipeline().addLast(new MasterHandler((CDTMaster) builder)); } diff --git a/protocol-cdt/src/main/java/wei/yigulu/cdt/netty/CDTSlaver.java b/protocol-cdt/src/main/java/wei/yigulu/cdt/netty/CDTSlaver.java index 3be4128314a45928167d3dcccc61989f890fccfe..6fc23794841a00040ad3dcd846a1633bd9557f2a 100644 --- a/protocol-cdt/src/main/java/wei/yigulu/cdt/netty/CDTSlaver.java +++ b/protocol-cdt/src/main/java/wei/yigulu/cdt/netty/CDTSlaver.java @@ -2,6 +2,7 @@ package wei.yigulu.cdt.netty; import lombok.Getter; import wei.yigulu.cdt.cdtframe.AbstractCDTDataTransmitter; +import wei.yigulu.jsc.JSerialCommChannel; import wei.yigulu.netty.AbstractRtuModeBuilder; import wei.yigulu.netty.ProtocolChannelInitializer; import wei.yigulu.purejavacomm.PureJavaCommChannel; @@ -26,10 +27,10 @@ public class CDTSlaver extends AbstractRtuModeBuilder { @Override protected ProtocolChannelInitializer getOrCreateChannelInitializer() { - return new ProtocolChannelInitializer(this) { + return new ProtocolChannelInitializer(this) { @Override - protected void initChannel(PureJavaCommChannel ch) throws Exception { + protected void initChannel(JSerialCommChannel ch) throws Exception { ch.pipeline().addLast(new SlaverHandler((CDTSlaver) builder)); } }; diff --git a/protocol-core/pom.xml b/protocol-core/pom.xml index be90e7b0ae1fc802b23ff0c4739e31a1c628407f..c5f955038d9183ffe97dff1d524c104cb492ad37 100644 --- a/protocol-core/pom.xml +++ b/protocol-core/pom.xml @@ -14,6 +14,12 @@ jar + + + com.fazecast + jSerialComm + 2.9.3 + com.github.purejavacomm diff --git a/protocol-core/src/main/java/wei/yigulu/jsc/DefaultJSerialCommChannelConfig.java b/protocol-core/src/main/java/wei/yigulu/jsc/DefaultJSerialCommChannelConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..385676f4b192801574fb5f29b1479d6ad11379f6 --- /dev/null +++ b/protocol-core/src/main/java/wei/yigulu/jsc/DefaultJSerialCommChannelConfig.java @@ -0,0 +1,219 @@ +/* + * Copyright 2017 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 wei.yigulu.jsc; + +import io.netty.buffer.ByteBufAllocator; +import io.netty.channel.ChannelOption; +import io.netty.channel.DefaultChannelConfig; +import io.netty.channel.MessageSizeEstimator; +import io.netty.channel.RecvByteBufAllocator; + +import java.util.Map; + +/** + * Default configuration class for jSerialComm device connections. + */ +final class DefaultJSerialCommChannelConfig extends DefaultChannelConfig implements JSerialCommChannelConfig { + + private volatile int baudrate = 115200; + private volatile Stopbits stopbits = Stopbits.STOPBITS_1; + private volatile Databits databits = Databits.DATABITS_8; + private volatile Paritybit paritybit = Paritybit.NONE; + private volatile int waitTime; + private volatile int readTimeout = 1000; + + DefaultJSerialCommChannelConfig(JSerialCommChannel channel) { + super(channel); + } + + @Override + public Map, Object> getOptions() { + return getOptions(super.getOptions(), JSerialCommChannelOption.BAUD_RATE, JSerialCommChannelOption.STOP_BITS, JSerialCommChannelOption.DATA_BITS, JSerialCommChannelOption.PARITY_BIT, JSerialCommChannelOption.WAIT_TIME); + } + + @SuppressWarnings("unchecked") + @Override + public T getOption(ChannelOption option) { + if (option == JSerialCommChannelOption.BAUD_RATE) { + return (T) Integer.valueOf(getBaudrate()); + } + if (option == JSerialCommChannelOption.STOP_BITS) { + return (T) getStopbits(); + } + if (option == JSerialCommChannelOption.DATA_BITS) { + return (T) getDatabits(); + } + if (option == JSerialCommChannelOption.PARITY_BIT) { + return (T) getParitybit(); + } + if (option == JSerialCommChannelOption.WAIT_TIME) { + return (T) Integer.valueOf(getWaitTimeMillis()); + } + if (option == JSerialCommChannelOption.READ_TIMEOUT) { + return (T) Integer.valueOf(getReadTimeout()); + } + return super.getOption(option); + } + + @Override + public boolean setOption(ChannelOption option, T value) { + validate(option, value); + + if (option == JSerialCommChannelOption.BAUD_RATE) { + setBaudrate((Integer) value); + } else if (option == JSerialCommChannelOption.STOP_BITS) { + setStopbits((Stopbits) value); + } else if (option == JSerialCommChannelOption.DATA_BITS) { + setDatabits((Databits) value); + } else if (option == JSerialCommChannelOption.PARITY_BIT) { + setParitybit((Paritybit) value); + } else if (option == JSerialCommChannelOption.WAIT_TIME) { + setWaitTimeMillis((Integer) value); + } else if (option == JSerialCommChannelOption.READ_TIMEOUT) { + setReadTimeout((Integer) value); + } else { + return super.setOption(option, value); + } + return true; + } + + @Override + public JSerialCommChannelConfig setBaudrate(final int baudrate) { + this.baudrate = baudrate; + return this; + } + + @Override + public JSerialCommChannelConfig setStopbits(final Stopbits stopbits) { + this.stopbits = stopbits; + return this; + } + + @Override + public JSerialCommChannelConfig setDatabits(final Databits databits) { + this.databits = databits; + return this; + } + + @Override + public JSerialCommChannelConfig setParitybit(final Paritybit paritybit) { + this.paritybit = paritybit; + return this; + } + + @Override + public int getBaudrate() { + return baudrate; + } + + @Override + public Stopbits getStopbits() { + return stopbits; + } + + @Override + public Databits getDatabits() { + return databits; + } + + @Override + public Paritybit getParitybit() { + return paritybit; + } + + + @Override + public int getWaitTimeMillis() { + return waitTime; + } + + @Override + public JSerialCommChannelConfig setWaitTimeMillis(final int waitTimeMillis) { + if (waitTimeMillis < 0) { + throw new IllegalArgumentException("Wait time must be >= 0"); + } + waitTime = waitTimeMillis; + return this; + } + + @Override + public JSerialCommChannelConfig setReadTimeout(int readTimeout) { + if (readTimeout < 0) { + throw new IllegalArgumentException("readTime must be >= 0"); + } + this.readTimeout = readTimeout; + return this; + } + + @Override + public int getReadTimeout() { + return readTimeout; + } + + @Override + public JSerialCommChannelConfig setConnectTimeoutMillis(int connectTimeoutMillis) { + super.setConnectTimeoutMillis(connectTimeoutMillis); + return this; + } + + @Override + public JSerialCommChannelConfig setWriteSpinCount(int writeSpinCount) { + super.setWriteSpinCount(writeSpinCount); + return this; + } + + @Override + public JSerialCommChannelConfig setAllocator(ByteBufAllocator allocator) { + super.setAllocator(allocator); + return this; + } + + @Override + public JSerialCommChannelConfig setRecvByteBufAllocator(RecvByteBufAllocator allocator) { + super.setRecvByteBufAllocator(allocator); + return this; + } + + @Override + public JSerialCommChannelConfig setAutoRead(boolean autoRead) { + super.setAutoRead(autoRead); + return this; + } + + @Override + public JSerialCommChannelConfig setAutoClose(boolean autoClose) { + super.setAutoClose(autoClose); + return this; + } + + @Override + public JSerialCommChannelConfig setWriteBufferHighWaterMark(int writeBufferHighWaterMark) { + super.setWriteBufferHighWaterMark(writeBufferHighWaterMark); + return this; + } + + @Override + public JSerialCommChannelConfig setWriteBufferLowWaterMark(int writeBufferLowWaterMark) { + super.setWriteBufferLowWaterMark(writeBufferLowWaterMark); + return this; + } + + @Override + public JSerialCommChannelConfig setMessageSizeEstimator(MessageSizeEstimator estimator) { + super.setMessageSizeEstimator(estimator); + return this; + } +} diff --git a/protocol-core/src/main/java/wei/yigulu/jsc/JSerialCommChannel.java b/protocol-core/src/main/java/wei/yigulu/jsc/JSerialCommChannel.java new file mode 100644 index 0000000000000000000000000000000000000000..45ebcac509901d5cf8ca6f0a3bc8efdb8607dd8d --- /dev/null +++ b/protocol-core/src/main/java/wei/yigulu/jsc/JSerialCommChannel.java @@ -0,0 +1,218 @@ +/* + * Copyright 2017 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 wei.yigulu.jsc; + +import com.fazecast.jSerialComm.SerialPort; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelPromise; +import io.netty.channel.RecvByteBufAllocator; +import io.netty.channel.oio.OioByteStreamChannel; + +import java.io.IOException; +import java.io.InputStream; +import java.net.SocketAddress; +import java.util.concurrent.TimeUnit; + + +/** + * A channel to a serial device using the jSerialComm library. + */ +public class JSerialCommChannel extends OioByteStreamChannel { + + private static final JSerialCommDeviceAddress LOCAL_ADDRESS = new JSerialCommDeviceAddress("localhost"); + + private final JSerialCommChannelConfig config; + + private boolean open = true; + private JSerialCommDeviceAddress deviceAddress; + private SerialPort serialPort; + + private InputStream is; + + public JSerialCommChannel() { + super(null); + + config = new DefaultJSerialCommChannelConfig(this); + } + + @Override + public JSerialCommChannelConfig config() { + return config; + } + + @Override + public boolean isOpen() { + return open; + } + + @Override + protected AbstractUnsafe newUnsafe() { + return new JSCUnsafe(); + } + + /** + * 重载doReadBytes函数,捕获因为串口没有数据读取,buf.writeBytes操作产生异常 + * Netty的默认处理是关闭连接 + * 此处理不妥,很多时候串口不一定有心跳数据,很长时间也不一定有数据,但是也不能关闭连接 + * 此处自定义JSerialCommReadTimeoutException,将该异常抛出到串口应用程序,然后依据业务实际情况进行处理 + * @param buf + * @return + * @throws Exception + */ + @Override + protected int doReadBytes(ByteBuf buf) throws Exception { + final RecvByteBufAllocator.Handle allocHandle = unsafe().recvBufAllocHandle(); + allocHandle.attemptedBytesRead(Math.max(1, Math.min(available(), buf.maxWritableBytes()))); + + is=serialPort.getInputStream(); + int i=allocHandle.attemptedBytesRead(); + try { + return buf.writeBytes(is, i); + } + catch (IOException io) + { + //串口在给定时间内没数据读取 + //抛出自定义串口读取超时异常处理异常JSerialCommReadTimeoutException +// throw new JSerialCommReadTimeoutException("The Serial read operation timed out before any data was returned"); + return 0; + } + } + + @Override + protected void doConnect(SocketAddress remoteAddress, SocketAddress localAddress) throws Exception { + JSerialCommDeviceAddress remote = (JSerialCommDeviceAddress) remoteAddress; + SerialPort commPort = SerialPort.getCommPort(remote.value()); + if (!commPort.openPort()) { + throw new IOException("Could not open port: " + remote.value()); + } + + commPort.setComPortTimeouts( + SerialPort.TIMEOUT_READ_BLOCKING, config().getOption(JSerialCommChannelOption.READ_TIMEOUT), 0); + + deviceAddress = remote; + serialPort = commPort; + } + + protected void doInit() throws Exception { + serialPort.setComPortParameters( + config().getOption(JSerialCommChannelOption.BAUD_RATE), + config().getOption(JSerialCommChannelOption.DATA_BITS).value(), + config().getOption(JSerialCommChannelOption.STOP_BITS).value(), + config().getOption(JSerialCommChannelOption.PARITY_BIT).value() + ); + + activate(serialPort.getInputStream(), serialPort.getOutputStream()); + } + + @Override + public JSerialCommDeviceAddress localAddress() { + return (JSerialCommDeviceAddress) super.localAddress(); + } + + @Override + public JSerialCommDeviceAddress remoteAddress() { + return (JSerialCommDeviceAddress) super.remoteAddress(); + } + + @Override + protected JSerialCommDeviceAddress localAddress0() { + return LOCAL_ADDRESS; + } + + @Override + protected JSerialCommDeviceAddress remoteAddress0() { + 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; + try { + super.doClose(); + } finally { + if (serialPort != null) { + serialPort.closePort(); + serialPort = null; + } + } + } + + @Override + protected boolean isInputShutdown() { + return !open; + } + + @Override + protected ChannelFuture shutdownInput() { + return newFailedFuture(new UnsupportedOperationException("shutdownInput")); + } + + + private final class JSCUnsafe extends AbstractUnsafe { + @Override + public void connect( + final SocketAddress remoteAddress, + final SocketAddress localAddress, final ChannelPromise promise) { + if (!promise.setUncancellable() || !isOpen()) { + return; + } + + try { + final boolean wasActive = isActive(); + doConnect(remoteAddress, localAddress); + + int waitTime = config().getOption(JSerialCommChannelOption.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(); + } + } + } +} diff --git a/protocol-core/src/main/java/wei/yigulu/jsc/JSerialCommChannelConfig.java b/protocol-core/src/main/java/wei/yigulu/jsc/JSerialCommChannelConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..65d575714f84fdaeeb6a8b75e94824daec09ac65 --- /dev/null +++ b/protocol-core/src/main/java/wei/yigulu/jsc/JSerialCommChannelConfig.java @@ -0,0 +1,268 @@ +/* + * Copyright 2017 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 wei.yigulu.jsc; + +import com.fazecast.jSerialComm.SerialPort; +import io.netty.buffer.ByteBufAllocator; +import io.netty.channel.ChannelConfig; +import io.netty.channel.MessageSizeEstimator; +import io.netty.channel.RecvByteBufAllocator; +import wei.yigulu.purejavacomm.PureJavaCommChannelConfig; + +/** + * A configuration class for JSerialComm device connections. + * + *

Available options

+ * + * In addition to the options provided by {@link ChannelConfig}, + * {@link DefaultJSerialCommChannelConfig} allows the following options in the option map: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
NameAssociated setter method
{@link JSerialCommChannelOption#BAUD_RATE}{@link #setBaudrate(int)}
{@link JSerialCommChannelOption#STOP_BITS}{@link #setStopbits(Stopbits)}
{@link JSerialCommChannelOption#DATA_BITS}{@link #setDatabits(int)}
{@link JSerialCommChannelOption#PARITY_BIT}{@link #setParitybit(Paritybit)}
{@link JSerialCommChannelOption#WAIT_TIME}{@link #setWaitTimeMillis(int)}
+ */ +public interface JSerialCommChannelConfig extends ChannelConfig { + enum Stopbits { + /** + * 1 stop bit will be sent at the end of every character + */ + STOPBITS_1(SerialPort.ONE_STOP_BIT), + /** + * 2 stop bits will be sent at the end of every character + */ + STOPBITS_2(SerialPort.TWO_STOP_BITS), + /** + * 1.5 stop bits will be sent at the end of every character + */ + STOPBITS_1_5(SerialPort.ONE_POINT_FIVE_STOP_BITS); + + private final int value; + + Stopbits(int value) { + this.value = value; + } + + public int value() { + return value; + } + + public static Stopbits valueOf(int value) { + for (Stopbits stopbit : Stopbits.values()) { + if (stopbit.value == value) { + return stopbit; + } + } + throw new IllegalArgumentException("unknown " + Stopbits.class.getSimpleName() + " value: " + value); + } + } + + enum Paritybit { + /** + * No parity bit will be sent with each data character at all + */ + NONE(SerialPort.NO_PARITY), + /** + * An odd parity bit will be sent with each data character, ie. will be set + * to 1 if the data character contains an even number of bits set to 1. + */ + ODD(SerialPort.ODD_PARITY), + /** + * An even parity bit will be sent with each data character, ie. will be set + * to 1 if the data character contains an odd number of bits set to 1. + */ + EVEN(SerialPort.EVEN_PARITY), + /** + * A mark parity bit (ie. always 1) will be sent with each data character + */ + MARK(SerialPort.MARK_PARITY), + /** + * A space parity bit (ie. always 0) will be sent with each data character + */ + SPACE(SerialPort.SPACE_PARITY); + + private final int value; + + Paritybit(int value) { + this.value = value; + } + + public int value() { + return value; + } + + public static Paritybit valueOf(int value) { + for (Paritybit paritybit : Paritybit.values()) { + if (paritybit.value == value) { + return paritybit; + } + } + throw new IllegalArgumentException("unknown " + Paritybit.class.getSimpleName() + " value: " + value); + } + } + + enum Databits { + /** + * 5 data bits will be used for each character (ie. Baudot code) + */ + DATABITS_5(purejavacomm.SerialPort.DATABITS_5), + /** + * 6 data bits will be used for each character + */ + DATABITS_6(purejavacomm.SerialPort.DATABITS_6), + /** + * 7 data bits will be used for each character (ie. ASCII) + */ + DATABITS_7(purejavacomm.SerialPort.DATABITS_7), + /** + * 8 data bits will be used for each character (ie. binary data) + */ + DATABITS_8(purejavacomm.SerialPort.DATABITS_8); + + private final int value; + + Databits(int value) { + this.value = value; + } + + public int value() { + return value; + } + + public static Databits valueOf(int value) { + for (Databits databit : Databits.values()) { + if (databit.value == value) { + return databit; + } + } + throw new IllegalArgumentException("unknown " + PureJavaCommChannelConfig.Databits.class.getSimpleName() + " value: " + value); + } + } + + /** + * Sets the baud rate (ie. bits per second) for communication with the serial device. + * The baud rate will include bits for framing (in the form of stop bits and parity), + * such that the effective data rate will be lower than this value. + * + * @param baudrate The baud rate (in bits per second) + */ + JSerialCommChannelConfig setBaudrate(int baudrate); + + /** + * Sets the number of stop bits to include at the end of every character to aid the + * serial device in synchronising with the data. + * + * @param stopbits The number of stop bits to use + */ + JSerialCommChannelConfig setStopbits(Stopbits stopbits); + + /** + * Sets the number of data bits to use to make up each character sent to the serial + * device. + * + * @param databits The number of data bits to use + */ + JSerialCommChannelConfig setDatabits(Databits databits); + + /** + * Sets the type of parity bit to be used when communicating with the serial device. + * + * @param paritybit The type of parity bit to be used + */ + JSerialCommChannelConfig setParitybit(Paritybit paritybit); + + /** + * @return The configured baud rate, defaulting to 115200 if unset + */ + int getBaudrate(); + + /** + * @return The configured stop bits, defaulting to {@link Stopbits#STOPBITS_1} if unset + */ + Stopbits getStopbits(); + + /** + * @return The configured data bits, defaulting to 8 if unset + */ + Databits getDatabits(); + + /** + * @return The configured parity bit, defaulting to {@link Paritybit#NONE} if unset + */ + Paritybit getParitybit(); + + /** + * @return The number of milliseconds to wait between opening the serial port and + * initialising. + */ + int getWaitTimeMillis(); + + /** + * Sets the time to wait after opening the serial port and before sending it any + * configuration information or data. A value of 0 indicates that no waiting should + * occur. + * + * @param waitTimeMillis The number of milliseconds to wait, defaulting to 0 (no + * wait) if unset + * @throws IllegalArgumentException if the supplied value is < 0 + */ + JSerialCommChannelConfig setWaitTimeMillis(int waitTimeMillis); + + /** + * Sets the maximal time (in ms) to block while try to read from the serial port. Default is 1000ms + */ + JSerialCommChannelConfig setReadTimeout(int readTimeout); + + /** + * Return the maximal time (in ms) to block and wait for something to be ready to read. + */ + int getReadTimeout(); + + @Override + JSerialCommChannelConfig setConnectTimeoutMillis(int connectTimeoutMillis); + + @Override + JSerialCommChannelConfig setWriteSpinCount(int writeSpinCount); + + @Override + JSerialCommChannelConfig setAllocator(ByteBufAllocator allocator); + + @Override + JSerialCommChannelConfig setRecvByteBufAllocator(RecvByteBufAllocator allocator); + + @Override + JSerialCommChannelConfig setAutoRead(boolean autoRead); + + @Override + JSerialCommChannelConfig setWriteBufferHighWaterMark(int writeBufferHighWaterMark); + + @Override + JSerialCommChannelConfig setWriteBufferLowWaterMark(int writeBufferLowWaterMark); + + @Override + JSerialCommChannelConfig setMessageSizeEstimator(MessageSizeEstimator estimator); +} diff --git a/protocol-core/src/main/java/wei/yigulu/jsc/JSerialCommChannelOption.java b/protocol-core/src/main/java/wei/yigulu/jsc/JSerialCommChannelOption.java new file mode 100644 index 0000000000000000000000000000000000000000..791ca73d3476f7b08b805e3f9e1c797df16c91b0 --- /dev/null +++ b/protocol-core/src/main/java/wei/yigulu/jsc/JSerialCommChannelOption.java @@ -0,0 +1,39 @@ +/* + * Copyright 2017 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 wei.yigulu.jsc; + +import io.netty.channel.ChannelOption; +import wei.yigulu.jsc.JSerialCommChannelConfig.Databits; +import wei.yigulu.jsc.JSerialCommChannelConfig.Paritybit; +import wei.yigulu.jsc.JSerialCommChannelConfig.Stopbits; + +/** + * Option for configuring a serial port connection + */ +public final class JSerialCommChannelOption extends ChannelOption { + + public static final ChannelOption BAUD_RATE = valueOf("BAUD_RATE"); + public static final ChannelOption STOP_BITS = valueOf("STOP_BITS"); + public static final ChannelOption DATA_BITS = valueOf("DATA_BITS"); + public static final ChannelOption PARITY_BIT = valueOf("PARITY_BIT"); + public static final ChannelOption WAIT_TIME = valueOf("WAIT_TIME"); + public static final ChannelOption READ_TIMEOUT = valueOf("READ_TIMEOUT"); + + @SuppressWarnings({ "unused", "deprecation" }) + private JSerialCommChannelOption() { + super(null); + } +} diff --git a/protocol-core/src/main/java/wei/yigulu/jsc/JSerialCommDeviceAddress.java b/protocol-core/src/main/java/wei/yigulu/jsc/JSerialCommDeviceAddress.java new file mode 100644 index 0000000000000000000000000000000000000000..867becd472dd1241af4068a387ff1a81a41277ce --- /dev/null +++ b/protocol-core/src/main/java/wei/yigulu/jsc/JSerialCommDeviceAddress.java @@ -0,0 +1,45 @@ +/* + * Copyright 2017 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 wei.yigulu.jsc; + +import java.net.SocketAddress; + +/** + * A {@link SocketAddress} subclass to wrap the serial port address of a jSerialComm + * device (e.g. COM1, /dev/ttyUSB0). + */ +public class JSerialCommDeviceAddress extends SocketAddress { + + private static final long serialVersionUID = -2907820090993709523L; + + private final String value; + + /** + * Creates a JSerialCommDeviceAddress representing the address of the serial port. + * + * @param value the address of the device (e.g. COM1, /dev/ttyUSB0, ...) + */ + public JSerialCommDeviceAddress(String value) { + this.value = value; + } + + /** + * @return The serial port address of the device (e.g. COM1, /dev/ttyUSB0, ...) + */ + public String value() { + return value; + } +} diff --git a/protocol-core/src/main/java/wei/yigulu/jsc/JSerialCommReadTimeoutException.java b/protocol-core/src/main/java/wei/yigulu/jsc/JSerialCommReadTimeoutException.java new file mode 100644 index 0000000000000000000000000000000000000000..18c5c6e584b7c091505fd088e10281178a0dceee --- /dev/null +++ b/protocol-core/src/main/java/wei/yigulu/jsc/JSerialCommReadTimeoutException.java @@ -0,0 +1,10 @@ +package wei.yigulu.jsc; + +public class JSerialCommReadTimeoutException extends RuntimeException{ + public JSerialCommReadTimeoutException(){ + + } + public JSerialCommReadTimeoutException(String msg){ + super(msg); + } +} diff --git a/protocol-modbus/src/main/java/wei/yigulu/modbus/netty/ModbusRtuMasterBuilder.java b/protocol-modbus/src/main/java/wei/yigulu/modbus/netty/ModbusRtuMasterBuilder.java index c594035307c05e6d1b477ec068c76b0c213831f9..a10df16207ffd4daeb8b0b83097e440f7d251ab7 100644 --- a/protocol-modbus/src/main/java/wei/yigulu/modbus/netty/ModbusRtuMasterBuilder.java +++ b/protocol-modbus/src/main/java/wei/yigulu/modbus/netty/ModbusRtuMasterBuilder.java @@ -2,6 +2,7 @@ package wei.yigulu.modbus.netty; import lombok.experimental.Accessors; import lombok.extern.slf4j.Slf4j; +import wei.yigulu.jsc.JSerialCommChannel; import wei.yigulu.modbus.domain.synchronouswaitingroom.RtuSynchronousWaitingRoom; import wei.yigulu.modbus.domain.synchronouswaitingroom.SynchronousWaitingRoom; import wei.yigulu.modbus.exceptiom.ModbusException; @@ -38,9 +39,9 @@ public class ModbusRtuMasterBuilder extends AbstractRtuModeBuilder implements Mo @Override protected ProtocolChannelInitializer getOrCreateChannelInitializer() { if (this.channelInitializer == null) { - this.channelInitializer = new ProtocolChannelInitializer(this) { + this.channelInitializer = new ProtocolChannelInitializer(this) { @Override - protected void initChannel(PureJavaCommChannel ch) throws Exception { + protected void initChannel(JSerialCommChannel ch) throws Exception { ch.pipeline().addLast(new ModbusRtuMasterDelimiterHandler().setLog(getLog())); ch.pipeline().addLast(new ModbusRtuMasterHandler((ModbusRtuMasterBuilder) builder)); } diff --git a/protocol-modbus/src/main/java/wei/yigulu/modbus/netty/ModbusRtuSlaverBuilder.java b/protocol-modbus/src/main/java/wei/yigulu/modbus/netty/ModbusRtuSlaverBuilder.java index 2edba77990e5cf7c1a3a2216c24c2f3296004df2..5aeb7f411dc43b639b6dae9684a6e98c5ce2c45e 100644 --- a/protocol-modbus/src/main/java/wei/yigulu/modbus/netty/ModbusRtuSlaverBuilder.java +++ b/protocol-modbus/src/main/java/wei/yigulu/modbus/netty/ModbusRtuSlaverBuilder.java @@ -3,6 +3,7 @@ package wei.yigulu.modbus.netty; import lombok.Getter; import lombok.experimental.Accessors; +import wei.yigulu.jsc.JSerialCommChannel; import wei.yigulu.modbus.domain.ModbusSlaveDataContainer; import wei.yigulu.modbus.domain.command.AbstractModbusCommand; import wei.yigulu.netty.AbstractRtuModeBuilder; @@ -34,9 +35,9 @@ public class ModbusRtuSlaverBuilder extends AbstractRtuModeBuilder implements Mo @Override protected ProtocolChannelInitializer getOrCreateChannelInitializer() { if (this.channelInitializer == null) { - this.channelInitializer = new ProtocolChannelInitializer(this) { + this.channelInitializer = new ProtocolChannelInitializer(this) { @Override - protected void initChannel(PureJavaCommChannel ch) throws Exception { + protected void initChannel(JSerialCommChannel ch) throws Exception { ch.pipeline().addLast(new ModbusRtuSlaverDelimiterHandler().setLog(getLog())); ch.pipeline().addLast(new ModbusRtuSlaverHandler((ModbusRtuSlaverBuilder) builder)); }