com.intelligt.modbus.jlibmodbus.slave.ModbusSlave Maven / Gradle / Ivy
package com.intelligt.modbus.jlibmodbus.slave;
import com.intelligt.modbus.jlibmodbus.Modbus;
import com.intelligt.modbus.jlibmodbus.data.DataHolder;
import com.intelligt.modbus.jlibmodbus.data.DataHolderBuilder;
import com.intelligt.modbus.jlibmodbus.exception.ModbusIOException;
import com.intelligt.modbus.jlibmodbus.net.ModbusConnection;
import com.intelligt.modbus.jlibmodbus.utils.FrameEvent;
import com.intelligt.modbus.jlibmodbus.utils.FrameEventListener;
import com.intelligt.modbus.jlibmodbus.utils.FrameEventListenerList;
import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import java.util.concurrent.atomic.AtomicBoolean;
/*
* Copyright (C) 2016 "Invertor" Factory", JSC
* [http://www.sbp-invertor.ru]
*
* This file is part of JLibModbus.
*
* Licensed 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.
*
* Authors: Vladislav Y. Kochedykov, software engineer.
* email: [email protected]
*/
abstract public class ModbusSlave implements FrameEventListenerList {
final private List connectionList = new ArrayList();
final private AtomicBoolean listening = new AtomicBoolean(false);
final private AtomicBoolean broadcastEnabled = new AtomicBoolean(false);
private Observable observable = new Observable() {
@Override
public void notifyObservers(Object arg) {
setChanged();
super.notifyObservers(arg);
}
};
private int serverAddress = Modbus.BROADCAST_ID;
private DataHolder dataHolder = new DataHolder();
/**
* a timeout for single connection handler. if master makes a new connection for every data request,
* we should close it's last connection as soon as possible. Else, if master is working through a single connection,
* we should be waiting for the next request as long as it is possible :).
*/
private volatile int readTimeout = Modbus.MAX_RESPONSE_TIMEOUT;
protected ModbusSlave() {
}
public int getReadTimeout() {
return readTimeout;
}
public void setReadTimeout(int readTimeout) {
this.readTimeout = readTimeout;
for (ModbusConnection conn : getConnectionList()) {
conn.setReadTimeout(readTimeout);
}
}
abstract protected void listenImpl() throws ModbusIOException;
abstract protected void shutdownImpl() throws ModbusIOException;
/**
* starts the ModbusSlave thread.
*/
final public void listen() throws ModbusIOException {
listenImpl();
setListening(true);
}
/**
* should have stop the thread of the ModbusSlave.
*/
final public void shutdown() throws ModbusIOException {
setListening(false);
shutdownImpl();
}
public boolean isListening() {
return listening.get();
}
protected void setListening(boolean listening) {
this.listening.set(listening);
}
/*Getters & Setters*/
public DataHolder getDataHolder() {
return dataHolder;
}
public void setDataHolder(DataHolderBuilder builder) {
setDataHolder(builder.build());
}
public void setDataHolder(DataHolder dataHolder) {
this.dataHolder = dataHolder;
}
public int getServerAddress() {
return serverAddress;
}
public void setServerAddress(int serverAddress) {
if (Modbus.checkServerAddress(serverAddress))
this.serverAddress = serverAddress;
}
public boolean isBroadcastEnabled() {
return broadcastEnabled.get();
}
public void setBroadcastEnabled(boolean broadcastEnabled) {
this.broadcastEnabled.set(broadcastEnabled);
}
protected List getConnectionList() {
return connectionList;
}
void connectionOpened(ModbusConnection connection) {
connection.setReadTimeout(getReadTimeout());
getConnectionList().add(connection);
}
void connectionClosed(ModbusConnection connection) {
getConnectionList().remove(connection);
}
@Override
public void addListener(FrameEventListener listener) {
for (ModbusConnection c : getConnectionList()) {
c.addListener(listener);
}
}
@Override
public void removeListener(FrameEventListener listener) {
for (ModbusConnection c : getConnectionList()) {
c.removeListener(listener);
}
}
@Override
public void removeListeners() {
for (ModbusConnection c : getConnectionList()) {
c.removeListeners();
}
}
@Override
public void fireFrameReceivedEvent(FrameEvent event) {
for (ModbusConnection c : getConnectionList()) {
c.fireFrameReceivedEvent(event);
}
}
@Override
public void fireFrameSentEvent(FrameEvent event) {
for (ModbusConnection c : getConnectionList()) {
c.fireFrameSentEvent(event);
}
}
@Override
public int countListeners() {
int count = 0;
for (ModbusConnection c : getConnectionList()) {
count += c.countListeners();
}
return count;
}
/*
facade
*/
public void addObserver(Observer observer) {
observable.addObserver(observer);
}
public void deleteObserver(Observer observer) {
observable.deleteObserver(observer);
}
public void deleteObservers() {
observable.deleteObservers();
}
public int countObservers() {
return observable.countObservers();
}
protected void notifyObservers(Object o) {
observable.notifyObservers(o);
}
}