WIP161208
parent
fd83cf147e
commit
ae09543e3d
|
@ -51,6 +51,8 @@ public class ServiceLink implements NewSerialPortListener {
|
|||
Smoother requestTime;
|
||||
int requestTimeOut;
|
||||
|
||||
boolean useV2 = true;
|
||||
|
||||
LinkedList<ServiceLinkTelegram> txQueue;
|
||||
Hashtable<ServiceLinkAddress, List<ServiceLinkTelegram>>
|
||||
pendingRequests;
|
||||
|
@ -251,24 +253,32 @@ public class ServiceLink implements NewSerialPortListener {
|
|||
|
||||
public Integer readInt(int achse,int knoten,int register) throws IOException, ServiceLinkException, ServiceLinkRequestFailedException
|
||||
{
|
||||
ServiceLinkTelegram request = ServiceLinkTelegram.create(REQ_INT | REQ_READ, achse, knoten, register, null);
|
||||
ServiceLinkTelegram request = useV2 ?
|
||||
new ServiceLinkV2Telegram(REQ_INT | REQ_READ, achse, knoten, register, null) :
|
||||
new ServiceLinkV1Telegram(REQ_INT | REQ_READ, achse, knoten, register, null);
|
||||
queueRequest(request);
|
||||
return (Integer)request.getValue();
|
||||
}
|
||||
public Float readFloat(int achse,int knoten,int register) throws IOException, ServiceLinkException, ServiceLinkRequestFailedException
|
||||
{
|
||||
ServiceLinkTelegram request = ServiceLinkTelegram.create(REQ_FLOAT | REQ_READ, achse, knoten, register, null);
|
||||
ServiceLinkTelegram request = useV2 ?
|
||||
new ServiceLinkV2Telegram(REQ_FLOAT | REQ_READ, achse, knoten, register, null) :
|
||||
new ServiceLinkV1Telegram(REQ_FLOAT | REQ_READ, achse, knoten, register, null);
|
||||
queueRequest(request);
|
||||
return (Float)request.getValue();
|
||||
}
|
||||
|
||||
public void writeInt(int achse,int knoten,int register,int value) throws IOException, ServiceLinkException, ServiceLinkRequestFailedException
|
||||
{
|
||||
ServiceLinkTelegram request = ServiceLinkTelegram.create(REQ_INT | REQ_WRITE, achse, knoten, register, value);
|
||||
ServiceLinkTelegram request = useV2 ?
|
||||
new ServiceLinkV2Telegram(REQ_INT | REQ_WRITE, achse, knoten, register, null) :
|
||||
new ServiceLinkV1Telegram(REQ_INT | REQ_WRITE, achse, knoten, register, null);
|
||||
queueRequest(request);
|
||||
}
|
||||
public void writeFloat(int achse,int knoten,int register,float value) throws IOException, ServiceLinkException, ServiceLinkRequestFailedException{
|
||||
ServiceLinkTelegram request = ServiceLinkTelegram.create(REQ_FLOAT | REQ_WRITE, achse, knoten, register, value);
|
||||
ServiceLinkTelegram request = useV2 ?
|
||||
new ServiceLinkV2Telegram(REQ_FLOAT | REQ_WRITE, achse, knoten, register, null) :
|
||||
new ServiceLinkV1Telegram(REQ_FLOAT | REQ_WRITE, achse, knoten, register, null);
|
||||
queueRequest(request);
|
||||
}
|
||||
|
||||
|
@ -323,7 +333,10 @@ public class ServiceLink implements NewSerialPortListener {
|
|||
return;
|
||||
}
|
||||
}
|
||||
rx = ServiceLinkTelegram.read(getSerialPort().getInputStream());
|
||||
rx = useV2 ?
|
||||
new ServiceLinkV2Telegram(getSerialPort().getInputStream()) :
|
||||
new ServiceLinkV1Telegram(getSerialPort().getInputStream()) ;
|
||||
|
||||
if (rx != null){
|
||||
received(rx);
|
||||
}
|
||||
|
|
|
@ -1,20 +1,10 @@
|
|||
package org.hwo.servicelink;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.Arrays;
|
||||
import java.util.zip.CRC32;
|
||||
|
||||
import org.hwo.ByteArrayHexlifier;
|
||||
import org.hwo.ChkSum;
|
||||
import org.hwo.servicelink.exceptions.CRCFailedException;
|
||||
public abstract class ServiceLinkTelegram {
|
||||
|
||||
import static org.hwo.logging.Logging.*;
|
||||
import static org.hwo.logging.LogLevel.*;
|
||||
|
||||
public class ServiceLinkTelegram {
|
||||
static int REQ_READ = 0x01;
|
||||
static int REQ_WRITE = 0x02;
|
||||
static int REQ_EVENT = 0x04;
|
||||
|
@ -26,63 +16,6 @@ public class ServiceLinkTelegram {
|
|||
|
||||
static int SL_MAGIC = 0x66;
|
||||
|
||||
public static ServiceLinkTelegram create(int operation,int achse,int knoten,int register,Object value){
|
||||
return new ServiceLinkTelegram(operation,achse,knoten,register,value);
|
||||
}
|
||||
|
||||
public static byte[] readTelegramBytes(InputStream in){
|
||||
int l,
|
||||
sync,
|
||||
opcode;
|
||||
|
||||
byte[] rxbuffer;
|
||||
|
||||
try {
|
||||
int ch = in.read();
|
||||
|
||||
while ((ch != SL_MAGIC)) {
|
||||
ch = in.read();
|
||||
if (ch != SL_MAGIC){
|
||||
if (ch == -1){
|
||||
return null;
|
||||
}
|
||||
log(DEBUGDETAIL,"readTelegramBytes(): junk byte in the line: %d [ 0x%02x ]",ch,ch);
|
||||
}
|
||||
}
|
||||
sync = (byte)ch;
|
||||
opcode = (byte)in.read();
|
||||
|
||||
l = ((opcode & (REQ_READ | REQ_ACK)) == (REQ_READ | REQ_ACK)) ? 10 : 6;
|
||||
|
||||
rxbuffer = new byte[ l + 2 ];
|
||||
|
||||
rxbuffer[0] = (byte)sync;
|
||||
rxbuffer[1] = (byte)opcode;
|
||||
|
||||
l = in.read(rxbuffer,2,l);
|
||||
log(DEBUGDETAIL,"RX BYTES: %2d: %s",rxbuffer.length,ByteArrayHexlifier.byteArrayToString(rxbuffer));
|
||||
|
||||
return rxbuffer;
|
||||
} catch (IOException e) {
|
||||
log(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ServiceLinkTelegram read(InputStream in){
|
||||
byte[] rx = readTelegramBytes(in);
|
||||
|
||||
if (rx != null){
|
||||
try {
|
||||
return new ServiceLinkTelegram(rx);
|
||||
} catch (Exception e){
|
||||
log(e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
int opcode;
|
||||
ServiceLinkAddress
|
||||
address;
|
||||
|
@ -96,31 +29,8 @@ public class ServiceLinkTelegram {
|
|||
this.opcode = operation;
|
||||
this.address = new ServiceLinkAddress(achse, knoten, register);
|
||||
this.value = value;
|
||||
}
|
||||
protected ServiceLinkTelegram(byte[] buffer) throws CRCFailedException {
|
||||
if ((buffer.length != 12) && (buffer.length != 8) ){
|
||||
throw new ArrayIndexOutOfBoundsException(String.format("ServiceLinkTelegram needs to be constructed from 8 or 12 bytes! But got %d bytes.",buffer.length));
|
||||
}
|
||||
|
||||
ByteBuffer bb = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN);
|
||||
short chk = ChkSum.chksum(buffer, 1, buffer.length - 3);
|
||||
|
||||
|
||||
if (bb.getShort(buffer.length - 2) != chk) {
|
||||
log(DEBUG,"CRC failed: 0x%04x != 0x%04x",bb.getShort(buffer.length - 2),chk);
|
||||
throw new CRCFailedException(buffer, "ServiceLinkTelegram bytes with wrong crc");
|
||||
}
|
||||
|
||||
this.opcode = bb.get(1);
|
||||
this.address = new ServiceLinkAddress(bb.get(2),bb.get(3),bb.getShort(4));
|
||||
if (buffer.length == 12){
|
||||
int v = bb.getInt(6);
|
||||
if ((opcode & REQ_FLOAT)==REQ_FLOAT){
|
||||
this.value = Float.intBitsToFloat(v);
|
||||
} else if ((opcode & REQ_INT)==REQ_INT){
|
||||
this.value = v;
|
||||
}
|
||||
}
|
||||
this.checkPlausible();
|
||||
}
|
||||
|
||||
private void checkPlausible(){
|
||||
|
@ -131,7 +41,7 @@ public class ServiceLinkTelegram {
|
|||
}
|
||||
}
|
||||
|
||||
private byte[] valueAsByteArray(){
|
||||
protected byte[] valueAsByteArray(){
|
||||
byte[] v = new byte[4];
|
||||
|
||||
if (value == null)
|
||||
|
@ -144,26 +54,7 @@ public class ServiceLinkTelegram {
|
|||
return v;
|
||||
}
|
||||
|
||||
public byte[] toByteArray(){
|
||||
byte[] txbuffer = new byte[ ((opcode & REQ_WRITE) == REQ_WRITE) ? 12 : 8 ];
|
||||
ByteBuffer bb = ByteBuffer.wrap(txbuffer).order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
bb.put( (byte)SL_MAGIC );
|
||||
bb.put( (byte)opcode );
|
||||
bb.put( (byte)address.getAx());
|
||||
bb.put( (byte)address.getNode());
|
||||
bb.putShort((short)(address.getRegister()));
|
||||
|
||||
|
||||
if ((opcode & REQ_WRITE) == REQ_WRITE){
|
||||
bb.put(valueAsByteArray());
|
||||
}
|
||||
|
||||
short chk = ChkSum.chksum(txbuffer, 1, bb.position()-1);
|
||||
bb.putShort(chk);
|
||||
|
||||
return txbuffer;
|
||||
}
|
||||
public abstract byte[] toByteArray();
|
||||
|
||||
public ServiceLinkAddress getAddress() {
|
||||
return address;
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
package org.hwo.servicelink;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.Arrays;
|
||||
import java.util.zip.CRC32;
|
||||
|
||||
import javax.management.RuntimeErrorException;
|
||||
|
||||
import org.hwo.ByteArrayHexlifier;
|
||||
import org.hwo.ChkSum;
|
||||
import org.hwo.servicelink.exceptions.CRCFailedException;
|
||||
|
||||
import static org.hwo.logging.Logging.*;
|
||||
import static org.hwo.logging.LogLevel.*;
|
||||
|
||||
public class ServiceLinkV1Telegram extends ServiceLinkTelegram {
|
||||
|
||||
public ServiceLinkV1Telegram(int operation,int achse,int knoten,int register,Object value){
|
||||
super(operation,achse,knoten,register,value);
|
||||
}
|
||||
|
||||
public ServiceLinkV1Telegram(InputStream in) {
|
||||
byte[] bytes = readTelegramBytes(in);
|
||||
try {
|
||||
fromBytes(bytes);
|
||||
} catch (CRCFailedException e){
|
||||
log(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected byte[] readTelegramBytes(InputStream in){
|
||||
int l,
|
||||
sync,
|
||||
opcode;
|
||||
|
||||
byte[] rxbuffer;
|
||||
|
||||
try {
|
||||
int ch = in.read();
|
||||
|
||||
while ((ch != SL_MAGIC)) {
|
||||
ch = in.read();
|
||||
if (ch != SL_MAGIC){
|
||||
if (ch == -1){
|
||||
return null;
|
||||
}
|
||||
log(DEBUGDETAIL,"readTelegramBytes(): junk byte in the line: %d [ 0x%02x ]",ch,ch);
|
||||
}
|
||||
}
|
||||
sync = (byte)ch;
|
||||
opcode = (byte)in.read();
|
||||
|
||||
l = ((opcode & (REQ_READ | REQ_ACK)) == (REQ_READ | REQ_ACK)) ? 10 : 6;
|
||||
|
||||
rxbuffer = new byte[ l + 2 ];
|
||||
|
||||
rxbuffer[0] = (byte)sync;
|
||||
rxbuffer[1] = (byte)opcode;
|
||||
|
||||
l = in.read(rxbuffer,2,l);
|
||||
log(DEBUGDETAIL,"RX BYTES: %2d: %s",rxbuffer.length,ByteArrayHexlifier.byteArrayToString(rxbuffer));
|
||||
|
||||
return rxbuffer;
|
||||
} catch (IOException e) {
|
||||
log(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void fromBytes(byte[] buffer) throws CRCFailedException {
|
||||
if ((buffer.length != 12) && (buffer.length != 8) ){
|
||||
throw new ArrayIndexOutOfBoundsException(String.format("ServiceLinkTelegram needs to be constructed from 8 or 12 bytes! But got %d bytes.",buffer.length));
|
||||
}
|
||||
|
||||
ByteBuffer bb = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN);
|
||||
short chk = ChkSum.chksum(buffer, 1, buffer.length - 3);
|
||||
|
||||
|
||||
if (bb.getShort(buffer.length - 2) != chk) {
|
||||
log(DEBUG,"CRC failed: 0x%04x != 0x%04x",bb.getShort(buffer.length - 2),chk);
|
||||
throw new CRCFailedException(buffer, "ServiceLinkTelegram bytes with wrong crc");
|
||||
}
|
||||
|
||||
this.opcode = bb.get(1);
|
||||
this.address = new ServiceLinkAddress(bb.get(2),bb.get(3),bb.getShort(4));
|
||||
if (buffer.length == 12){
|
||||
int v = bb.getInt(6);
|
||||
if ((opcode & REQ_FLOAT)==REQ_FLOAT){
|
||||
this.value = Float.intBitsToFloat(v);
|
||||
} else if ((opcode & REQ_INT)==REQ_INT){
|
||||
this.value = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] toByteArray(){
|
||||
byte[] txbuffer = new byte[ ((opcode & REQ_WRITE) == REQ_WRITE) ? 12 : 8 ];
|
||||
ByteBuffer bb = ByteBuffer.wrap(txbuffer).order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
bb.put( (byte)SL_MAGIC );
|
||||
bb.put( (byte)opcode );
|
||||
bb.put( (byte)address.getAx());
|
||||
bb.put( (byte)address.getNode());
|
||||
bb.putShort((short)(address.getRegister()));
|
||||
|
||||
|
||||
if ((opcode & REQ_WRITE) == REQ_WRITE){
|
||||
bb.put(valueAsByteArray());
|
||||
}
|
||||
|
||||
short chk = ChkSum.chksum(txbuffer, 1, bb.position()-1);
|
||||
bb.putShort(chk);
|
||||
|
||||
return txbuffer;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
package org.hwo.servicelink;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.Arrays;
|
||||
import java.util.zip.CRC32;
|
||||
|
||||
import org.hwo.ByteArrayHexlifier;
|
||||
import org.hwo.ChkSum;
|
||||
import org.hwo.servicelink.exceptions.CRCFailedException;
|
||||
|
||||
import static org.hwo.logging.Logging.*;
|
||||
import static org.hwo.logging.LogLevel.*;
|
||||
|
||||
public class ServiceLinkV2Telegram extends ServiceLinkTelegram {
|
||||
static int REQ_READ = 0x01;
|
||||
static int REQ_WRITE = 0x02;
|
||||
static int REQ_EVENT = 0x04;
|
||||
static int REQ_FAIL = 0x08;
|
||||
|
||||
static int REQ_INT = 0x10;
|
||||
static int REQ_FLOAT = 0x20;
|
||||
static int REQ_ACK = 0x40;
|
||||
|
||||
public ServiceLinkV2Telegram(int operation,int achse,int knoten,int register,Object value){
|
||||
super(operation,achse,knoten,register,value);
|
||||
}
|
||||
|
||||
public ServiceLinkV2Telegram(InputStream in){
|
||||
byte[] buffer = new byte[8];
|
||||
|
||||
try {
|
||||
in.read(buffer, 0, 8);
|
||||
} catch (IOException e) {
|
||||
log(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
setAddress(new ServiceLinkAddress((buffer[1]>>4) & 0x0F, buffer[1] & 0x0F, ((int)buffer[2]) | ((int)buffer[3])<<8 ));
|
||||
|
||||
int op = 0;
|
||||
|
||||
op |= ( buffer[0] & 0x01 ) == 0 ? REQ_WRITE : REQ_READ;
|
||||
op |= ( buffer[0] & 0x02 ) == 0 ? REQ_INT : REQ_FLOAT;
|
||||
op |= ( buffer[0] & 0x04 ) == 0 ? REQ_ACK : REQ_FAIL;
|
||||
|
||||
setOpcode(op);
|
||||
|
||||
if ((op & (REQ_READ | REQ_ACK))==(REQ_READ | REQ_ACK)){
|
||||
// ToDo: set value...
|
||||
} else {
|
||||
setValue(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public byte[] toByteArray() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
package org.hwo.servicelink.exceptions;
|
||||
|
||||
import org.hwo.servicelink.ServiceLinkTelegram;
|
||||
import org.hwo.servicelink.ServiceLinkV1Telegram;
|
||||
|
||||
public class ServiceLinkRequestFailedException extends ServiceLinkException {
|
||||
|
||||
private ServiceLinkTelegram serviceTelegram;
|
||||
private ServiceLinkV1Telegram serviceTelegram;
|
||||
|
||||
public ServiceLinkRequestFailedException(ServiceLinkTelegram telegram)
|
||||
public ServiceLinkRequestFailedException(ServiceLinkV1Telegram telegram)
|
||||
{
|
||||
serviceTelegram = telegram;
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ public class ServiceLinkRequestFailedException extends ServiceLinkException {
|
|||
serviceTelegram = null;
|
||||
}
|
||||
|
||||
public ServiceLinkTelegram getServiceLinkTelegram()
|
||||
public ServiceLinkV1Telegram getServiceLinkTelegram()
|
||||
{
|
||||
return this.serviceTelegram;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue