Search in sources :

Example 21 with PlcRuntimeException

use of org.apache.plc4x.java.api.exceptions.PlcRuntimeException in project plc4x by apache.

the class PooledPlcDriverManager method getStatistics.

// TODO: maybe export to jmx // generic poolKey has builtin jmx too
public Map<String, Number> getStatistics() {
    HashMap<String, Number> statistics = new HashMap<>();
    statistics.put("numActive", keyedObjectPool.getNumActive());
    statistics.put("numIdle", keyedObjectPool.getNumIdle());
    if (keyedObjectPool instanceof GenericKeyedObjectPool) {
        GenericKeyedObjectPool<PoolKey, PlcConnection> genericKeyedObjectPool = (GenericKeyedObjectPool<PoolKey, PlcConnection>) this.keyedObjectPool;
        // Thats pretty ugly and we really should't do that...
        try {
            Map poolMap = (Map) FieldUtils.getField(GenericKeyedObjectPool.class, "poolMap", true).get(this.keyedObjectPool);
            statistics.put("pools.count", poolMap.size());
        } catch (IllegalAccessException e) {
            throw new PlcRuntimeException(e);
        }
        Map<String, Integer> numActivePerKey = genericKeyedObjectPool.getNumActivePerKey();
        for (Map.Entry<String, Integer> entry : numActivePerKey.entrySet()) {
            statistics.put(entry.getKey() + ".numActive", entry.getValue());
        }
    }
    return statistics;
}
Also used : PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) HashMap(java.util.HashMap) GenericKeyedObjectPool(org.apache.commons.pool2.impl.GenericKeyedObjectPool) PlcConnection(org.apache.plc4x.java.api.PlcConnection) HashMap(java.util.HashMap) Map(java.util.Map)

Example 22 with PlcRuntimeException

use of org.apache.plc4x.java.api.exceptions.PlcRuntimeException in project plc4x by apache.

the class LittleEndianEncoder method encodeData.

public static byte[] encodeData(AdsDataType adsDataType, Object... values) throws PlcProtocolException {
    if (values.length == 0) {
        return new byte[] {};
    }
    Class<?> valueType = values[0].getClass();
    Stream<byte[]> result;
    if (valueType == Boolean.class) {
        result = encodeBoolean(adsDataType, Arrays.stream(values).map(Boolean.class::cast));
    } else if (valueType == Byte.class) {
        result = encodeByte(adsDataType, Arrays.stream(values).map(Byte.class::cast));
    } else if (valueType == Short.class) {
        result = encodeShort(adsDataType, Arrays.stream(values).map(Short.class::cast));
    } else if (valueType == Integer.class) {
        result = encodeInteger(adsDataType, Arrays.stream(values).map(Integer.class::cast));
    } else if (valueType == Long.class) {
        result = encodeLong(adsDataType, Arrays.stream(values).map(Long.class::cast));
    } else if (valueType == BigInteger.class) {
        result = encodeBigInteger(adsDataType, Arrays.stream(values).map(BigInteger.class::cast));
    } else if (valueType == LocalTime.class) {
        result = encodeLocalTime(adsDataType, Arrays.stream(values).map(LocalTime.class::cast));
    } else if (valueType == LocalDate.class) {
        result = encodeLocalDate(adsDataType, Arrays.stream(values).map(LocalDate.class::cast));
    } else if (valueType == LocalDateTime.class) {
        result = encodeLocalDateTime(adsDataType, Arrays.stream(values).map(LocalDateTime.class::cast));
    } else if (valueType == Float.class) {
        result = encodeFloat(adsDataType, Arrays.stream(values).map(Float.class::cast));
    } else if (valueType == Double.class) {
        result = encodeDouble(adsDataType, Arrays.stream(values).map(Double.class::cast));
    } else if (valueType == String.class) {
        result = encodeString(adsDataType, Arrays.stream(values).map(String.class::cast));
    } else if (valueType == byte[].class) {
        result = encodeByteArray(adsDataType, Arrays.stream(values).map(byte[].class::cast));
    } else if (valueType == Byte[].class) {
        result = encodeBigByteArray(adsDataType, Arrays.stream(values).map(Byte[].class::cast));
    } else {
        throw new PlcUnsupportedDataTypeException(valueType);
    }
    // TODO: maybe we can replace this by a smarter flatmap
    try {
        return result.collect(ByteArrayOutputStream::new, (bos, byteValue) -> {
            try {
                bos.write(byteValue);
            } catch (IOException e) {
                throw new PlcRuntimeException(e);
            }
        }, (a, b) -> {
        }).toByteArray();
    } catch (PlcRuntimeException e) {
        throw new PlcProtocolException("Error encoding data", e);
    }
}
Also used : Arrays(java.util.Arrays) ByteArrayOutputStream(java.io.ByteArrayOutputStream) PlcUnsupportedDataTypeException(org.apache.plc4x.java.api.exceptions.PlcUnsupportedDataTypeException) PlcProtocolPayloadTooBigException(org.apache.plc4x.java.api.exceptions.PlcProtocolPayloadTooBigException) ArrayUtils(org.apache.commons.lang3.ArrayUtils) IOException(java.io.IOException) java.time(java.time) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) ChronoUnit(java.time.temporal.ChronoUnit) Stream(java.util.stream.Stream) Charset(java.nio.charset.Charset) BigInteger(java.math.BigInteger) AdsDataType(org.apache.plc4x.java.ads.model.AdsDataType) PlcProtocolException(org.apache.plc4x.java.api.exceptions.PlcProtocolException) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) PlcProtocolException(org.apache.plc4x.java.api.exceptions.PlcProtocolException) IOException(java.io.IOException) BigInteger(java.math.BigInteger) PlcUnsupportedDataTypeException(org.apache.plc4x.java.api.exceptions.PlcUnsupportedDataTypeException) BigInteger(java.math.BigInteger)

