/* * Copyright 2011-16 Fraunhofer ISE * * This file is part of OpenMUC. * For more information visit http://www.openmuc.org * * OpenMUC is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenMUC is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenMUC. If not, see <http://www.gnu.org/licenses/>. * */ package org.openmuc.framework.driver.dlms; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.UnknownHostException; import org.openmuc.framework.config.ArgumentSyntaxException; import org.openmuc.jdlms.client.ClientConnectionSettings; import org.openmuc.jdlms.client.ClientConnectionSettings.Authentication; import org.openmuc.jdlms.client.ClientConnectionSettings.ReferencingMethod; import org.openmuc.jdlms.client.hdlc.HdlcAddress; import org.openmuc.jdlms.client.hdlc.HdlcClientConnectionSettings; import org.openmuc.jdlms.client.ip.TcpClientConnectionSettings; import org.openmuc.jdlms.client.ip.UdpClientConnectionSettings; public class AddressParser { public ClientConnectionSettings<?> parse(String deviceAddress, SettingsHelper settings) throws UnknownHostException, ArgumentSyntaxException { String[] deviceTokens = deviceAddress.split(":"); if (deviceTokens.length < 4 || deviceTokens.length > 5) { throw new ArgumentSyntaxException("Device address has less than 4 or more than 5 parameters."); } String protocol = deviceTokens[0].toLowerCase(); ClientConnectionSettings<?> result = null; ReferencingMethod referencing = ReferencingMethod.LN; referencing = ReferencingMethod.valueOf(settings.getReferencing()); String oldInterfaceAddress; String oldDeviceAddress; if (deviceTokens.length == 4) { oldInterfaceAddress = deviceTokens[0] + ":" + deviceTokens[1]; oldDeviceAddress = deviceTokens[2] + ":" + deviceTokens[3]; } else { oldInterfaceAddress = deviceTokens[0] + ":" + deviceTokens[1] + ":" + deviceTokens[2]; oldDeviceAddress = deviceTokens[3] + ":" + deviceTokens[4]; } if (protocol.equals("hdlc")) { result = parseHdlc(oldInterfaceAddress, oldDeviceAddress, referencing, settings); } else if (protocol.equals("udp")) { result = parseUdp(oldInterfaceAddress, oldDeviceAddress, referencing, settings); } else if (protocol.equals("tcp")) { result = parseTcp(oldInterfaceAddress, oldDeviceAddress, referencing, settings); } if (settings.getPassword() != null) { result.setAuthentication(Authentication.LOW); } return result; } private HdlcClientConnectionSettings parseHdlc(String interfaceAddress, String deviceAddress, ReferencingMethod referencing, SettingsHelper settings) { HdlcClientConnectionSettings result = null; String[] interfaceTokens = interfaceAddress.split(":"); String[] deviceTokens = deviceAddress.split(":"); if (interfaceTokens.length < 2 || interfaceTokens.length > 3) { throw new IllegalArgumentException( "InterfaceAddress has unknown format. Use hdlc:port[:serverPhysical] as pattern"); } if (deviceTokens.length != 2) { throw new IllegalArgumentException("DeviceAddress has unknown format. Use serverLogical:clientLogical"); } String serialPort = interfaceTokens[1]; HdlcAddress clientAddress = new HdlcAddress(Integer.parseInt(deviceTokens[1])); HdlcAddress serverAddress = null; if (interfaceTokens.length == 2) { serverAddress = new HdlcAddress(Integer.parseInt(deviceTokens[0])); } else { int logical = Integer.parseInt(deviceTokens[0]); int physical = Integer.parseInt(interfaceTokens[2]); int addressSize = 2; if (logical > 127 || physical > 127) { addressSize = 4; } serverAddress = new HdlcAddress(logical, physical, addressSize); } if (clientAddress.isValidAddress() == false) { throw new IllegalArgumentException("Client logical address must be in range [1, 127]"); } if (serverAddress.isValidAddress() == false) { throw new IllegalArgumentException("Server address is invalid"); } boolean useHandshake = settings.useHandshake(); int baudrate = settings.getBaudrate(); result = new HdlcClientConnectionSettings(serialPort, clientAddress, serverAddress, referencing) .setBaudrate(baudrate).setUseHandshake(useHandshake); return result; } private UdpClientConnectionSettings parseUdp(String interfaceAddress, String deviceAddress, ReferencingMethod referencing, SettingsHelper settings) throws UnknownHostException { UdpClientConnectionSettings result = null; String[] interfaceTokens = interfaceAddress.split(":"); String[] deviceTokens = deviceAddress.split(":"); if (interfaceTokens.length < 2 && interfaceTokens.length > 3) { throw new IllegalArgumentException( "InterfaceAddress has unknown format. Use udp:serverIp[:serverPort] as a pattern"); } if (deviceTokens.length != 2) { throw new IllegalArgumentException("DeviceAddress has unknown format. Use serverWPort:clientWPort"); } int serverPort = 4059; if (interfaceTokens.length == 3) { serverPort = Integer.parseInt(interfaceTokens[2]); } int clientWPort = Integer.parseInt(deviceTokens[1]); InetSocketAddress serverAddress = new InetSocketAddress(InetAddress.getByName(interfaceTokens[1]), serverPort); int serverWPort = Integer.parseInt(deviceTokens[0]); result = new UdpClientConnectionSettings(serverAddress, serverWPort, clientWPort, referencing); return result; } private TcpClientConnectionSettings parseTcp(String interfaceAddress, String deviceAddress, ReferencingMethod referencing, SettingsHelper settings) throws UnknownHostException { TcpClientConnectionSettings result = null; String[] interfaceTokens = interfaceAddress.split(":"); String[] deviceTokens = deviceAddress.split(":"); if (interfaceTokens.length < 2 && interfaceTokens.length > 3) { throw new IllegalArgumentException( "InterfaceAddress has unknown format. Use tcp:serverIp[:serverPort] as a pattern"); } if (deviceTokens.length != 2) { throw new IllegalArgumentException("DeviceAddress has unknown format. Use serverWPort:clientWPort"); } int serverPort = 4059; if (interfaceTokens.length == 3) { serverPort = Integer.parseInt(interfaceTokens[2]); } int clientWPort = Integer.parseInt(deviceTokens[1]); InetSocketAddress serverAddress = new InetSocketAddress(InetAddress.getByName(interfaceTokens[1]), serverPort); int serverWPort = Integer.parseInt(deviceTokens[0]); result = new TcpClientConnectionSettings(serverAddress, serverWPort, clientWPort, referencing); return result; } }