Search in sources :

Example 1 with ConversationContext

use of org.apache.plc4x.java.spi.ConversationContext in project plc4x by apache.

the class SecureChannel method onDiscoverGetEndpointsRequest.

public void onDiscoverGetEndpointsRequest(ConversationContext<OpcuaAPU> context, OpcuaOpenResponse opcuaOpenResponse, OpenSecureChannelResponse openSecureChannelResponse) throws PlcConnectionException {
    tokenId.set((int) ((ChannelSecurityToken) openSecureChannelResponse.getSecurityToken()).getTokenId());
    channelId.set((int) ((ChannelSecurityToken) openSecureChannelResponse.getSecurityToken()).getChannelId());
    int transactionId = channelTransactionManager.getTransactionIdentifier();
    int nextSequenceNumber = opcuaOpenResponse.getSequenceNumber() + 1;
    int nextRequestId = opcuaOpenResponse.getRequestId() + 1;
    if (!(transactionId == nextSequenceNumber)) {
        LOGGER.error("Sequence number isn't as expected, we might have missed a packet. - " + transactionId + " != " + nextSequenceNumber);
        throw new PlcConnectionException("Sequence number isn't as expected, we might have missed a packet. - " + transactionId + " != " + nextSequenceNumber);
    }
    RequestHeader requestHeader = new RequestHeader(new NodeId(authenticationToken), getCurrentDateTime(), 0L, 0L, NULL_STRING, REQUEST_TIMEOUT_LONG, NULL_EXTENSION_OBJECT);
    GetEndpointsRequest endpointsRequest = new GetEndpointsRequest(requestHeader, this.endpoint, 0, null, 0, null);
    ExpandedNodeId expandedNodeId = new // Namespace Uri Specified
    ExpandedNodeId(// Namespace Uri Specified
    false, // Server Index Specified
    false, new NodeIdFourByte((short) 0, Integer.parseInt(endpointsRequest.getIdentifier())), null, null);
    try {
        WriteBufferByteBased buffer = new WriteBufferByteBased(endpointsRequest.getLengthInBytes(), org.apache.plc4x.java.spi.generation.ByteOrder.LITTLE_ENDIAN);
        new ExtensionObject(expandedNodeId, null, endpointsRequest, false).serialize(buffer);
        OpcuaMessageRequest messageRequest = new OpcuaMessageRequest(FINAL_CHUNK, channelId.get(), tokenId.get(), nextSequenceNumber, nextRequestId, buffer.getData());
        Consumer<Integer> requestConsumer = t -> context.sendRequest(new OpcuaAPU(messageRequest, false)).expectResponse(OpcuaAPU.class, REQUEST_TIMEOUT).check(p -> p.getMessage() instanceof OpcuaMessageResponse).unwrap(p -> (OpcuaMessageResponse) p.getMessage()).check(p -> p.getRequestId() == transactionId).handle(opcuaMessageResponse -> {
            try {
                ExtensionObject message = ExtensionObject.staticParse(new ReadBufferByteBased(opcuaMessageResponse.getMessage(), org.apache.plc4x.java.spi.generation.ByteOrder.LITTLE_ENDIAN), false);
                if (message.getBody() instanceof ServiceFault) {
                    ServiceFault fault = (ServiceFault) message.getBody();
                    LOGGER.error("Failed to connect to opc ua server for the following reason:- {}, {}", ((ResponseHeader) fault.getResponseHeader()).getServiceResult().getStatusCode(), OpcuaStatusCode.enumForValue(((ResponseHeader) fault.getResponseHeader()).getServiceResult().getStatusCode()));
                } else {
                    LOGGER.debug("Got Create Session Response Connection Response");
                    GetEndpointsResponse response = (GetEndpointsResponse) message.getBody();
                    List<ExtensionObjectDefinition> endpoints = response.getEndpoints();
                    for (ExtensionObjectDefinition endpoint : endpoints) {
                        EndpointDescription endpointDescription = (EndpointDescription) endpoint;
                        if (endpointDescription.getEndpointUrl().getStringValue().equals(this.endpoint.getStringValue()) && endpointDescription.getSecurityPolicyUri().getStringValue().equals(this.securityPolicy)) {
                            LOGGER.info("Found OPC UA endpoint {}", this.endpoint.getStringValue());
                            this.configuration.setSenderCertificate(endpointDescription.getServerCertificate().getStringValue());
                        }
                    }
                    try {
                        MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
                        byte[] digest = messageDigest.digest(this.configuration.getSenderCertificate());
                        this.configuration.setThumbprint(new PascalByteString(digest.length, digest));
                    } catch (NoSuchAlgorithmException e) {
                        LOGGER.error("Failed to find hashing algorithm");
                    }
                    onDiscoverCloseSecureChannel(context, response);
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
        });
        channelTransactionManager.submit(requestConsumer, transactionId);
    } catch (SerializationException e) {
        LOGGER.error("Unable to to Parse Create Session Request");
    }
}
Also used : RandomUtils(org.apache.commons.lang3.RandomUtils) ByteArrayOutputStream(java.io.ByteArrayOutputStream) DriverContext(org.apache.plc4x.java.spi.context.DriverContext) MessageDigest(java.security.MessageDigest) LoggerFactory(org.slf4j.LoggerFactory) TimeoutException(java.util.concurrent.TimeoutException) CompletableFuture(java.util.concurrent.CompletableFuture) ByteBuffer(java.nio.ByteBuffer) ArrayList(java.util.ArrayList) InetAddress(java.net.InetAddress) Matcher(java.util.regex.Matcher) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) PlcConnectionException(org.apache.plc4x.java.api.exceptions.PlcConnectionException) ConversationContext(org.apache.plc4x.java.spi.ConversationContext) Duration(java.time.Duration) org.apache.plc4x.java.opcua.readwrite(org.apache.plc4x.java.opcua.readwrite) BiConsumer(java.util.function.BiConsumer) Logger(org.slf4j.Logger) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) org.apache.plc4x.java.spi.generation(org.apache.plc4x.java.spi.generation) Consumer(java.util.function.Consumer) ByteOrder(java.nio.ByteOrder) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) Stream(java.util.stream.Stream) OpcuaConfiguration(org.apache.plc4x.java.opcua.config.OpcuaConfiguration) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) RandomStringUtils(org.apache.commons.lang3.RandomStringUtils) Pattern(java.util.regex.Pattern) CertificateEncodingException(java.security.cert.CertificateEncodingException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) MessageDigest(java.security.MessageDigest) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) PlcConnectionException(org.apache.plc4x.java.api.exceptions.PlcConnectionException)

