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

166 lines
4.1 KiB
Java

package org.hwo.servicelink.ng;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import org.hwo.ByteArrayHexlifier;
import static org.hwo.logging.Logging.*;
import static org.hwo.logging.LogLevel.*;
public class TelegramStreamV2 extends ServiceLinkStream {
boolean exceptionCaught = false;
public TelegramStreamV2(){
}
public TelegramStreamV2(StreamContainer streamContainer) {
setStreamContainer(streamContainer);
}
public TelegramStreamV2(InputStream inStream,OutputStream outStream){
this.setStreamContainer(new StreamContainer(inStream,outStream));
}
public TelegramStreamV2(Socket socket) throws IOException {
this.setStreamContainer(new StreamContainer(socket));
}
@Override
boolean isConnected() {
return (this.streamContainer != null) && !exceptionCaught;
}
@Override
void close() {
if (this.streamContainer != null) {
this.streamContainer.close();
exceptionCaught = true;
}
}
@Override
boolean write(ServiceLinkRequestBuffer rbuffer) throws IOException {
if ((this.streamContainer == null) || (this.streamContainer.getOutStream() == null))
{
throw new IOException();
}
byte[] buffer = new byte[8];
byte[] bv;
int i;
i = rbuffer.isWrite() ? 0x01 : 0x00;
i |= rbuffer.hasFloatValue() ? 0x02 : 0x00;
buffer[0] = (byte)i;
buffer[1] = (byte)( ((rbuffer.getAx()&0x0F)<<4) | (rbuffer.getNode() & 0x0F) );
buffer[2] = (byte)(rbuffer.getRegister() & 0xFF);
buffer[3] = (byte)((rbuffer.getRegister()>>8) & 0xFF);
bv = rbuffer.getValueAsBytes();
buffer[4] = bv[0];
buffer[5] = bv[1];
buffer[6] = bv[2];
buffer[7] = bv[3];
try {
log(DEBUGDETAIL,"TX BUFFER: %s",rbuffer);
log(DEBUGDETAIL,"TX BYTES: %s",ByteArrayHexlifier.byteArrayToString(buffer));
synchronized(this.streamContainer.getOutStream()) {
this.streamContainer.getOutStream().write(buffer);
}
return true;
} catch (IOException e) {
exceptionCaught = true;
log(e);
}
return false;
}
@Override
boolean read(ServiceLinkRequestBuffer rbuffer) throws IOException{
byte[] buffer = new byte[8];
int bufferUsed = 0;
if ((streamContainer == null) || (this.streamContainer.getInStream() == null)) {
log(DEBUG,"TelegramStreamV2: streamContainer == null || getInStream() == null");
throw new IOException();
}
try {
while (bufferUsed != 8) {
long start = System.currentTimeMillis();
int n;
try {
n = streamContainer.getInStream().read(buffer, bufferUsed, 8 - bufferUsed);
} catch (SocketTimeoutException ste) {
n = 0;
}
if (n > 0){
bufferUsed += n;
} else if (n < 0) {
throw new IOException();
}
log(DEBUGDETAIL,"TelegramStreamV2: read(...): bufferUsed=%d n=%d dT=%dms",bufferUsed,n,System.currentTimeMillis() - start);
}
} catch (IOException e) {
exceptionCaught = true;
log(e);
throw new RuntimeException(e);
}
log(DEBUGDETAIL,"RX BYTES: %s",ByteArrayHexlifier.byteArrayToString(buffer));
if (bufferUsed != 8){
return false;
}
rbuffer.setAx((buffer[1]>>4) & 0x0F);
rbuffer.setNode(buffer[1] & 0x0F);
rbuffer.setRegister((((int)buffer[2])&0xff) | (((int)buffer[3])<<8)&0xFF00);
rbuffer.setWrite( (buffer[0] & 0x01) == 0 );
rbuffer.setSuccess( ( buffer[0] & 0x04 ) == 0 );
ByteBuffer bb = ByteBuffer.wrap(buffer);
if ( (buffer[0] & 0x02 ) == 0) {
rbuffer.setValue(bb.order(ByteOrder.LITTLE_ENDIAN).asIntBuffer().get(1));
} else {
rbuffer.setValue( bb.order(ByteOrder.LITTLE_ENDIAN).asFloatBuffer().get(1) );
}
log(DEBUGDETAIL,String.format("RX BUFFER: %s",rbuffer));
return rbuffer.isSuccess();
}
public InputStream getInStream() {
return streamContainer.getInStream();
}
public OutputStream getOutStream() {
return streamContainer.getOutStream();
}
@Override
public StreamContainer getStreamContainer() {
return this.streamContainer;
}
@Override
public void setStreamContainer(StreamContainer streamContainer) {
this.streamContainer = streamContainer;
exceptionCaught = false;
}
}