use of org.apache.plc4x.java.api.exceptions.PlcProtocolPayloadTooBigException in project plc4x by apache.
the class Plc4x2AdsProtocol method encodeWriteRequest.
private void encodeWriteRequest(PlcRequestContainer<InternalPlcRequest, InternalPlcResponse> msg, List<Object> out) throws PlcException {
InternalPlcWriteRequest writeRequest = (InternalPlcWriteRequest) msg.getRequest();
if (writeRequest.getFields().size() != 1) {
throw new PlcProtocolException("Only one item supported");
}
PlcField field = writeRequest.getFields().get(0);
if (field instanceof SymbolicAdsField) {
DirectAdsField mappedField = fieldMapping.get(field);
LOGGER.debug("Replacing {} with {}", field, mappedField);
field = mappedField;
}
if (!(field instanceof DirectAdsField)) {
throw new PlcProtocolException("PlcField not of type DirectAdsField: " + field.getClass());
}
DirectAdsField directAdsField = (DirectAdsField) field;
Invoke invokeId = Invoke.of(correlationBuilder.incrementAndGet());
IndexGroup indexGroup = IndexGroup.of(directAdsField.getIndexGroup());
IndexOffset indexOffset = IndexOffset.of(directAdsField.getIndexOffset());
Object[] plcValues;
PlcValue plcValue = writeRequest.getPlcValues().get(0);
if (plcValue instanceof PlcList) {
plcValues = ((PlcList) plcValue).getList().toArray(new Object[0]);
} else {
plcValues = new Object[] { plcValue.getObject() };
}
byte[] bytes = encodeData(directAdsField.getAdsDataType(), plcValues);
int bytesToBeWritten = bytes.length;
int maxTheoreticalSize = directAdsField.getAdsDataType().getTargetByteSize() * directAdsField.getNumberOfElements();
if (bytesToBeWritten > maxTheoreticalSize) {
LOGGER.debug("Requested AdsDatatype {} is exceeded by number of bytes {}. Limit {}.", directAdsField.getAdsDataType(), bytesToBeWritten, maxTheoreticalSize);
throw new PlcProtocolPayloadTooBigException("ADS", maxTheoreticalSize, bytesToBeWritten, plcValues);
}
Data data = Data.of(bytes);
AmsPacket amsPacket = AdsWriteRequest.of(targetAmsNetId, targetAmsPort, sourceAmsNetId, sourceAmsPort, invokeId, indexGroup, indexOffset, data);
LOGGER.debug("encoded write request {}", amsPacket);
out.add(amsPacket);
requests.put(invokeId.getAsLong(), msg);
}
use of org.apache.plc4x.java.api.exceptions.PlcProtocolPayloadTooBigException in project plc4x by apache.
the class Payload2SerialProtocol method encode.
@Override
protected void encode(ChannelHandlerContext channelHandlerContext, ByteBuf amsPacket, List<Object> out) throws PlcProtocolPayloadTooBigException {
if (amsPacket == Unpooled.EMPTY_BUFFER) {
// Cleanup...
ScheduledFuture<?> scheduledFuture = currentRetryer.get();
if (scheduledFuture != null) {
scheduledFuture.cancel(true);
}
return;
}
LOGGER.trace("(<--OUT): {}, {}, {}", channelHandlerContext, amsPacket, out);
int fragmentNumber = fragmentCounter.getAndUpdate(value -> value > 255 ? 0 : ++value);
LOGGER.debug("Using fragmentNumber {} for {}", fragmentNumber, amsPacket);
UserData userData = UserData.of(amsPacket);
if (userData.getCalculatedLength() > 255) {
throw new PlcProtocolPayloadTooBigException("ADS/AMS", 255, (int) userData.getCalculatedLength(), amsPacket);
}
AmsSerialFrame amsSerialFrame = AmsSerialFrame.of(FragmentNumber.of((byte) fragmentNumber), userData);
MutableInt retryCount = new MutableInt(0);
ScheduledFuture<?> oldRetryer = currentRetryer.get();
if (oldRetryer != null) {
oldRetryer.cancel(false);
}
currentRetryer.set(channelHandlerContext.executor().scheduleAtFixedRate(() -> {
LOGGER.trace("Retrying {} the {} time", amsSerialFrame, retryCount);
int currentTry = retryCount.incrementAndGet();
if (currentTry > 10) {
// TODO: we might need to throw an exception to potentially cancel upstream waiting
channelHandlerContext.writeAndFlush(AmsSerialResetFrame.of(FragmentNumber.of((byte) fragmentNumber)));
PlcRuntimeException plcRuntimeException = new PlcRuntimeException("Retry exhausted after " + retryCount + " times");
channelHandlerContext.fireExceptionCaught(plcRuntimeException);
throw plcRuntimeException;
} else {
channelHandlerContext.writeAndFlush(amsSerialFrame);
}
}, 100, 100, TimeUnit.MILLISECONDS));
out.add(amsSerialFrame.getByteBuf());
}
use of org.apache.plc4x.java.api.exceptions.PlcProtocolPayloadTooBigException in project plc4x by apache.
the class Device method of.
public static Device of(String value, Charset charset) {
requireNonNull(value);
requireNonNull(charset);
byte[] bytes = value.getBytes(charset);
if (bytes.length > NUM_BYTES) {
throw new PlcRuntimeException(new PlcProtocolPayloadTooBigException("ADS/AMS", NUM_BYTES, bytes.length, value));
}
return new Device(Arrays.copyOf(bytes, NUM_BYTES));
}
Aggregations