Search in sources :

Example 1 with TradfriGatewayConfig

use of org.eclipse.smarthome.binding.tradfri.internal.config.TradfriGatewayConfig in project smarthome by eclipse.

the class TradfriGatewayHandler method obtainIdentityAndPreSharedKey.

/**
 * Authenticates against the gateway with the security code in order to receive a pre-shared key for a newly
 * generated identity.
 * As this requires a remote request, this method might be long-running.
 *
 * @return true, if credentials were successfully obtained, false otherwise
 */
protected boolean obtainIdentityAndPreSharedKey() {
    TradfriGatewayConfig configuration = getConfigAs(TradfriGatewayConfig.class);
    String identity = UUID.randomUUID().toString().replace("-", "");
    String preSharedKey = null;
    CoapResponse gatewayResponse;
    String authUrl = null;
    String responseText = null;
    try {
        DtlsConnectorConfig.Builder builder = new DtlsConnectorConfig.Builder(new InetSocketAddress(0));
        builder.setPskStore(new StaticPskStore("Client_identity", configuration.code.getBytes()));
        DTLSConnector dtlsConnector = new DTLSConnector(builder.build());
        CoapEndpoint authEndpoint = new CoapEndpoint(dtlsConnector, NetworkConfig.getStandard());
        authUrl = "coaps://" + configuration.host + ":" + configuration.port + "/15011/9063";
        CoapClient deviceClient = new CoapClient(new URI(authUrl));
        deviceClient.setTimeout(TimeUnit.SECONDS.toMillis(10));
        deviceClient.setEndpoint(authEndpoint);
        JsonObject json = new JsonObject();
        json.addProperty(CLIENT_IDENTITY_PROPOSED, identity);
        gatewayResponse = deviceClient.post(json.toString(), 0);
        authEndpoint.destroy();
        deviceClient.shutdown();
        if (gatewayResponse == null) {
            // seems we ran in a timeout, which potentially also happens
            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "No response from gateway. Might be due to an invalid security code.");
            return false;
        }
        if (gatewayResponse.isSuccess()) {
            responseText = gatewayResponse.getResponseText();
            json = new JsonParser().parse(responseText).getAsJsonObject();
            preSharedKey = json.get(NEW_PSK_BY_GW).getAsString();
            if (isNullOrEmpty(preSharedKey)) {
                logger.error("Received pre-shared key is empty for thing {} on gateway at {}", getThing().getUID(), configuration.host);
                updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Pre-shared key was not obtain successfully");
                return false;
            } else {
                logger.info("Received pre-shared key for gateway '{}'", configuration.host);
                logger.debug("Using identity '{}' with pre-shared key '{}'.", identity, preSharedKey);
                Configuration editedConfig = editConfiguration();
                editedConfig.put(TradfriBindingConstants.GATEWAY_CONFIG_CODE, null);
                editedConfig.put(TradfriBindingConstants.GATEWAY_CONFIG_IDENTITY, identity);
                editedConfig.put(TradfriBindingConstants.GATEWAY_CONFIG_PRE_SHARED_KEY, preSharedKey);
                updateConfiguration(editedConfig);
                return true;
            }
        } else {
            logger.warn("Failed obtaining pre-shared key for identity '{}' (response code '{}', response text '{}')", identity, gatewayResponse.getCode(), isNullOrEmpty(gatewayResponse.getResponseText()) ? "<empty>" : gatewayResponse.getResponseText());
            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, String.format("Failed obtaining pre-shared key with status code '%s'", gatewayResponse.getCode()));
        }
    } catch (URISyntaxException e) {
        logger.error("Illegal gateway URI '{}'", authUrl, e);
        updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
    } catch (JsonParseException e) {
        logger.warn("Invalid response recieved from gateway '{}'", responseText, e);
        updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, String.format("Invalid response recieved from gateway '%s'", responseText));
    }
    return false;
}
Also used : CoapResponse(org.eclipse.californium.core.CoapResponse) Configuration(org.eclipse.smarthome.config.core.Configuration) InetSocketAddress(java.net.InetSocketAddress) JsonObject(com.google.gson.JsonObject) URISyntaxException(java.net.URISyntaxException) JsonParseException(com.google.gson.JsonParseException) URI(java.net.URI) DtlsConnectorConfig(org.eclipse.californium.scandium.config.DtlsConnectorConfig) DTLSConnector(org.eclipse.californium.scandium.DTLSConnector) CoapClient(org.eclipse.californium.core.CoapClient) TradfriCoapClient(org.eclipse.smarthome.binding.tradfri.internal.TradfriCoapClient) StaticPskStore(org.eclipse.californium.scandium.dtls.pskstore.StaticPskStore) TradfriGatewayConfig(org.eclipse.smarthome.binding.tradfri.internal.config.TradfriGatewayConfig) CoapEndpoint(org.eclipse.californium.core.network.CoapEndpoint) TradfriCoapEndpoint(org.eclipse.smarthome.binding.tradfri.internal.TradfriCoapEndpoint) JsonParser(com.google.gson.JsonParser)

Example 2 with TradfriGatewayConfig

use of org.eclipse.smarthome.binding.tradfri.internal.config.TradfriGatewayConfig in project smarthome by eclipse.