Example 2 with ConversationContext

use of org.apache.plc4x.java.spi.ConversationContext in project plc4x by apache.

the class SecureChannel method onConnectActivateSessionRequest.

private void onConnectActivateSessionRequest(ConversationContext<OpcuaAPU> context, CreateSessionResponse opcuaMessageResponse, CreateSessionResponse sessionResponse) throws PlcConnectionException, ParseException {
    senderCertificate = sessionResponse.getServerCertificate().getStringValue();
    encryptionHandler.setServerCertificate(EncryptionHandler.getCertificateX509(senderCertificate));
    this.senderNonce = sessionResponse.getServerNonce().getStringValue();
    String[] endpoints = new String[3];
    try {
        InetAddress address = InetAddress.getByName(this.configuration.getHost());
        endpoints[0] = "opc.tcp://" + address.getHostAddress() + ":" + configuration.getPort() + configuration.getTransportEndpoint();
        endpoints[1] = "opc.tcp://" + address.getHostName() + ":" + configuration.getPort() + configuration.getTransportEndpoint();
        endpoints[2] = "opc.tcp://" + address.getCanonicalHostName() + ":" + configuration.getPort() + configuration.getTransportEndpoint();
    } catch (UnknownHostException e) {
        e.printStackTrace();
    }
    selectEndpoint(sessionResponse);
    if (this.policyId == null) {
        throw new PlcRuntimeException("Unable to find endpoint - " + endpoints[1]);
    }
    ExtensionObject userIdentityToken = getIdentityToken(this.tokenType, policyId.getStringValue());
    int requestHandle = getRequestHandle();
    RequestHeader requestHeader = new RequestHeader(new NodeId(authenticationToken), getCurrentDateTime(), requestHandle, 0L, NULL_STRING, REQUEST_TIMEOUT_LONG, NULL_EXTENSION_OBJECT);
    SignatureData clientSignature = new SignatureData(NULL_STRING, NULL_BYTE_STRING);
    ActivateSessionRequest activateSessionRequest = new ActivateSessionRequest(requestHeader, clientSignature, 0, null, 0, null, userIdentityToken, clientSignature);
    ExpandedNodeId expandedNodeId = new // Namespace Uri Specified
    ExpandedNodeId(// Namespace Uri Specified
    false, // Server Index Specified
    false, new NodeIdFourByte((short) 0, Integer.parseInt(activateSessionRequest.getIdentifier())), null, null);
    ExtensionObject extObject = new ExtensionObject(expandedNodeId, null, activateSessionRequest, false);
    try {
        WriteBufferByteBased buffer = new WriteBufferByteBased(extObject.getLengthInBytes(), org.apache.plc4x.java.spi.generation.ByteOrder.LITTLE_ENDIAN);
        extObject.serialize(buffer);
        Consumer<byte[]> consumer = opcuaResponse -> {
            try {
                ExtensionObject message = ExtensionObject.staticParse(new ReadBufferByteBased(opcuaResponse, org.apache.plc4x.java.spi.generation.ByteOrder.LITTLE_ENDIAN), false);
                if (message.getBody() instanceof ServiceFault) {
                    ServiceFault fault = (ServiceFault) message.getBody();
                    LOGGER.error("Failed to connect to opc ua server for the following reason:- {}, {}", ((ResponseHeader) fault.getResponseHeader()).getServiceResult().getStatusCode(), OpcuaStatusCode.enumForValue(((ResponseHeader) fault.getResponseHeader()).getServiceResult().getStatusCode()));
                } else {
                    LOGGER.debug("Got Activate Session Response Connection Response");
                    try {
                        ActivateSessionResponse responseMessage;
                        ExtensionObjectDefinition unknownExtensionObject = ExtensionObject.staticParse(new ReadBufferByteBased(opcuaResponse, org.apache.plc4x.java.spi.generation.ByteOrder.LITTLE_ENDIAN), false).getBody();
                        if (unknownExtensionObject instanceof ActivateSessionResponse) {
                            responseMessage = (ActivateSessionResponse) unknownExtensionObject;
                            long returnedRequestHandle = ((ResponseHeader) responseMessage.getResponseHeader()).getRequestHandle();
                            if (!(requestHandle == returnedRequestHandle)) {
                                LOGGER.error("Request handle isn't as expected, we might have missed a packet. {} != {}", requestHandle, returnedRequestHandle);
                            }
                            // Send an event that connection setup is complete.
                            keepAlive();
                            context.fireConnected();
                        } else {
                            ServiceFault serviceFault = (ServiceFault) unknownExtensionObject;
                            ResponseHeader header = (ResponseHeader) serviceFault.getResponseHeader();
                            LOGGER.error("Subscription ServiceFault returned from server with error code,  '{}'", header.getServiceResult().toString());
                        }
                    } catch (ParseException e) {
                        LOGGER.error("Unable to parse the returned Subscription response");
                        e.printStackTrace();
                    }
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
        };
        Consumer<TimeoutException> timeout = e -> {
            LOGGER.error("Timeout while waiting for activate session response");
            e.printStackTrace();
        };
        BiConsumer<OpcuaAPU, Throwable> error = (message, e) -> {
            LOGGER.error("Error while waiting for activate session response");
            e.printStackTrace();
        };
        submit(context, timeout, error, consumer, buffer);
    } catch (SerializationException e) {
        LOGGER.error("Unable to to Parse Activate Session Request");
    }
}
Also used : RandomUtils(org.apache.commons.lang3.RandomUtils) ByteArrayOutputStream(java.io.ByteArrayOutputStream) DriverContext(org.apache.plc4x.java.spi.context.DriverContext) MessageDigest(java.security.MessageDigest) LoggerFactory(org.slf4j.LoggerFactory) TimeoutException(java.util.concurrent.TimeoutException) CompletableFuture(java.util.concurrent.CompletableFuture) ByteBuffer(java.nio.ByteBuffer) ArrayList(java.util.ArrayList) InetAddress(java.net.InetAddress) Matcher(java.util.regex.Matcher) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) PlcConnectionException(org.apache.plc4x.java.api.exceptions.PlcConnectionException) ConversationContext(org.apache.plc4x.java.spi.ConversationContext) Duration(java.time.Duration) org.apache.plc4x.java.opcua.readwrite(org.apache.plc4x.java.opcua.readwrite) BiConsumer(java.util.function.BiConsumer) Logger(org.slf4j.Logger) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) org.apache.plc4x.java.spi.generation(org.apache.plc4x.java.spi.generation) Consumer(java.util.function.Consumer) ByteOrder(java.nio.ByteOrder) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) Stream(java.util.stream.Stream) OpcuaConfiguration(org.apache.plc4x.java.opcua.config.OpcuaConfiguration) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) RandomStringUtils(org.apache.commons.lang3.RandomStringUtils) Pattern(java.util.regex.Pattern) CertificateEncodingException(java.security.cert.CertificateEncodingException) TimeoutException(java.util.concurrent.TimeoutException) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) UnknownHostException(java.net.UnknownHostException) InetAddress(java.net.InetAddress)

