java-org.hwo.servicelink/src/org/hwo/servicelink/ng/ServiceLink.java

240 lines
5.1 KiB
Java

package org.hwo.servicelink.ng;
import java.io.IOException;
import java.util.Hashtable;
import javax.swing.DebugGraphics;
import org.hwo.Smoother;
import static org.hwo.logging.Logging.*;
import static org.hwo.logging.LogLevel.*;
public class ServiceLink implements RegBUSInterface {
ServiceLinkStream stream = null;
Hashtable<Integer,ServiceLinkRequestBuffer> pendingRequests = new Hashtable<>();
int timeout = 175;
boolean closed = false;
ServiceRegisterCache registerCache = new ServiceRegisterCache(this);
AsynchronServiceLinkProvider asynchronServiceLinkProvider = new AsynchronServiceLinkProvider(registerCache);
Smoother turnAroundTime = new Smoother();
Thread readerThread = new Thread(new Runnable() {
@Override
public void run() {
reader();
}
});
public ServiceLink() {
this.readerThread.start();
this.initialize();
}
public ServiceLink(ServiceLinkStream stream) {
this.stream = stream;
this.readerThread.start();
this.initialize();
}
private void initialize() {
this.turnAroundTime.setTn(10);
}
public void close() {
this.stream.close();
}
@Override
public boolean isConnected() {
return (this.stream != null) && (this.stream.isConnected());
}
public ServiceRegisterCache getRegisterCache() {
return registerCache;
}
public AsynchronServiceLinkProvider getAsynchronServiceLinkProvider() {
return asynchronServiceLinkProvider;
}
private boolean request(ServiceLinkRequestBuffer buffer) {
long tStart = System.currentTimeMillis();
if ((this.stream == null)||(!this.stream.isConnected())) {
return false;
}
synchronized(this.pendingRequests) {
this.pendingRequests.put(buffer.hashCode(), buffer);
}
synchronized(buffer) {
try {
this.stream.write(buffer);
buffer.wait(this.timeout);
} catch (Exception e) {
log(e);
}
}
synchronized(this.pendingRequests) {
this.pendingRequests.remove(buffer.hashCode());
}
long tLen = System.currentTimeMillis() - tStart;
turnAroundTime.cycle((int)tLen);
return buffer.isSuccess();
}
public int getTurnAroundTime() {
return this.turnAroundTime.getLastValue();
}
public synchronized ServiceLinkStream getServiceLinkStream() {
return stream;
}
public synchronized void setServiceLinkStream(ServiceLinkStream stream) {
this.stream = stream;
}
@Override
public Float readFloat(int ax, int node, int reg) {
Float result = null;
ServiceLinkRequestBuffer buffer = ObjectPool.popRequestBuffer();
buffer.setAx(ax);
buffer.setNode(node);
buffer.setRegister(reg);
buffer.setValue(0.0f);
if (request(buffer)) {
result = (Float)buffer.getValue();
}
ObjectPool.push(buffer);
return result;
}
@Override
public Integer readInteger(int ax, int node, int reg) {
Integer result = null;
ServiceLinkRequestBuffer buffer = ObjectPool.popRequestBuffer();
buffer.setAx(ax);
buffer.setNode(node);
buffer.setRegister(reg);
buffer.setValue(0);
if (request(buffer)) {
result = (Integer)buffer.getValue();
}
ObjectPool.push(buffer);
return result;
}
@Override
public boolean writeFloat(int ax, int node, int reg, float value) {
ServiceLinkRequestBuffer buffer = ObjectPool.popRequestBuffer();
buffer.setAx(ax);
buffer.setNode(node);
buffer.setRegister(reg);
buffer.setValue(value);
buffer.setWrite(true);
boolean success = request(buffer);
ObjectPool.push(buffer);
return success;
}
@Override
public boolean writeInteger(int ax, int node, int reg, int value) {
ServiceLinkRequestBuffer buffer = ObjectPool.popRequestBuffer();
buffer.setAx(ax);
buffer.setNode(node);
buffer.setRegister(reg);
buffer.setValue(value);
buffer.setWrite(true);
boolean success = request(buffer);
ObjectPool.push(buffer);
return success;
}
public int getTimeout() {
return timeout;
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
private void reader() {
ServiceLinkRequestBuffer buffer = new ServiceLinkRequestBuffer();
while (!closed) {
if ((this.stream == null) || !this.stream.isConnected()) {
try {
log(DEBUG,"ServiceLink:reader() sleeps...");
Thread.sleep(1000);
log(DEBUG,"ServiceLink:reader() slept.");
} catch (InterruptedException e) {
log(e);
}
} else {
buffer.clear();
try {
if (this.stream.isConnected() && this.stream.read(buffer)) {
int hash = buffer.hashCode();
ServiceLinkRequestBuffer req;
synchronized(this.pendingRequests) {
req = this.pendingRequests.remove(hash);
}
if (req != null) {
req.setValue(buffer.getValue());
req.setSuccess(buffer.isSuccess());
synchronized(req) {
req.notifyAll();
}
} else {
log(DEBUG,"REPLY WITHOUT PENDING REQUEST");
}
}
} catch (Exception e) {
log(e);
close();
try {
Thread.sleep(250);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
log(DEBUG,"ServiceLinke:reader() exits");
}
}