Search in sources :

Example 1 with PlcProtocolPayloadTooBigException

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);
}
Also used : PlcProtocolException(org.apache.plc4x.java.api.exceptions.PlcProtocolException) SymbolicAdsField(org.apache.plc4x.java.ads.model.SymbolicAdsField) PlcField(org.apache.plc4x.java.api.model.PlcField) LittleEndianEncoder.encodeData(org.apache.plc4x.java.ads.protocol.util.LittleEndianEncoder.encodeData) Invoke(org.apache.plc4x.java.ads.api.generic.types.Invoke) PlcList(org.apache.plc4x.java.api.value.PlcList) PlcValue(org.apache.plc4x.java.api.value.PlcValue) DirectAdsField(org.apache.plc4x.java.ads.model.DirectAdsField) PlcProtocolPayloadTooBigException(org.apache.plc4x.java.api.exceptions.PlcProtocolPayloadTooBigException) AmsPacket(org.apache.plc4x.java.ads.api.generic.AmsPacket)

Example 2 with PlcProtocolPayloadTooBigException

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());
}
Also used : AmsSerialFrame(org.apache.plc4x.java.ads.api.serial.AmsSerialFrame) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) MutableInt(org.apache.commons.lang3.mutable.MutableInt) PlcProtocolPayloadTooBigException(org.apache.plc4x.java.api.exceptions.PlcProtocolPayloadTooBigException)

Example 3 with PlcProtocolPayloadTooBigException

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));
}
Also used : PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) PlcProtocolPayloadTooBigException(org.apache.plc4x.java.api.exceptions.PlcProtocolPayloadTooBigException)

Aggregations

PlcProtocolPayloadTooBigException (org.apache.plc4x.java.api.exceptions.PlcProtocolPayloadTooBigException)3 PlcRuntimeException (org.apache.plc4x.java.api.exceptions.PlcRuntimeException)2 MutableInt (org.apache.commons.lang3.mutable.MutableInt)1 AmsPacket (org.apache.plc4x.java.ads.api.generic.AmsPacket)1 Invoke (org.apache.plc4x.java.ads.api.generic.types.Invoke)1 AmsSerialFrame (org.apache.plc4x.java.ads.api.serial.AmsSerialFrame)1 DirectAdsField (org.apache.plc4x.java.ads.model.DirectAdsField)1 SymbolicAdsField (org.apache.plc4x.java.ads.model.SymbolicAdsField)1 LittleEndianEncoder.encodeData (org.apache.plc4x.java.ads.protocol.util.LittleEndianEncoder.encodeData)1 PlcProtocolException (org.apache.plc4x.java.api.exceptions.PlcProtocolException)1 PlcField (org.apache.plc4x.java.api.model.PlcField)1 PlcList (org.apache.plc4x.java.api.value.PlcList)1 PlcValue (org.apache.plc4x.java.api.value.PlcValue)1