Example 3 with ConversationContext

use of org.apache.plc4x.java.spi.ConversationContext in project plc4x by apache.

the class SecureChannel method submit.

public void submit(ConversationContext<OpcuaAPU> context, Consumer<TimeoutException> onTimeout, BiConsumer<OpcuaAPU, Throwable> error, Consumer<byte[]> consumer, WriteBufferByteBased buffer) {
    int transactionId = channelTransactionManager.getTransactionIdentifier();
    // TODO: We need to split large messages up into chunks if it is larger than the sendBufferSize
    // This value is negotiated when opening a channel
    OpcuaMessageRequest messageRequest = new OpcuaMessageRequest(FINAL_CHUNK, channelId.get(), tokenId.get(), transactionId, transactionId, buffer.getData());
    final OpcuaAPU apu;
    try {
        if (this.isEncrypted) {
            apu = OpcuaAPU.staticParse(encryptionHandler.encodeMessage(messageRequest, buffer.getData()), false);
        } else {
            apu = new OpcuaAPU(messageRequest, false);
        }
    } catch (ParseException e) {
        throw new PlcRuntimeException("Unable to encrypt message before sending");
    }
    Consumer<Integer> requestConsumer = t -> {
        try {
            ByteArrayOutputStream messageBuffer = new ByteArrayOutputStream();
            context.sendRequest(apu).expectResponse(OpcuaAPU.class, REQUEST_TIMEOUT).onTimeout(onTimeout).onError(error).unwrap(encryptionHandler::decodeMessage).unwrap(OpcuaAPU::getMessage).check(OpcuaMessageResponse.class::isInstance).unwrap(OpcuaMessageResponse.class::cast).check(p -> {
                if (p.getRequestId() == transactionId) {
                    try {
                        messageBuffer.write(p.getMessage());
                        if (!(senderSequenceNumber.incrementAndGet() == (p.getSequenceNumber()))) {
                            LOGGER.error("Sequence number isn't as expected, we might have missed a packet. - {} != {}", senderSequenceNumber.incrementAndGet(), p.getSequenceNumber());
                            context.fireDisconnected();
                        }
                    } catch (IOException e) {
                        LOGGER.debug("Failed to store incoming message in buffer");
                        throw new PlcRuntimeException("Error while sending message");
                    }
                    return p.getChunk().equals(FINAL_CHUNK);
                } else {
                    return false;
                }
            }).handle(opcuaResponse -> {
                if (opcuaResponse.getChunk().equals(FINAL_CHUNK)) {
                    tokenId.set(opcuaResponse.getSecureTokenId());
                    channelId.set(opcuaResponse.getSecureChannelId());
                    consumer.accept(messageBuffer.toByteArray());
                }
            });
        } catch (Exception e) {
            throw new PlcRuntimeException("Error while sending message");
        }
    };
    LOGGER.debug("Submitting Transaction to TransactionManager {}", transactionId);
    channelTransactionManager.submit(requestConsumer, transactionId);
}
Also used : RandomUtils(org.apache.commons.lang3.RandomUtils) ByteArrayOutputStream(java.io.ByteArrayOutputStream) DriverContext(org.apache.plc4x.java.spi.context.DriverContext) MessageDigest(java.security.MessageDigest) LoggerFactory(org.slf4j.LoggerFactory) TimeoutException(java.util.concurrent.TimeoutException) CompletableFuture(java.util.concurrent.CompletableFuture) ByteBuffer(java.nio.ByteBuffer) ArrayList(java.util.ArrayList) InetAddress(java.net.InetAddress) Matcher(java.util.regex.Matcher) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) PlcConnectionException(org.apache.plc4x.java.api.exceptions.PlcConnectionException) ConversationContext(org.apache.plc4x.java.spi.ConversationContext) Duration(java.time.Duration) org.apache.plc4x.java.opcua.readwrite(org.apache.plc4x.java.opcua.readwrite) BiConsumer(java.util.function.BiConsumer) Logger(org.slf4j.Logger) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) org.apache.plc4x.java.spi.generation(org.apache.plc4x.java.spi.generation) Consumer(java.util.function.Consumer) ByteOrder(java.nio.ByteOrder) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) Stream(java.util.stream.Stream) OpcuaConfiguration(org.apache.plc4x.java.opcua.config.OpcuaConfiguration) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) RandomStringUtils(org.apache.commons.lang3.RandomStringUtils) Pattern(java.util.regex.Pattern) CertificateEncodingException(java.security.cert.CertificateEncodingException) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) TimeoutException(java.util.concurrent.TimeoutException) PlcConnectionException(org.apache.plc4x.java.api.exceptions.PlcConnectionException) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) CertificateEncodingException(java.security.cert.CertificateEncodingException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger)