the class TradfriGatewayHandler method initialize.

@Override
public void initialize() {
    TradfriGatewayConfig configuration = getConfigAs(TradfriGatewayConfig.class);
    if (isNullOrEmpty(configuration.host)) {
        updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Host must be specified in the configuration!");
        return;
    }
    if (isNullOrEmpty(configuration.code)) {
        if (isNullOrEmpty(configuration.identity) || isNullOrEmpty(configuration.preSharedKey)) {
            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Either security code or identity and pre-shared key must be provided in the configuration!");
            return;
        } else {
            establishConnection();
        }
    } else {
        if (isOldFirmware()) {
            /*
                 * older firmware - fall back to authentication with security code
                 * in this case the Thing configuration will not be persisted
                 */
            logger.warn("Gateway with old firmware - please consider upgrading to the latest version.");
            Configuration editedConfig = editConfiguration();
            editedConfig.put(TradfriBindingConstants.GATEWAY_CONFIG_IDENTITY, "");
            editedConfig.put(TradfriBindingConstants.GATEWAY_CONFIG_PRE_SHARED_KEY, configuration.code);
            updateConfiguration(editedConfig);
            establishConnection();
        } else {
            // Running async operation to retrieve new <'identity','key'> pair
            scheduler.execute(() -> {
                boolean success = obtainIdentityAndPreSharedKey();
                if (success) {
                    establishConnection();
                }
            });
        }
    }
}
Also used : Configuration(org.eclipse.smarthome.config.core.Configuration) TradfriGatewayConfig(org.eclipse.smarthome.binding.tradfri.internal.config.TradfriGatewayConfig)

Example 3 with TradfriGatewayConfig

use of org.eclipse.smarthome.binding.tradfri.internal.config.TradfriGatewayConfig in project smarthome by eclipse.

the class TradfriGatewayHandler method establishConnection.

private void establishConnection() {
    TradfriGatewayConfig configuration = getConfigAs(TradfriGatewayConfig.class);
    this.gatewayURI = "coaps://" + configuration.host + ":" + configuration.port + "/" + DEVICES;
    this.gatewayInfoURI = "coaps://" + configuration.host + ":" + configuration.port + "/" + GATEWAY + "/" + GATEWAY_DETAILS;
    try {
        URI uri = new URI(gatewayURI);
        deviceClient = new TradfriCoapClient(uri);
    } catch (URISyntaxException e) {
        logger.error("Illegal gateway URI '{}': {}", gatewayURI, e.getMessage());
        updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
        return;
    }
    DtlsConnectorConfig.Builder builder = new DtlsConnectorConfig.Builder(new InetSocketAddress(0));
    builder.setPskStore(new StaticPskStore(configuration.identity, configuration.preSharedKey.getBytes()));
    dtlsConnector = new DTLSConnector(builder.build());
    endPoint = new TradfriCoapEndpoint(dtlsConnector, NetworkConfig.getStandard());
    deviceClient.setEndpoint(endPoint);
    updateStatus(ThingStatus.UNKNOWN);
    // schedule a new scan every minute
    scanJob = scheduler.scheduleWithFixedDelay(this::startScan, 0, 1, TimeUnit.MINUTES);
}
Also used : StaticPskStore(org.eclipse.californium.scandium.dtls.pskstore.StaticPskStore) TradfriGatewayConfig(org.eclipse.smarthome.binding.tradfri.internal.config.TradfriGatewayConfig) InetSocketAddress(java.net.InetSocketAddress) URISyntaxException(java.net.URISyntaxException) URI(java.net.URI) DtlsConnectorConfig(org.eclipse.californium.scandium.config.DtlsConnectorConfig) DTLSConnector(org.eclipse.californium.scandium.DTLSConnector) TradfriCoapEndpoint(org.eclipse.smarthome.binding.tradfri.internal.TradfriCoapEndpoint) TradfriCoapClient(org.eclipse.smarthome.binding.tradfri.internal.TradfriCoapClient)

Aggregations

TradfriGatewayConfig (org.eclipse.smarthome.binding.tradfri.internal.config.TradfriGatewayConfig)3 InetSocketAddress (java.net.InetSocketAddress)2 URI (java.net.URI)2 URISyntaxException (java.net.URISyntaxException)2 DTLSConnector (org.eclipse.californium.scandium.DTLSConnector)2 DtlsConnectorConfig (org.eclipse.californium.scandium.config.DtlsConnectorConfig)2 StaticPskStore (org.eclipse.californium.scandium.dtls.pskstore.StaticPskStore)2 TradfriCoapClient (org.eclipse.smarthome.binding.tradfri.internal.TradfriCoapClient)2 TradfriCoapEndpoint (org.eclipse.smarthome.binding.tradfri.internal.TradfriCoapEndpoint)2 Configuration (org.eclipse.smarthome.config.core.Configuration)2 JsonObject (com.google.gson.JsonObject)1 JsonParseException (com.google.gson.JsonParseException)1 JsonParser (com.google.gson.JsonParser)1 CoapClient (org.eclipse.californium.core.CoapClient)1 CoapResponse (org.eclipse.californium.core.CoapResponse)1 CoapEndpoint (org.eclipse.californium.core.network.CoapEndpoint)1