org.openhab.binding.km200.internal.KM200Device.java Source code

Java tutorial

Introduction

Here is the source code for org.openhab.binding.km200.internal.KM200Device.java

Source

/**
 * Copyright (c) 2010-2019 by the respective copyright holders.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 */
package org.openhab.binding.km200.internal;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.xml.bind.DatatypeConverter;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The KM200Device representing the device with its all capabilities
 *
 * @author Markus Eckhardt
 *
 * @since 1.9.0
 */

class KM200Device {

    private static final Logger logger = LoggerFactory.getLogger(KM200Device.class);

    /* valid IPv4 address of the KMxxx. */
    protected String ip4Address = null;

    /* The gateway password which is provided on the type sign of the KMxxx. */
    protected String gatewayPassword = null;

    /* The private password which has been defined by the user via EasyControl. */
    protected String privatePassword = null;

    /* The returned device charset for communication */
    protected String charSet = null;

    /* Needed keys for the communication */
    protected byte[] cryptKeyInit = null;
    protected byte[] cryptKeyPriv = null;

    /* Buderus_MD5Salt */
    protected byte[] MD5Salt = null;

    /* Device services */
    HashMap<String, KM200CommObject> serviceMap = null;
    /* Device services blacklist */
    List<String> blacklistMap = null;
    /* List of virtual services */
    List<KM200CommObject> virtualList = null;

    /* Is the first INIT done */
    protected Boolean inited = false;

    public KM200Device() {
        serviceMap = new HashMap<String, KM200CommObject>();
        blacklistMap = new ArrayList<String>();
        blacklistMap.add("/gateway/firmware");
        virtualList = new ArrayList<KM200CommObject>();
    }

