package org.openmuc.framework.driver.modbus.rtutcp.bonino;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import net.wimpi.modbus.Modbus;
import net.wimpi.modbus.io.ModbusTransport;
/**
* @author bonino
*
* https://github.com/dog-gateway/jamod-rtu-over-tcp
*
*/
public class RTUTCPMasterConnection implements MasterConnection {
// the log identifier
public static final String logId = "[RTUTCPMasterConnection]: ";
// the socket upon which sending/receiveing Modbus RTU data
private Socket socket;
// the timeout for the socket
private int socketTimeout = Modbus.DEFAULT_TIMEOUT;
// a flag for detecting if the connection is up or not
private boolean connected;
// the ip address of the remote slave
private InetAddress slaveIPAddress;
// the port to which connect on the remote slave
private int slaveIPPort;
// private int retries = Modbus.DEFAULT_RETRIES;
// the RTU over TCP transport
private ModbusRTUTCPTransport modbusRTUTCPTransport;
/**
* Constructs an {@link RTUTCPMasterConnection} instance with a given destination address and port. It permits to
* handle Modbus RTU over TCP connections in a way similar to standard Modbus/TCP connections
*
* @param adr
* the destination IP addres as an {@link InetAddress} instance.
* @param port
* the port to which connect on the destination address.
*/
public RTUTCPMasterConnection(InetAddress adr, int port) {
// store the IP address of the destination
this.slaveIPAddress = adr;
// store the port of the destination
this.slaveIPPort = port;
}
/**
* Opens the RTU over TCP connection represented by this object.
*
* @throws Exception
* if the connection cannot be open (e.g., due to a network failure).
*/
@Override
public synchronized void connect() throws Exception {
// if not connected, try to connect
if (!this.connected) {
// handle debug...(TODO: logging?)
if (Modbus.debug) {
System.out.println(RTUTCPMasterConnection.logId + "connecting...)");
}
// create a socket towards the remote slave
this.socket = new Socket(this.slaveIPAddress, this.slaveIPPort);
// set the socket timeout
setTimeout(this.socketTimeout);
// prepare the RTU over TCP transport to handle communications
prepareTransport();
// set the connected flag at true
connected = true;
// handle debug...(TODO: logging?)
if (Modbus.debug) {
System.out.println(RTUTCPMasterConnection.logId + "successfully connected)");
}
}
}// connect
/**
* Closes the RTU over TCP connection represented by this object.
*/
@Override
public void close() {
// if connected... disconnect, otherwise do nothing
if (this.connected) {
// try closing the transport...
try {
this.modbusRTUTCPTransport.close();
} catch (IOException e) {
// handle debug...(TODO: logging?)
if (Modbus.debug) {
System.out
.println(RTUTCPMasterConnection.logId + " error while closing the connection, cause:" + e);
}
}
// if everything is fine, set the connected flag at false
this.connected = false;
}
}// close
/**
* Returns the ModbusTransport associated with this TCPMasterConnection.
*
* @return the connection's ModbusTransport.
*/
public ModbusTransport getModbusTransport() {
return this.modbusRTUTCPTransport;
}// getModbusTransport
/**
* Prepares the associated {@link ModbusTransport} of this {@link RTUTCPMasterConnection} for use.
*
* @throws IOException
* if an I/O related error occurs.
*/
private void prepareTransport() throws IOException {
// if the modbus transport is not available, create it
if (this.modbusRTUTCPTransport == null) {
// create the transport
this.modbusRTUTCPTransport = new ModbusRTUTCPTransport(socket);
}
else {
// just update the transport socket
this.modbusRTUTCPTransport.setSocket(socket);
}
}// prepareIO
/**
* Returns the timeout for this {@link RTUTCPMasterConnection}.
*
* @return the timeout as an <tt>int</tt> value.
*/
public int getTimeout() {
return this.socketTimeout;
}// getReceiveTimeout
/**
* Sets the timeout for this {@link RTUTCPMasterConnection}.
*
* @param timeout
* the timeout as an <tt>int</tt>.
*/
public void setTimeout(int timeout) {
// store the current socket timeout
this.socketTimeout = timeout;
// set the timeout on the socket, if available
if (this.socket != null) {
try {
this.socket.setSoTimeout(socketTimeout);
} catch (IOException ex) {
// TODO: handle?
}
}
}// setReceiveTimeout
/**
* Returns the destination port of this {@link RTUTCPMasterConnection}.
*
* @return the port number as an <tt>int</tt>.
*/
public int getPort() {
return this.slaveIPPort;
}// getPort
/**
* Sets the destination port of this {@link RTUTCPMasterConnection}.
*
* @param port
* the port number as <tt>int</tt>.
*/
public void setPort(int port) {
this.slaveIPPort = port;
}// setPort
/**
* Returns the destination {@link InetAddress} of this {@link RTUTCPMasterConnection}.
*
* @return the destination address as InetAddress.
*/
public InetAddress getAddress() {
return this.slaveIPAddress;
}// getAddress
/**
* Sets the destination {@link InetAddress} of this {@link RTUTCPMasterConnection}.
*
* @param adr
* the destination address as {@link InetAddress}.
*/
public void setAddress(InetAddress adr) {
this.slaveIPAddress = adr;
}// setAddress
/**
* Tests if this {@link RTUTCPMasterConnection} is active or not.
*
* @return <tt>true</tt> if connected, <tt>false</tt> otherwise.
*/
@Override
public boolean isConnected() {
return connected;
}// isConnected
}