Example 23 with PlcRuntimeException

use of org.apache.plc4x.java.api.exceptions.PlcRuntimeException in project plc4x by apache.

the class Payload2SerialProtocol method decode.

@Override
protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> out) throws Exception {
    LOGGER.trace("(-->IN): {}, {}, {}", channelHandlerContext, byteBuf, out);
    if (byteBuf.readableBytes() < MagicCookie.NUM_BYTES + TransmitterAddress.NUM_BYTES + ReceiverAddress.NUM_BYTES + FragmentNumber.NUM_BYTES) {
        return;
    }
    MagicCookie magicCookie = MagicCookie.of(byteBuf);
    TransmitterAddress transmitterAddress = TransmitterAddress.of(byteBuf);
    ReceiverAddress receiverAddress = ReceiverAddress.of(byteBuf);
    FragmentNumber fragmentNumber = FragmentNumber.of(byteBuf);
    int expectedFrameNumber = fragmentCounter.get() - 1;
    if (expectedFrameNumber < 0) {
        expectedFrameNumber = 255;
    }
    if (fragmentNumber.getAsByte() != expectedFrameNumber) {
        LOGGER.warn("Unexpected fragment {} received. Expected {}", fragmentNumber, expectedFrameNumber);
    }
    UserDataLength userDataLength = UserDataLength.of(byteBuf);
    UserData userData;
    byte userDataLengthAsByte = userDataLength.getAsByte();
    if (byteBuf.readableBytes() < userDataLengthAsByte) {
        return;
    }
    if (userDataLengthAsByte > 0) {
        byte[] userDataByteArray = new byte[userDataLengthAsByte];
        byteBuf.readBytes(userDataByteArray);
        userData = UserData.of(userDataByteArray);
    } else {
        userData = UserData.EMPTY;
    }
    CRC crc = CRC.of(byteBuf);
    // we don't need to retransmit
    ScheduledFuture<?> scheduledFuture = currentRetryer.get();
    if (scheduledFuture != null) {
        scheduledFuture.cancel(false);
    }
    Runnable postAction = null;
    switch(magicCookie.getAsInt()) {
        case AmsSerialFrame.ID:
            AmsSerialFrame amsSerialFrame = AmsSerialFrame.of(magicCookie, transmitterAddress, receiverAddress, fragmentNumber, userDataLength, userData, crc);
            LOGGER.debug("Ams Serial Frame received {}", amsSerialFrame);
            postAction = () -> {
                // TODO: check if this is the right way to ack a package.
                ChannelFuture channelFuture = channelHandlerContext.writeAndFlush(AmsSerialAcknowledgeFrame.of(transmitterAddress, receiverAddress, fragmentNumber).getByteBuf());
                // waiting for the ack-frame to be transmitted before we forward the package
                try {
                    channelFuture.await();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    throw new PlcRuntimeException(e);
                }
                out.add(userData.getByteBuf());
            };
            break;
        case AmsSerialAcknowledgeFrame.ID:
            AmsSerialAcknowledgeFrame amsSerialAcknowledgeFrame = AmsSerialAcknowledgeFrame.of(magicCookie, transmitterAddress, receiverAddress, fragmentNumber, userDataLength, crc);
            LOGGER.debug("Ams Serial ACK Frame received {}", amsSerialAcknowledgeFrame);
            ReferenceCountUtil.release(byteBuf);
            break;
        case AmsSerialResetFrame.ID:
            // TODO: how to react to a reset
            AmsSerialResetFrame amsSerialResetFrame = AmsSerialResetFrame.of(magicCookie, transmitterAddress, receiverAddress, fragmentNumber, userDataLength, crc);
            LOGGER.debug("Ams Serial Reset Frame received {}", amsSerialResetFrame);
            ReferenceCountUtil.release(byteBuf);
            break;
        default:
            throw new PlcProtocolException("Unknown type: " + magicCookie);
    }
    CRC calculatedCrc = CRC.of(DigestUtil.calculateCrc16(magicCookie, transmitterAddress, receiverAddress, fragmentNumber, userDataLength, userData));
    if (!crc.equals(calculatedCrc)) {
        throw new PlcProtocolException("CRC checksum wrong. Got " + crc + " expected " + calculatedCrc);
    }
    if (postAction != null) {
        postAction.run();
    }
    if (byteBuf.readableBytes() > 0) {
        throw new IllegalStateException("Unread bytes left: " + byteBuf.readableBytes());
    }
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) AmsSerialFrame(org.apache.plc4x.java.ads.api.serial.AmsSerialFrame) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) AmsSerialResetFrame(org.apache.plc4x.java.ads.api.serial.AmsSerialResetFrame) PlcProtocolException(org.apache.plc4x.java.api.exceptions.PlcProtocolException) AmsSerialAcknowledgeFrame(org.apache.plc4x.java.ads.api.serial.AmsSerialAcknowledgeFrame)