Example 4 with ConversationContext

use of org.apache.plc4x.java.spi.ConversationContext in project plc4x by apache.

the class KnxNetIpProtocolLogic method onConnect.

@Override
public void onConnect(ConversationContext<KnxNetIpMessage> context) {
    // Only the UDP transport supports login.
    if (!context.isPassive()) {
        LOGGER.info("KNX Driver running in ACTIVE mode.");
        knxNetIpDriverContext.setPassiveMode(false);
        DatagramChannel channel = (DatagramChannel) context.getChannel();
        final InetSocketAddress localSocketAddress = channel.localAddress();
        knxNetIpDriverContext.setLocalIPAddress(new IPAddress(localSocketAddress.getAddress().getAddress()));
        knxNetIpDriverContext.setLocalPort(localSocketAddress.getPort());
        // First send out a search request
        // REMARK: This might be optional ... usually we would send a search request to ip 224.0.23.12
        // Any KNX Gateway will respond with a search response. We're currently directly sending to the
        // known gateway address, so it's sort of pointless, but at least only one device will respond.
        LOGGER.info("Sending KNXnet/IP Search Request.");
        SearchRequest searchRequest = new SearchRequest(new HPAIDiscoveryEndpoint(HostProtocolCode.IPV4_UDP, knxNetIpDriverContext.getLocalIPAddress(), knxNetIpDriverContext.getLocalPort()));
        context.sendRequest(searchRequest).expectResponse(KnxNetIpMessage.class, Duration.ofMillis(1000)).check(p -> p instanceof SearchResponse).unwrap(p -> (SearchResponse) p).handle(searchResponse -> {
            LOGGER.info("Got KNXnet/IP Search Response.");
            // Check if this device supports tunneling services.
            final ServiceId tunnelingService = searchResponse.getDibSuppSvcFamilies().getServiceIds().stream().filter(serviceId -> serviceId instanceof KnxNetIpTunneling).findFirst().orElse(null);
            // If this device supports this type of service, tell the driver, we found a suitable device.
            if (tunnelingService != null) {
                // Extract the required information form the search request.
                knxNetIpDriverContext.setGatewayAddress(searchResponse.getDibDeviceInfo().getKnxAddress());
                knxNetIpDriverContext.setGatewayName(new String(searchResponse.getDibDeviceInfo().getDeviceFriendlyName()).trim());
                LOGGER.info(String.format("Found KNXnet/IP Gateway '%s' with KNX address '%d.%d.%d'", knxNetIpDriverContext.getGatewayName(), knxNetIpDriverContext.getGatewayAddress().getMainGroup(), knxNetIpDriverContext.getGatewayAddress().getMiddleGroup(), knxNetIpDriverContext.getGatewayAddress().getSubGroup()));
                // Next send a connection request to the gateway.
                ConnectionRequest connectionRequest = new ConnectionRequest(new HPAIDiscoveryEndpoint(HostProtocolCode.IPV4_UDP, knxNetIpDriverContext.getLocalIPAddress(), knxNetIpDriverContext.getLocalPort()), new HPAIDataEndpoint(HostProtocolCode.IPV4_UDP, knxNetIpDriverContext.getLocalIPAddress(), knxNetIpDriverContext.getLocalPort()), new ConnectionRequestInformationTunnelConnection(knxNetIpDriverContext.getTunnelConnectionType()));
                LOGGER.info("Sending KNXnet/IP Connection Request.");
                context.sendRequest(connectionRequest).expectResponse(KnxNetIpMessage.class, Duration.ofMillis(1000)).check(p -> p instanceof ConnectionResponse).unwrap(p -> (ConnectionResponse) p).handle(connectionResponse -> {
                    // Remember the communication channel id.
                    knxNetIpDriverContext.setCommunicationChannelId(connectionResponse.getCommunicationChannelId());
                    LOGGER.info(String.format("Received KNXnet/IP Connection Response (Connection Id %s)", knxNetIpDriverContext.getCommunicationChannelId()));
                    // Check if everything went well.
                    Status status = connectionResponse.getStatus();
                    if (status == Status.NO_ERROR) {
                        final ConnectionResponseDataBlockTunnelConnection tunnelConnectionDataBlock = (ConnectionResponseDataBlockTunnelConnection) connectionResponse.getConnectionResponseDataBlock();
                        // Save the KNX Address the Gateway assigned to this connection.
                        knxNetIpDriverContext.setClientKnxAddress(tunnelConnectionDataBlock.getKnxAddress());
                        final KnxAddress gatewayAddress = knxNetIpDriverContext.getGatewayAddress();
                        final KnxAddress clientKnxAddress = knxNetIpDriverContext.getClientKnxAddress();
                        LOGGER.info(String.format("Successfully connected to KNXnet/IP Gateway '%s' with KNX address '%d.%d.%d' got assigned client KNX address '%d.%d.%d'", knxNetIpDriverContext.getGatewayName(), gatewayAddress.getMainGroup(), gatewayAddress.getMiddleGroup(), gatewayAddress.getSubGroup(), clientKnxAddress.getMainGroup(), clientKnxAddress.getMiddleGroup(), clientKnxAddress.getSubGroup()));
                        // Send an event that connection setup is complete.
                        context.fireConnected();
                        // Start a timer to check the connection state every 60 seconds.
                        // This keeps the connection open if no data is transported.
                        // Otherwise the gateway will terminate the connection.
                        connectionStateTimer = new Timer();
                        connectionStateTimer.scheduleAtFixedRate(new TimerTask() {

                            @Override
                            public void run() {
                                ConnectionStateRequest connectionStateRequest = new ConnectionStateRequest(knxNetIpDriverContext.getCommunicationChannelId(), new HPAIControlEndpoint(HostProtocolCode.IPV4_UDP, knxNetIpDriverContext.getLocalIPAddress(), knxNetIpDriverContext.getLocalPort()));
                                context.sendRequest(connectionStateRequest).expectResponse(KnxNetIpMessage.class, Duration.ofMillis(1000)).check(p -> p instanceof ConnectionStateResponse).unwrap(p -> (ConnectionStateResponse) p).handle(connectionStateResponse -> {
                                    if (connectionStateResponse.getStatus() != Status.NO_ERROR) {
                                        if (connectionStateResponse.getStatus() != null) {
                                            LOGGER.error(String.format("Connection state problems. Got %s", connectionStateResponse.getStatus().name()));
                                        } else {
                                            LOGGER.error("Connection state problems. Got no status information.");
                                        }
                                        // Stop the timer.
                                        connectionStateTimer.cancel();
                                    }
                                });
                            }
                        }, 60000, 60000);
                    } else {
                        // The connection request wasn't successful.
                        LOGGER.error(String.format("Not connected to KNXnet/IP Gateway '%s' with KNX address '%d.%d.%d' got status: '%s'", knxNetIpDriverContext.getGatewayName(), knxNetIpDriverContext.getGatewayAddress().getMainGroup(), knxNetIpDriverContext.getGatewayAddress().getMiddleGroup(), knxNetIpDriverContext.getGatewayAddress().getSubGroup(), status.toString()));
                    // TODO: Actively disconnect
                    }
                });
            } else {
                // This device doesn't support tunneling ... do some error handling.
                LOGGER.error("Not connected to KNCnet/IP Gateway. The device doesn't support Tunneling.");
            // TODO: Actively disconnect
            }
        });
    } else // This usually when we're running a passive mode river.
    {
        LOGGER.info("KNX Driver running in PASSIVE mode.");
        knxNetIpDriverContext.setPassiveMode(true);
        // No login required, just confirm that we're connected.
        context.fireConnected();
    }
}
Also used : org.apache.plc4x.java.api.value(org.apache.plc4x.java.api.value) PlcStruct(org.apache.plc4x.java.spi.values.PlcStruct) java.util(java.util) GroupAddress(org.apache.plc4x.java.knxnetip.ets5.model.GroupAddress) DriverContext(org.apache.plc4x.java.spi.context.DriverContext) LoggerFactory(org.slf4j.LoggerFactory) KnxGroupAddress3Level(org.apache.plc4x.java.knxnetip.readwrite.KnxGroupAddress3Level) DefaultPlcConsumerRegistration(org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration) CompletableFuture(java.util.concurrent.CompletableFuture) Hex(org.apache.commons.codec.binary.Hex) PlcConsumerRegistration(org.apache.plc4x.java.api.model.PlcConsumerRegistration) KnxNetIpDriverContext(org.apache.plc4x.java.knxnetip.context.KnxNetIpDriverContext) KnxNetIpSubscriptionHandle(org.apache.plc4x.java.knxnetip.model.KnxNetIpSubscriptionHandle) RequestTransactionManager(org.apache.plc4x.java.spi.transaction.RequestTransactionManager) DatagramChannel(io.netty.channel.socket.DatagramChannel) PlcSTRING(org.apache.plc4x.java.spi.values.PlcSTRING) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) 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) KnxDatapoint(org.apache.plc4x.java.knxnetip.readwrite.KnxDatapoint) Plc4xProtocolBase(org.apache.plc4x.java.spi.Plc4xProtocolBase) Logger(org.slf4j.Logger) KnxGroupAddress2Level(org.apache.plc4x.java.knxnetip.readwrite.KnxGroupAddress2Level) PlcSubscriptionHandle(org.apache.plc4x.java.api.model.PlcSubscriptionHandle) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) KnxGroupAddressFreeLevel(org.apache.plc4x.java.knxnetip.readwrite.KnxGroupAddressFreeLevel) org.apache.plc4x.java.spi.messages(org.apache.plc4x.java.spi.messages) Instant(java.time.Instant) KnxNetIpField(org.apache.plc4x.java.knxnetip.field.KnxNetIpField) InetSocketAddress(java.net.InetSocketAddress) Ets5Model(org.apache.plc4x.java.knxnetip.ets5.model.Ets5Model) org.apache.plc4x.java.spi.generation(org.apache.plc4x.java.spi.generation) Consumer(java.util.function.Consumer) KnxGroupAddress(org.apache.plc4x.java.knxnetip.readwrite.KnxGroupAddress) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) org.apache.plc4x.java.knxnetip.readwrite(org.apache.plc4x.java.knxnetip.readwrite) ResponseItem(org.apache.plc4x.java.spi.messages.utils.ResponseItem) org.apache.plc4x.java.api.messages(org.apache.plc4x.java.api.messages) InetSocketAddress(java.net.InetSocketAddress) DatagramChannel(io.netty.channel.socket.DatagramChannel)

Aggregations

Duration (java.time.Duration)4 CompletableFuture (java.util.concurrent.CompletableFuture)4 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)4 Consumer (java.util.function.Consumer)4 PlcRuntimeException (org.apache.plc4x.java.api.exceptions.PlcRuntimeException)4 ConversationContext (org.apache.plc4x.java.spi.ConversationContext)4 DriverContext (org.apache.plc4x.java.spi.context.DriverContext)4 org.apache.plc4x.java.spi.generation (org.apache.plc4x.java.spi.generation)4 Logger (org.slf4j.Logger)4 LoggerFactory (org.slf4j.LoggerFactory)4 ByteArrayOutputStream (java.io.ByteArrayOutputStream)3 IOException (java.io.IOException)3 InetAddress (java.net.InetAddress)3 UnknownHostException (java.net.UnknownHostException)3 ByteBuffer (java.nio.ByteBuffer)3 ByteOrder (java.nio.ByteOrder)3 MessageDigest (java.security.MessageDigest)3 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)3 CertificateEncodingException (java.security.cert.CertificateEncodingException)3 ArrayList (java.util.ArrayList)3