    public Boolean isConfigured() {
        if (StringUtils.isNotBlank(ip4Address) && cryptKeyPriv != null) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * This function creates the private key from the MD5Salt, the device and the private password
     *
     * @author Markus Eckhardt
     *
     * @since 1.9.0
     */
    @SuppressWarnings("null")
    private void RecreateKeys() {
        if (StringUtils.isNotBlank(gatewayPassword) && StringUtils.isNotBlank(privatePassword) && MD5Salt != null) {
            byte[] MD5_K1 = null;
            byte[] MD5_K2_Init = null;
            byte[] MD5_K2_Private = null;
            byte[] bytesOfGatewayPassword = null;
            byte[] bytesOfPrivatePassword = null;
            MessageDigest md = null;
            try {
                md = MessageDigest.getInstance("MD5");
            } catch (NoSuchAlgorithmException e) {
                logger.error("No such algorithm, MD5: {}", e.getMessage());
            }

            /* First half of the key: MD5 of (GatewayPassword . Salt) */
            try {
                bytesOfGatewayPassword = gatewayPassword.getBytes("UTF-8");
            } catch (UnsupportedEncodingException e) {
                logger.error("No such encoding, UTF-8: {}", e.getMessage());
            }
            byte[] CombParts1 = new byte[bytesOfGatewayPassword.length + MD5Salt.length];
            System.arraycopy(bytesOfGatewayPassword, 0, CombParts1, 0, bytesOfGatewayPassword.length);
            System.arraycopy(MD5Salt, 0, CombParts1, bytesOfGatewayPassword.length, MD5Salt.length);
            MD5_K1 = md.digest(CombParts1);

            /* Second half of the key: - Initial: MD5 of ( Salt) */
            MD5_K2_Init = md.digest(MD5Salt);

            /* Second half of the key: - private: MD5 of ( Salt . PrivatePassword) */
            try {
                bytesOfPrivatePassword = privatePassword.getBytes("UTF-8");
            } catch (UnsupportedEncodingException e) {
                logger.error("No such encoding, UTF-8: {}", e.getMessage());
            }
            byte[] CombParts2 = new byte[bytesOfPrivatePassword.length + MD5Salt.length];
            System.arraycopy(MD5Salt, 0, CombParts2, 0, MD5Salt.length);
            System.arraycopy(bytesOfPrivatePassword, 0, CombParts2, MD5Salt.length, bytesOfPrivatePassword.length);
            MD5_K2_Private = md.digest(CombParts2);

            /* Create Keys */
            cryptKeyInit = new byte[MD5_K1.length + MD5_K2_Init.length];
            System.arraycopy(MD5_K1, 0, cryptKeyInit, 0, MD5_K1.length);
            System.arraycopy(MD5_K2_Init, 0, cryptKeyInit, MD5_K1.length, MD5_K2_Init.length);

            cryptKeyPriv = new byte[MD5_K1.length + MD5_K2_Private.length];
            System.arraycopy(MD5_K1, 0, cryptKeyPriv, 0, MD5_K1.length);
            System.arraycopy(MD5_K2_Private, 0, cryptKeyPriv, MD5_K1.length, MD5_K2_Private.length);

        }
    }

    // getter
    public String getIP4Address() {
        return ip4Address;
    }

    public String getGatewayPassword() {
        return gatewayPassword;
    }

    public String getPrivatePassword() {
        return privatePassword;
    }

    public byte[] getCryptKeyInit() {
        return cryptKeyInit;
    }

    public byte[] getCryptKeyPriv() {
        return cryptKeyPriv;
    }

    public String getCharSet() {
        return charSet;
    }

    public Boolean getInited() {
        return inited;
    }

    /**
     * This function outputs a ";" separated list of all on the device available services with its capabilities
     *
     */
    public void listAllServices() {
        if (serviceMap != null) {
            logger.info("##################################################################");
            logger.info("List of avalible services");
            logger.info("readable;writeable;recordable;virtual;type;service;value;allowed;min;max");
            for (KM200CommObject object : serviceMap.values()) {
                if (object != null) {
                    String val = "", type, valPara = "";
                    logger.debug("List type: {} service: {}", object.getServiceType(), object.getFullServiceName());
                    type = object.getServiceType();
                    if (type == null) {
                        type = new String();
                    }
                    if (type.equals("stringValue") || type.equals("floatValue")) {
                        val = object.getValue().toString();
                        if (object.getValueParameter() != null) {
                            if (type.equals("stringValue")) {
                                @SuppressWarnings("unchecked")
                                List<String> valParas = (List<String>) object.getValueParameter();
                                for (int i = 0; i < valParas.size(); i++) {
                                    if (i > 0) {
                                        valPara += "|";
                                    }
                                    valPara += valParas.get(i);
                                }
                                valPara += ";;";
                            }
                            if (type.equals("floatValue")) {
                                @SuppressWarnings("unchecked")
                                List<Float> valParas = (List<Float>) object.getValueParameter();
                                valPara += ";";
                                if (valParas.size() == 2) {
                                    valPara += valParas.get(0);
                                    valPara += ";";
                                    valPara += valParas.get(1);
                                } else {
                                    logger.debug("Value parameter for float != 2, this shouldn't happen");
                                    valPara += ";";
                                }
                            }
                        } else {
                            valPara += ";;";
                        }
                    } else {
                        val = "";
                        valPara = ";";
                    }
                    logger.info("{};{};{};{};{};{};{};{}", object.getReadable().toString(),
                            object.getWriteable().toString(), object.getRecordable().toString(),
                            object.getVirtual().toString(), type, object.getFullServiceName(), val, valPara);
                }
            }
            logger.info("##################################################################");
        }
    }

    /**
     * This function resets the update state on all service objects
     *
     */
    public void resetAllUpdates() {
        if (serviceMap != null) {
            for (KM200CommObject object : serviceMap.values()) {
                if (object != null) {
                    object.setUpdated(false);
                }
            }
        }
    }

    // setter
    public void setIP4Address(String ip) {
        ip4Address = ip;
    }

    public void setGatewayPassword(String password) {
        gatewayPassword = password;
        RecreateKeys();
    }

    public void setPrivatePassword(String password) {
        privatePassword = password;
        RecreateKeys();
    }

    public void setMD5Salt(String salt) {
        MD5Salt = DatatypeConverter.parseHexBinary(salt);
        RecreateKeys();
    }

    public void setCryptKeyPriv(String key) {
        cryptKeyPriv = DatatypeConverter.parseHexBinary(key);
    }

    public void setCharSet(String charset) {
        charSet = charset;
    }

    public void setInited(Boolean Init) {
        inited = Init;
    }

}