Example 24 with PlcRuntimeException

use of org.apache.plc4x.java.api.exceptions.PlcRuntimeException in project plc4x by apache.

the class BacNetIpProtocolLogic method setConfiguration.

@Override
public void setConfiguration(BacNetIpConfiguration configuration) {
    if (configuration.getEdeFilePath() != null) {
        File edeFile = new File(configuration.getEdeFilePath());
        if (!edeFile.exists() || !edeFile.isFile()) {
            throw new PlcRuntimeException(String.format("File specified with 'ede-file-path' does not exist or is not a file: '%s'", configuration.getEdeFilePath()));
        }
        edeModel = new EdeParser().parseFile(edeFile);
    } else if (configuration.getEdeDirectoryPath() != null) {
        File edeDirectory = new File(configuration.getEdeDirectoryPath());
        if (!edeDirectory.exists() || !edeDirectory.isDirectory()) {
            throw new PlcRuntimeException(String.format("File specified with 'ede-directory-path' does not exist or is not a directory: '%s'", configuration.getEdeDirectoryPath()));
        }
        edeModel = new EdeParser().parseDirectory(edeDirectory);
    }
}
Also used : PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) EdeParser(org.apache.plc4x.java.bacnetip.ede.EdeParser) File(java.io.File)

Example 25 with PlcRuntimeException

use of org.apache.plc4x.java.api.exceptions.PlcRuntimeException in project plc4x by apache.

the class AdsProtocolLogic method multiWrite.

