diff --git a/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/.classpath b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/.classpath new file mode 100644 index 00000000000..7f457fa4138 --- /dev/null +++ b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/.project b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/.project new file mode 100644 index 00000000000..55c90003b09 --- /dev/null +++ b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/.project @@ -0,0 +1,33 @@ + + + org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.ds.core.builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/.settings/org.eclipse.jdt.core.prefs b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..672496e107e --- /dev/null +++ b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/.settings/org.eclipse.pde.core.prefs b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/.settings/org.eclipse.pde.core.prefs new file mode 100644 index 00000000000..e8ff8be0bab --- /dev/null +++ b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/.settings/org.eclipse.pde.core.prefs @@ -0,0 +1,4 @@ +eclipse.preferences.version=1 +pluginProject.equinox=false +pluginProject.extensions=false +resolve.requirebundle=false diff --git a/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/META-INF/MANIFEST.MF b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..9e19e0a075f --- /dev/null +++ b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/META-INF/MANIFEST.MF @@ -0,0 +1,18 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-ClassPath: . +Bundle-Name: Eclipse SmartHome Serial Transport extension for RXTX RFC2217 +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Bundle-SymbolicName: org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217;singleton:=true +Bundle-Vendor: Eclipse.org/SmartHome +Bundle-Version: 0.10.0.qualifier +Import-Package: gnu.io, + gnu.io.rfc2217, + org.apache.commons.net, + org.apache.commons.net.telnet, + org.eclipse.jdt.annotation;resolution:=optional, + org.eclipse.smarthome.io.transport.serial, + org.eclipse.smarthome.io.transport.serial.rxtx +Service-Component: OSGI-INF/*.xml +Provide-Capability: osgi.service;objectClass:List="org.eclipse + .smarthome.io.transport.serial.SerialPortManager" diff --git a/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/NOTICE b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/NOTICE new file mode 100644 index 00000000000..b8675cd02e8 --- /dev/null +++ b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/NOTICE @@ -0,0 +1,19 @@ +This content is produced and maintained by the Eclipse SmartHome project. + +* Project home: https://eclipse.org/smarthome/ + +== Declared Project Licenses + +This program and the accompanying materials are made available under the terms +of the Eclipse Public License 2.0 which is available at +https://www.eclipse.org/legal/epl-2.0/. + +== Source Code + +https://github.com/eclipse/smarthome + +== Copyright Holders + +See the NOTICE file distributed with the source code at +https://github.com/eclipse/smarthome/blob/master/NOTICE +for detailed information regarding copyright ownership. diff --git a/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/OSGI-INF/.gitignore b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/OSGI-INF/.gitignore new file mode 100644 index 00000000000..b81c7954b78 --- /dev/null +++ b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/OSGI-INF/.gitignore @@ -0,0 +1 @@ +*.xml \ No newline at end of file diff --git a/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/build.properties b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/build.properties new file mode 100644 index 00000000000..5f46522d8aa --- /dev/null +++ b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/build.properties @@ -0,0 +1,7 @@ +bin.includes = META-INF/,\ + OSGI-INF/,\ + .,\ + NOTICE +jars.compile.order = . +source.. = src/main/java/ +output.. = target/classes diff --git a/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/pom.xml b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/pom.xml new file mode 100644 index 00000000000..873c0a981c1 --- /dev/null +++ b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + + + org.eclipse.smarthome.bundles + io + 0.10.0-SNAPSHOT + + + org.eclipse.smarthome.io + org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217 + eclipse-plugin + + Eclipse SmartHome Serial Transport for RFC2217 + + diff --git a/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/src/main/java/org/eclipse/smarthome/io/transport/serial/rxtx/rfc2217/internal/RFC2217PortCreator.java b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/src/main/java/org/eclipse/smarthome/io/transport/serial/rxtx/rfc2217/internal/RFC2217PortCreator.java new file mode 100644 index 00000000000..a8be7416c05 --- /dev/null +++ b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/src/main/java/org/eclipse/smarthome/io/transport/serial/rxtx/rfc2217/internal/RFC2217PortCreator.java @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2014,2018 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217.internal; + +import java.net.URI; +import java.util.stream.Stream; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.smarthome.io.transport.serial.SerialPortIdentifier; +import org.eclipse.smarthome.io.transport.serial.rxtx.SerialPortCreator; +import org.osgi.service.component.annotations.Component; + +import gnu.io.NoSuchPortException; +import gnu.io.UnsupportedCommOperationException; +import gnu.io.rfc2217.TelnetSerialPort; + +/** + * + * @author MatthiasS + * + */ +@NonNullByDefault +@Component(service = SerialPortCreator.class) +public class RFC2217PortCreator implements SerialPortCreator { + + private final static String PROTOCOL = "rfc2217"; + + @Override + public boolean isApplicable(String portName, Class expectedClass) { + try { + if (expectedClass.isAssignableFrom(TelnetSerialPort.class)) { + URI uri = URI.create(portName); + return uri.getScheme().equalsIgnoreCase(PROTOCOL); + } + return false; + } catch (Throwable t) { + return false; + } + } + + /** + * @throws UnsupportedCommOperationException if connection to the remote serial port fails. + * @throws NoSuchPortException if the host does not exist. + */ + @Override + public @Nullable SerialPortIdentifier getPortIdentifier(String portName) { + TelnetSerialPort telnetSerialPort = new TelnetSerialPort(); + telnetSerialPort.setName(portName); + return new SerialPortIdentifierImpl(telnetSerialPort); + } + + @Override + public String getProtocol() { + return PROTOCOL; + } + + @Override + public Stream getSerialPortIdentifiers() { + return Stream.empty(); + } + +} diff --git a/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/src/main/java/org/eclipse/smarthome/io/transport/serial/rxtx/rfc2217/internal/SerialPortIdentifierImpl.java b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/src/main/java/org/eclipse/smarthome/io/transport/serial/rxtx/rfc2217/internal/SerialPortIdentifierImpl.java new file mode 100644 index 00000000000..b6ef631db40 --- /dev/null +++ b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217/src/main/java/org/eclipse/smarthome/io/transport/serial/rxtx/rfc2217/internal/SerialPortIdentifierImpl.java @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2014,2018 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217.internal; + +import java.net.URI; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.smarthome.io.transport.serial.PortInUseException; +import org.eclipse.smarthome.io.transport.serial.SerialPort; +import org.eclipse.smarthome.io.transport.serial.SerialPortIdentifier; +import org.eclipse.smarthome.io.transport.serial.internal.SerialPortImpl; +import gnu.io.rfc2217.TelnetSerialPort; + +/** + * Specific serial port identifier implementation. + * + * @author Markus Rathgeb - Initial contribution + */ +@NonNullByDefault +public class SerialPortIdentifierImpl implements SerialPortIdentifier { + + final TelnetSerialPort id; + + /** + * Constructor. + * + * @param id the underlying comm port identifier implementation + */ + public SerialPortIdentifierImpl(final TelnetSerialPort id) { + this.id = id; + } + + @Override + public String getName() { + final String name = id.getName(); + return name != null ? name : ""; + } + + @Override + public SerialPort open(String owner, int timeout) throws PortInUseException { + URI url = URI.create(id.getName()); + + try { + id.getTelnetClient().setDefaultTimeout(timeout); + id.getTelnetClient().connect(url.getHost(), url.getPort()); + return new SerialPortImpl(id); + } catch (Exception e) { + throw new IllegalStateException( + String.format("Unable to establish remote connection to serial port %s", url), e); + } + } + +} diff --git a/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx/META-INF/MANIFEST.MF b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx/META-INF/MANIFEST.MF index 8f564e33c93..9628a664489 100644 --- a/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx/META-INF/MANIFEST.MF +++ b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx/META-INF/MANIFEST.MF @@ -1,15 +1,16 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-ClassPath: . -Bundle-Name: Eclipse SmartHome Serial Transport for RXTX -Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Bundle-SymbolicName: org.eclipse.smarthome.io.transport.serial.rxtx;si - ngleton:=true -Bundle-Vendor: Eclipse.org/SmartHome -Bundle-Version: 0.10.0.qualifier -Import-Package: gnu.io, - org.eclipse.jdt.annotation;resolution:=optional, - org.eclipse.smarthome.io.transport.serial -Service-Component: OSGI-INF/*.xml -Provide-Capability: osgi.service;objectClass:List="org.eclipse - .smarthome.io.transport.serial.SerialPortManager" +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-ClassPath: . +Bundle-Name: Eclipse SmartHome Serial Transport for RXTX +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Bundle-SymbolicName: org.eclipse.smarthome.io.transport.serial.rxtx;si + ngleton:=true +Bundle-Vendor: Eclipse.org/SmartHome +Bundle-Version: 0.10.0.qualifier +Import-Package: gnu.io, + org.eclipse.jdt.annotation;resolution:=optional, + org.eclipse.smarthome.io.transport.serial +Service-Component: OSGI-INF/*.xml +Provide-Capability: osgi.service;objectClass:List="org.eclipse + .smarthome.io.transport.serial.SerialPortManager" +Export-Package: org.eclipse.smarthome.io.transport.serial.rxtx diff --git a/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx/src/main/java/org/eclipse/smarthome/io/transport/serial/internal/RxTxPortCreator.java b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx/src/main/java/org/eclipse/smarthome/io/transport/serial/internal/RxTxPortCreator.java new file mode 100644 index 00000000000..d62cc080e93 --- /dev/null +++ b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx/src/main/java/org/eclipse/smarthome/io/transport/serial/internal/RxTxPortCreator.java @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2014,2018 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.smarthome.io.transport.serial.internal; + +import java.util.Enumeration; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.function.Consumer; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.smarthome.io.transport.serial.SerialPortIdentifier; +import org.eclipse.smarthome.io.transport.serial.rxtx.SerialPortCreator; +import org.osgi.service.component.annotations.Component; + +import gnu.io.CommPortIdentifier; +import gnu.io.RXTXPort; + +/** + * + * @author MatthiasS + * + */ +@NonNullByDefault +@Component(service = SerialPortCreator.class, immediate = true) +public class RxTxPortCreator implements SerialPortCreator { + + @Override + public boolean isApplicable(String portName, Class expectedClass) { + return expectedClass.isAssignableFrom(RXTXPort.class); + } + + @Override + public @Nullable SerialPortIdentifier getPortIdentifier(String port) { + CommPortIdentifier ident = null; + if ((System.getProperty("os.name").toLowerCase().indexOf("linux") != -1)) { + SerialPortUtil.appendSerialPortProperty(port); + } + try { + ident = CommPortIdentifier.getPortIdentifier(port); + } catch (gnu.io.NoSuchPortException e) { + return null; + } + return new SerialPortIdentifierImpl(ident); + + } + + @Override + public String getProtocol() { + return LOCAL; + } + + @Override + public Stream getSerialPortIdentifiers() { + @SuppressWarnings("unchecked") + final Enumeration ids = CommPortIdentifier.getPortIdentifiers(); + return StreamSupport.stream(new SplitIteratorForEnumeration<>(ids), false) + .filter(id -> id.getPortType() == CommPortIdentifier.PORT_SERIAL) + .map(sid -> new SerialPortIdentifierImpl(sid)); + } + + private static class SplitIteratorForEnumeration extends Spliterators.AbstractSpliterator { + private final Enumeration e; + + public SplitIteratorForEnumeration(final Enumeration e) { + super(Long.MAX_VALUE, Spliterator.ORDERED); + this.e = e; + } + + @Override + @NonNullByDefault({}) + public boolean tryAdvance(Consumer action) { + if (e.hasMoreElements()) { + action.accept(e.nextElement()); + return true; + } + return false; + } + + @Override + @NonNullByDefault({}) + public void forEachRemaining(Consumer action) { + while (e.hasMoreElements()) { + action.accept(e.nextElement()); + } + } + } +} diff --git a/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx/src/main/java/org/eclipse/smarthome/io/transport/serial/internal/SerialPortManagerImpl.java b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx/src/main/java/org/eclipse/smarthome/io/transport/serial/internal/SerialPortManagerImpl.java index 95df0fb9227..1ffddd0153f 100644 --- a/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx/src/main/java/org/eclipse/smarthome/io/transport/serial/internal/SerialPortManagerImpl.java +++ b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx/src/main/java/org/eclipse/smarthome/io/transport/serial/internal/SerialPortManagerImpl.java @@ -12,19 +12,17 @@ */ package org.eclipse.smarthome.io.transport.serial.internal; -import java.util.Enumeration; -import java.util.Spliterator; -import java.util.Spliterators; -import java.util.function.Consumer; import java.util.stream.Stream; -import java.util.stream.StreamSupport; import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; import org.eclipse.smarthome.io.transport.serial.SerialPortIdentifier; import org.eclipse.smarthome.io.transport.serial.SerialPortManager; +import org.eclipse.smarthome.io.transport.serial.rxtx.SerialPortCreator; import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; -import gnu.io.CommPortIdentifier; +import gnu.io.SerialPort; /** * Specific serial port manager implementation. @@ -35,39 +33,34 @@ @Component public class SerialPortManagerImpl implements SerialPortManager { - private static class SplitIteratorForEnumeration extends Spliterators.AbstractSpliterator { - private final Enumeration e; + private @NonNullByDefault({}) SerialPortRegistry registry; - public SplitIteratorForEnumeration(final Enumeration e) { - super(Long.MAX_VALUE, Spliterator.ORDERED); - this.e = e; - } + @Reference + protected void setSerialportRegistry(SerialPortRegistry registry) { + this.registry = registry; + } - @Override - @NonNullByDefault({}) - public boolean tryAdvance(Consumer action) { - if (e.hasMoreElements()) { - action.accept(e.nextElement()); - return true; - } - return false; - } + protected void unsetSerialportRegistry(SerialPortRegistry registry) { + this.registry = registry; + } - @Override - @NonNullByDefault({}) - public void forEachRemaining(Consumer action) { - while (e.hasMoreElements()) { - action.accept(e.nextElement()); - } + @Override + public Stream getIdentifiers() { + if (registry == null) { + return Stream.empty(); } + return registry.getPortCreators().stream().flatMap(element -> element.getSerialPortIdentifiers()); } @Override - public Stream getIdentifiers() { - @SuppressWarnings("unchecked") - final Enumeration ids = CommPortIdentifier.getPortIdentifiers(); - return StreamSupport.stream(new SplitIteratorForEnumeration<>(ids), false) - .filter(id -> id.getPortType() == CommPortIdentifier.PORT_SERIAL) - .map(sid -> new SerialPortIdentifierImpl(sid)); + public @Nullable SerialPortIdentifier getIdentifier(String name) { + if (registry == null) { + return null; + } + SerialPortCreator portCreator = registry.getPortCreatorForPortName(name, SerialPort.class); + if (portCreator == null) { + return null; + } + return portCreator.getPortIdentifier(name); } } diff --git a/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx/src/main/java/org/eclipse/smarthome/io/transport/serial/internal/SerialPortRegistry.java b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx/src/main/java/org/eclipse/smarthome/io/transport/serial/internal/SerialPortRegistry.java new file mode 100644 index 00000000000..f47ed9053fb --- /dev/null +++ b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx/src/main/java/org/eclipse/smarthome/io/transport/serial/internal/SerialPortRegistry.java @@ -0,0 +1,94 @@ +/** + * Copyright (c) 2014,2018 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.smarthome.io.transport.serial.internal; + +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.TreeSet; + +import org.eclipse.smarthome.io.transport.serial.rxtx.SerialPortCreator; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferenceCardinality; +import org.osgi.service.component.annotations.ReferencePolicy; + +/** + * + * @author MatthiasS + * + */ +@Component(immediate = true, service = SerialPortRegistry.class) +public class SerialPortRegistry { + + private Collection> portCreators; + + public SerialPortRegistry() { + // register the LOCAL PortCreator as last argument, so that is always taken into account when no other creator + // is applicable. + this.portCreators = new TreeSet>(new Comparator>() { + + @Override + public int compare(SerialPortCreator o1, SerialPortCreator o2) { + if (o1.getProtocol().equals(SerialPortCreator.LOCAL)) { + return 1; + } + if (o2.getProtocol().equals(SerialPortCreator.LOCAL)) { + return -1; + } + return o1.getProtocol().compareTo(o2.getProtocol()); + } + }); + + } + + /** + * Registers a {@link SerialPortCreator}. + * + * @param creator + */ + @Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC) + protected void registerSerialPortCreator(SerialPortCreator creator) { + this.portCreators.add(creator); + } + + protected void unregisterSerialPortCreator(SerialPortCreator creator) { + this.portCreators.remove(creator); + } + + /** + * Gets the best applicable {@link SerialPortCreator} for the given portName + * + * @param portName The port's name. + * @return A found {@link SerialPortCreator} or null if none could be found. + */ + @SuppressWarnings("unchecked") + public SerialPortCreator getPortCreatorForPortName(String portName, Class expectedClass) { + for (@SuppressWarnings("rawtypes") + SerialPortCreator creator : this.portCreators) { + try { + if (creator.isApplicable(portName, expectedClass)) { + return creator; + } + } catch (Exception e) { + System.err.println("Error for SerialPortCreator#isApplicable: " + creator.getClass() + "; " + + creator.getProtocol() + " -> " + e.getMessage()); + } + } + return null; + } + + public Collection> getPortCreators() { + return Collections.unmodifiableCollection(portCreators); + } +} diff --git a/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx/src/main/java/org/eclipse/smarthome/io/transport/serial/internal/SerialPortUtil.java b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx/src/main/java/org/eclipse/smarthome/io/transport/serial/internal/SerialPortUtil.java new file mode 100644 index 00000000000..b0407427a10 --- /dev/null +++ b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx/src/main/java/org/eclipse/smarthome/io/transport/serial/internal/SerialPortUtil.java @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2014,2018 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.smarthome.io.transport.serial.internal; + +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * + * @author MatthiasS + * + */ +public class SerialPortUtil { + + private static final String GNU_IO_RXTX_SERIAL_PORTS = "gnu.io.rxtx.SerialPorts"; + + /** + * Registers the given port as system property {@value #GNU_IO_RXTX_SERIAL_PORTS}. The method is capable of + * extending the system property, if any other ports are already registered. + * + * @param port the port to be registered + */ + public synchronized static void appendSerialPortProperty(String port) { + String serialPortsProperty = System.getProperty(GNU_IO_RXTX_SERIAL_PORTS); + String newValue = initSerialPort(port, serialPortsProperty); + if (newValue != null) { + + System.setProperty(GNU_IO_RXTX_SERIAL_PORTS, newValue); + } + } + + static String initSerialPort(String port, String serialPortsProperty) { + + String pathSeparator = System.getProperty("path.separator", ":"); + Set serialPorts = null; + if (serialPortsProperty != null) { + serialPorts = Stream.of(serialPortsProperty.split(pathSeparator)).collect(Collectors.toSet()); + } else { + serialPorts = new HashSet(); + } + if (serialPorts.add(port)) { + return serialPorts.stream().collect(Collectors.joining(pathSeparator)); // see + // RXTXCommDriver#addSpecifiedPorts + } + return null; + } +} diff --git a/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx/src/main/java/org/eclipse/smarthome/io/transport/serial/rxtx/SerialPortCreator.java b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx/src/main/java/org/eclipse/smarthome/io/transport/serial/rxtx/SerialPortCreator.java new file mode 100644 index 00000000000..e34788ce11b --- /dev/null +++ b/bundles/io/org.eclipse.smarthome.io.transport.serial.rxtx/src/main/java/org/eclipse/smarthome/io/transport/serial/rxtx/SerialPortCreator.java @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2014,2018 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.smarthome.io.transport.serial.rxtx; + +import java.util.stream.Stream; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.smarthome.io.transport.serial.PortInUseException; +import org.eclipse.smarthome.io.transport.serial.SerialPort; +import org.eclipse.smarthome.io.transport.serial.SerialPortIdentifier; +import org.eclipse.smarthome.io.transport.serial.UnsupportedCommOperationException; + +import gnu.io.NoSuchPortException; + +/** + * + * @author MatthiasS + * + * @param + */ +@NonNullByDefault +public interface SerialPortCreator { + + final static String LOCAL = "local"; + + /** + * Gets whether this {@link SerialPortCreator} is applicable to create the given port. + * + * @param portName The ports name. + * @return Whether the port can be created and opened by this creator. + */ + public boolean isApplicable(String portName, Class expectedClass); + + /** + * Gets the {@link SerialPortIdentifier} if it is available or null otherwise. + * + * @param portName The ports name. + * @return The created {@link SerialPort}. + * @throws NoSuchPortException If the serial port does not exist. + * @throws UnsupportedCommOperationException + * @throws PortInUseException + */ + public @Nullable SerialPortIdentifier getPortIdentifier(String portName); + + /** + * Gets the protocol type of the Port to create. + * + * @return The protocol type. + */ + public String getProtocol(); + + /** + * Gets all the available {@link SerialPortIdentifier}s for this {@link SerialPortCreator}. + * Please note: Discovery is not available necessarily + * + * @return The available ports + */ + public Stream getSerialPortIdentifiers(); +} diff --git a/bundles/io/pom.xml b/bundles/io/pom.xml index 149b38316f8..db8c02d9074 100644 --- a/bundles/io/pom.xml +++ b/bundles/io/pom.xml @@ -44,6 +44,7 @@ org.eclipse.smarthome.io.transport.serial org.eclipse.smarthome.io.transport.serial.javacomm org.eclipse.smarthome.io.transport.serial.rxtx + org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217 org.eclipse.smarthome.io.transport.upnp org.eclipse.smarthome.io.transport.upnp.test