use of org.apache.plc4x.java.s7.readwrite.TransportSize in project plc4x by apache.
the class S7ProtocolLogic method serializePlcValue.
private S7VarPayloadDataItem serializePlcValue(S7Field field, PlcValue plcValue) {
try {
DataTransportSize transportSize = field.getDataType().getDataTransportSize();
int stringLength = (field instanceof S7StringField) ? ((S7StringField) field).getStringLength() : 254;
ByteBuffer byteBuffer = null;
for (int i = 0; i < field.getNumberOfElements(); i++) {
final int lengthInBits = DataItem.getLengthInBits(plcValue.getIndex(i), field.getDataType().getDataProtocolId(), stringLength);
final WriteBufferByteBased writeBuffer = new WriteBufferByteBased((int) Math.ceil(((float) lengthInBits) / 8.0f));
DataItem.staticSerialize(writeBuffer, plcValue.getIndex(i), field.getDataType().getDataProtocolId(), stringLength);
// Allocate enough space for all items.
if (byteBuffer == null) {
byteBuffer = ByteBuffer.allocate(writeBuffer.getBytes().length * field.getNumberOfElements());
}
byteBuffer.put(writeBuffer.getBytes());
}
if (byteBuffer != null) {
byte[] data = byteBuffer.array();
return new S7VarPayloadDataItem(DataTransportErrorCode.OK, transportSize, data);
}
} catch (SerializationException e) {
logger.warn("Error serializing field item of type: '{}'", field.getDataType().name(), e);
}
return null;
}
use of org.apache.plc4x.java.s7.readwrite.TransportSize in project plc4x by apache.
the class S7Field method of.
public static S7Field of(String fieldString) {
Matcher matcher;
if ((matcher = DATA_BLOCK_STRING_ADDRESS_PATTERN.matcher(fieldString)).matches()) {
TransportSize dataType = TransportSize.valueOf(matcher.group(DATA_TYPE));
int stringLength = Integer.parseInt(matcher.group(STRING_LENGTH));
MemoryArea memoryArea = MemoryArea.DATA_BLOCKS;
int blockNumber = checkDatablockNumber(Integer.parseInt(matcher.group(BLOCK_NUMBER)));
Short transferSizeCode = getSizeCode(matcher.group(TRANSFER_SIZE_CODE));
int byteOffset = checkByteOffset(Integer.parseInt(matcher.group(BYTE_OFFSET)));
byte bitOffset = 0;
if (matcher.group(BIT_OFFSET) != null) {
bitOffset = Byte.parseByte(matcher.group(BIT_OFFSET));
} else if (dataType == TransportSize.BOOL) {
throw new PlcInvalidFieldException("Expected bit offset for BOOL parameters.");
}
int numElements = 1;
if (matcher.group(NUM_ELEMENTS) != null) {
numElements = Integer.parseInt(matcher.group(NUM_ELEMENTS));
}
if ((transferSizeCode != null) && (dataType.getShortName() != transferSizeCode)) {
throw new PlcInvalidFieldException("Transfer size code '" + transferSizeCode + "' doesn't match specified data type '" + dataType.name() + "'");
}
return new S7StringField(dataType, memoryArea, blockNumber, byteOffset, bitOffset, numElements, stringLength);
} else if ((matcher = DATA_BLOCK_STRING_SHORT_PATTERN.matcher(fieldString)).matches()) {
TransportSize dataType = TransportSize.valueOf(matcher.group(DATA_TYPE));
int stringLength = Integer.parseInt(matcher.group(STRING_LENGTH));
MemoryArea memoryArea = MemoryArea.DATA_BLOCKS;
int blockNumber = checkDatablockNumber(Integer.parseInt(matcher.group(BLOCK_NUMBER)));
int byteOffset = checkByteOffset(Integer.parseInt(matcher.group(BYTE_OFFSET)));
byte bitOffset = 0;
int numElements = 1;
if (matcher.group(NUM_ELEMENTS) != null) {
numElements = Integer.parseInt(matcher.group(NUM_ELEMENTS));
}
return new S7StringField(dataType, memoryArea, blockNumber, byteOffset, bitOffset, numElements, stringLength);
} else if ((matcher = DATA_BLOCK_ADDRESS_PATTERN.matcher(fieldString)).matches()) {
TransportSize dataType = TransportSize.valueOf(matcher.group(DATA_TYPE));
MemoryArea memoryArea = MemoryArea.DATA_BLOCKS;
Short transferSizeCode = getSizeCode(matcher.group(TRANSFER_SIZE_CODE));
int blockNumber = checkDatablockNumber(Integer.parseInt(matcher.group(BLOCK_NUMBER)));
int byteOffset = checkByteOffset(Integer.parseInt(matcher.group(BYTE_OFFSET)));
byte bitOffset = 0;
if (matcher.group(BIT_OFFSET) != null) {
bitOffset = Byte.parseByte(matcher.group(BIT_OFFSET));
} else if (dataType == TransportSize.BOOL) {
throw new PlcInvalidFieldException("Expected bit offset for BOOL parameters.");
}
int numElements = 1;
if (matcher.group(NUM_ELEMENTS) != null) {
numElements = Integer.parseInt(matcher.group(NUM_ELEMENTS));
}
if ((transferSizeCode != null) && (dataType.getShortName() != transferSizeCode)) {
throw new PlcInvalidFieldException("Transfer size code '" + transferSizeCode + "' doesn't match specified data type '" + dataType.name() + "'");
}
return new S7Field(dataType, memoryArea, blockNumber, byteOffset, bitOffset, numElements);
} else if ((matcher = DATA_BLOCK_SHORT_PATTERN.matcher(fieldString)).matches()) {
TransportSize dataType = TransportSize.valueOf(matcher.group(DATA_TYPE));
MemoryArea memoryArea = MemoryArea.DATA_BLOCKS;
int blockNumber = checkDatablockNumber(Integer.parseInt(matcher.group(BLOCK_NUMBER)));
int byteOffset = checkByteOffset(Integer.parseInt(matcher.group(BYTE_OFFSET)));
byte bitOffset = 0;
if (matcher.group(BIT_OFFSET) != null) {
bitOffset = Byte.parseByte(matcher.group(BIT_OFFSET));
} else if (dataType == TransportSize.BOOL) {
throw new PlcInvalidFieldException("Expected bit offset for BOOL parameters.");
}
int numElements = 1;
if (matcher.group(NUM_ELEMENTS) != null) {
numElements = Integer.parseInt(matcher.group(NUM_ELEMENTS));
}
return new S7Field(dataType, memoryArea, blockNumber, byteOffset, bitOffset, numElements);
} else if (PLC_PROXY_ADDRESS_PATTERN.matcher(fieldString).matches()) {
try {
byte[] addressData = Hex.decodeHex(fieldString.replaceAll("[-]", ""));
ReadBuffer rb = new ReadBufferByteBased(addressData);
final S7Address s7Address = S7Address.staticParse(rb);
if (s7Address instanceof S7AddressAny) {
S7AddressAny s7AddressAny = (S7AddressAny) s7Address;
if ((s7AddressAny.getTransportSize() != TransportSize.BOOL) && s7AddressAny.getBitAddress() != 0) {
throw new PlcInvalidFieldException("A bit offset other than 0 is only supported for type BOOL");
}
return new S7Field(s7AddressAny.getTransportSize(), s7AddressAny.getArea(), s7AddressAny.getDbNumber(), s7AddressAny.getByteAddress(), s7AddressAny.getBitAddress(), s7AddressAny.getNumberOfElements());
} else {
throw new PlcInvalidFieldException("Unsupported address type.");
}
} catch (ParseException | DecoderException e) {
throw new PlcInvalidFieldException("Unable to parse address: " + fieldString);
}
} else if ((matcher = ADDRESS_PATTERN.matcher(fieldString)).matches()) {
TransportSize dataType = TransportSize.valueOf(matcher.group(DATA_TYPE));
MemoryArea memoryArea = getMemoryAreaForShortName(matcher.group(MEMORY_AREA));
Short transferSizeCode = getSizeCode(matcher.group(TRANSFER_SIZE_CODE));
int byteOffset = checkByteOffset(Integer.parseInt(matcher.group(BYTE_OFFSET)));
byte bitOffset = 0;
if (matcher.group(BIT_OFFSET) != null) {
bitOffset = Byte.parseByte(matcher.group(BIT_OFFSET));
} else if (dataType == TransportSize.BOOL) {
throw new PlcInvalidFieldException("Expected bit offset for BOOL parameters.");
}
int numElements = 1;
if (matcher.group(NUM_ELEMENTS) != null) {
numElements = Integer.parseInt(matcher.group(NUM_ELEMENTS));
}
if ((transferSizeCode != null) && (dataType.getShortName() != transferSizeCode)) {
throw new PlcInvalidFieldException("Transfer size code '" + transferSizeCode + "' doesn't match specified data type '" + dataType.name() + "'");
}
if ((dataType != TransportSize.BOOL) && bitOffset != 0) {
throw new PlcInvalidFieldException("A bit offset other than 0 is only supported for type BOOL");
}
return new S7Field(dataType, memoryArea, (short) 0, byteOffset, bitOffset, numElements);
}
throw new PlcInvalidFieldException("Unable to parse address: " + fieldString);
}
use of org.apache.plc4x.java.s7.readwrite.TransportSize in project plc4x by apache.
the class S7ProtocolLogic method encodeS7Address.
/**
* Currently we only support the S7 Any type of addresses. This helper simply converts the S7Field
* from PLC4X into S7Address objects.
*
* @param field S7Field instance we need to convert into an S7Address
* @return the S7Address
*/
protected S7Address encodeS7Address(PlcField field) {
if (!(field instanceof S7Field)) {
throw new PlcRuntimeException("Unsupported address type " + field.getClass().getName());
}
S7Field s7Field = (S7Field) field;
TransportSize transportSize = s7Field.getDataType();
int numElements = s7Field.getNumberOfElements();
// As otherwise the S7 will deny them with "Data type not supported" replies.
if ((transportSize == TransportSize.TIME) || /*|| (transportSize == TransportSize.S7_S5TIME)*/
(transportSize == TransportSize.LTIME) || (transportSize == TransportSize.DATE) || (transportSize == TransportSize.TIME_OF_DAY) || (transportSize == TransportSize.DATE_AND_TIME)) {
numElements = numElements * transportSize.getSizeInBytes();
transportSize = TransportSize.BYTE;
}
if (transportSize == TransportSize.STRING) {
transportSize = TransportSize.CHAR;
int stringLength = (s7Field instanceof S7StringField) ? ((S7StringField) s7Field).getStringLength() : 254;
numElements = numElements * (stringLength + 2);
} else if (transportSize == TransportSize.WSTRING) {
transportSize = TransportSize.CHAR;
int stringLength = (s7Field instanceof S7StringField) ? ((S7StringField) s7Field).getStringLength() : 254;
numElements = numElements * (stringLength + 2) * 2;
}
return new S7AddressAny(transportSize, numElements, s7Field.getBlockNumber(), s7Field.getMemoryArea(), s7Field.getByteOffset(), s7Field.getBitOffset());
}
Aggregations