protected CompletableFuture<PlcWriteResponse> multiWrite(PlcWriteRequest writeRequest, List<DirectAdsField> directAdsFields) {
    CompletableFuture<PlcWriteResponse> future = new CompletableFuture<>();
    // Calculate the size of all fields together.
    // Calculate the expected size of the response data.
    int expectedRequestDataSize = directAdsFields.stream().mapToInt(field -> field.getAdsDataType().getNumBytes() * field.getNumberOfElements()).sum();
    byte[] writeBuffer = new byte[expectedRequestDataSize];
    int pos = 0;
    for (String fieldName : writeRequest.getFieldNames()) {
        final AdsField field = (AdsField) writeRequest.getField(fieldName);
        final PlcValue plcValue = writeRequest.getPlcValue(fieldName);
        final int stringLength;
        if (field.getAdsDataType() == AdsDataType.STRING) {
            stringLength = plcValue.getString().length() + 1;
        } else {
            if (field.getAdsDataType() == AdsDataType.WSTRING) {
                stringLength = (plcValue.getString().length() + 1) * 2;
            } else {
                stringLength = 0;
            }
        }
        try {
            WriteBufferByteBased itemWriteBuffer = new WriteBufferByteBased(DataItem.getLengthInBytes(plcValue, field.getAdsDataType().getDataFormatName(), stringLength));
            DataItem.staticSerialize(itemWriteBuffer, plcValue, field.getAdsDataType().getDataFormatName(), stringLength, ByteOrder.LITTLE_ENDIAN);
            int numBytes = itemWriteBuffer.getPos();
            System.arraycopy(itemWriteBuffer.getData(), 0, writeBuffer, pos, numBytes);
            pos += numBytes;
        } catch (Exception e) {
            throw new PlcRuntimeException("Error serializing data", e);
        }
    }
    // With multi-requests, the index-group is fixed and the index offset indicates the number of elements.
    AdsData adsData = new AdsReadWriteRequest(ReservedIndexGroups.ADSIGRP_MULTIPLE_WRITE.getValue(), directAdsFields.size(), (long) directAdsFields.size() * 4, directAdsFields.stream().map(directAdsField -> new AdsMultiRequestItemWrite(directAdsField.getIndexGroup(), directAdsField.getIndexOffset(), ((long) directAdsField.getAdsDataType().getNumBytes() * directAdsField.getNumberOfElements()))).collect(Collectors.toList()), writeBuffer);
    AmsPacket amsPacket = new AmsPacket(configuration.getTargetAmsNetId(), configuration.getTargetAmsPort(), configuration.getSourceAmsNetId(), configuration.getSourceAmsPort(), CommandId.ADS_READ_WRITE, DEFAULT_COMMAND_STATE, 0, getInvokeId(), adsData);
    AmsTCPPacket amsTCPPacket = new AmsTCPPacket(amsPacket);
    // Start a new request-transaction (Is ended in the response-handler)
    RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
    transaction.submit(() -> context.sendRequest(amsTCPPacket).expectResponse(AmsTCPPacket.class, Duration.ofMillis(configuration.getTimeoutRequest())).onTimeout(future::completeExceptionally).onError((p, e) -> future.completeExceptionally(e)).check(responseAmsPacket -> responseAmsPacket.getUserdata().getInvokeId() == amsPacket.getInvokeId()).unwrap(response -> (AdsReadWriteResponse) response.getUserdata().getData()).handle(responseAdsData -> {
        if (responseAdsData.getResult() == ReturnCode.OK) {
            final PlcWriteResponse plcWriteResponse = convertToPlc4xWriteResponse(writeRequest, responseAdsData);
            // Convert the response from the PLC into a PLC4X Response ...
            future.complete(plcWriteResponse);
        } else {
            // TODO: Implement this correctly.
            future.completeExceptionally(new PlcException("Error"));
        }
        // Finish the request-transaction.
        transaction.endRequest();
    }));
    return future;
}
Also used : IntStream(java.util.stream.IntStream) PlcSubscriptionType(org.apache.plc4x.java.api.types.PlcSubscriptionType) java.util(java.util) LoggerFactory(org.slf4j.LoggerFactory) PlcValue(org.apache.plc4x.java.api.value.PlcValue) DefaultPlcConsumerRegistration(org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration) CompletableFuture(java.util.concurrent.CompletableFuture) PlcConsumerRegistration(org.apache.plc4x.java.api.model.PlcConsumerRegistration) AdsSubscriptionHandle(org.apache.plc4x.java.ads.model.AdsSubscriptionHandle) PlcException(org.apache.plc4x.java.api.exceptions.PlcException) RequestTransactionManager(org.apache.plc4x.java.spi.transaction.RequestTransactionManager) ConversationContext(org.apache.plc4x.java.spi.ConversationContext) DefaultPlcSubscriptionField(org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionField) Duration(java.time.Duration) PlcResponseCode(org.apache.plc4x.java.api.types.PlcResponseCode) DataItem(org.apache.plc4x.java.ads.readwrite.DataItem) Plc4xProtocolBase(org.apache.plc4x.java.spi.Plc4xProtocolBase) BigInteger(java.math.BigInteger) Logger(org.slf4j.Logger) PlcSubscriptionHandle(org.apache.plc4x.java.api.model.PlcSubscriptionHandle) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) org.apache.plc4x.java.spi.messages(org.apache.plc4x.java.spi.messages) Instant(java.time.Instant) Collectors(java.util.stream.Collectors) org.apache.plc4x.java.ads.readwrite(org.apache.plc4x.java.ads.readwrite) PlcField(org.apache.plc4x.java.api.model.PlcField) IEC61131ValueHandler(org.apache.plc4x.java.spi.values.IEC61131ValueHandler) HasConfiguration(org.apache.plc4x.java.spi.configuration.HasConfiguration) org.apache.plc4x.java.spi.generation(org.apache.plc4x.java.spi.generation) Consumer(java.util.function.Consumer) AtomicLong(java.util.concurrent.atomic.AtomicLong) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) org.apache.plc4x.java.ads.field(org.apache.plc4x.java.ads.field) AdsConfiguration(org.apache.plc4x.java.ads.configuration.AdsConfiguration) ResponseItem(org.apache.plc4x.java.spi.messages.utils.ResponseItem) org.apache.plc4x.java.api.messages(org.apache.plc4x.java.api.messages) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) RequestTransactionManager(org.apache.plc4x.java.spi.transaction.RequestTransactionManager) PlcException(org.apache.plc4x.java.api.exceptions.PlcException) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) PlcException(org.apache.plc4x.java.api.exceptions.PlcException) CompletableFuture(java.util.concurrent.CompletableFuture) PlcValue(org.apache.plc4x.java.api.value.PlcValue)

