238 lines
5.0 KiB
Java
238 lines
5.0 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);
|
|
|
|
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);
|
|
|
|
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");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|