Aggregations

PlcRuntimeException (org.apache.plc4x.java.api.exceptions.PlcRuntimeException)95 BigInteger (java.math.BigInteger)17 CompletableFuture (java.util.concurrent.CompletableFuture)14 PlcResponseCode (org.apache.plc4x.java.api.types.PlcResponseCode)14 PlcValue (org.apache.plc4x.java.api.value.PlcValue)14 ResponseItem (org.apache.plc4x.java.spi.messages.utils.ResponseItem)14 Duration (java.time.Duration)13 PlcField (org.apache.plc4x.java.api.model.PlcField)13 PlcConnectionException (org.apache.plc4x.java.api.exceptions.PlcConnectionException)10 HasConfiguration (org.apache.plc4x.java.spi.configuration.HasConfiguration)10 ParseException (org.apache.plc4x.java.spi.generation.ParseException)10 RequestTransactionManager (org.apache.plc4x.java.spi.transaction.RequestTransactionManager)10 Collections (java.util.Collections)9 DefaultPlcReadRequest (org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest)9 DefaultPlcWriteRequest (org.apache.plc4x.java.spi.messages.DefaultPlcWriteRequest)9 IOException (java.io.IOException)8 org.apache.plc4x.java.modbus.readwrite (org.apache.plc4x.java.modbus.readwrite)8 DefaultPlcReadResponse (org.apache.plc4x.java.spi.messages.DefaultPlcReadResponse)8 ModbusField (org.apache.plc4x.java.modbus.base.field.ModbusField)7 PlcList (org.apache.plc4x.java.spi.values.PlcList)7