Skip to content
This repository has been archived by the owner on May 7, 2020. It is now read-only.

Commit

Permalink
SerialPort creation dependent on port name
Browse files Browse the repository at this point in the history
The actual instance of the SerialPort is chosen at runtime depending on the port's name.
This allows to have different implementations for different protocols. This can be e.g. RXTX (default local) or RFC2217.
Implementations are discovered at runtime via OSGi DS.

Signed-off-by: Matthias Steigenberger <[email protected]>
  • Loading branch information
Matthias Steigenberger authored and msteigenberger committed May 9, 2018
1 parent 5667814 commit 0c11583
Show file tree
Hide file tree
Showing 18 changed files with 620 additions and 48 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ds.core.builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
eclipse.preferences.version=1
pluginProject.equinox=false
pluginProject.extensions=false
resolve.requirebundle=false
Original file line number Diff line number Diff line change
@@ -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<String>="org.eclipse
.smarthome.io.transport.serial.SerialPortManager"
Original file line number Diff line number Diff line change
@@ -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.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
bin.includes = META-INF/,\
OSGI-INF/,\
.,\
NOTICE
jars.compile.order = .
source.. = src/main/java/
output.. = target/classes
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.eclipse.smarthome.bundles</groupId>
<artifactId>io</artifactId>
<version>0.10.0-SNAPSHOT</version>
</parent>

<groupId>org.eclipse.smarthome.io</groupId>
<artifactId>org.eclipse.smarthome.io.transport.serial.rxtx.rfc2217</artifactId>
<packaging>eclipse-plugin</packaging>

<name>Eclipse SmartHome Serial Transport for RFC2217</name>

</project>
Original file line number Diff line number Diff line change
@@ -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<TelnetSerialPort> {

private final static String PROTOCOL = "rfc2217";

@Override
public boolean isApplicable(String portName, Class<TelnetSerialPort> 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<SerialPortIdentifier> getSerialPortIdentifiers() {
return Stream.empty();
}

}
Original file line number Diff line number Diff line change
@@ -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);
}
}

}
Original file line number Diff line number Diff line change
@@ -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<String>="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<String>="org.eclipse
.smarthome.io.transport.serial.SerialPortManager"
Export-Package: org.eclipse.smarthome.io.transport.serial.rxtx
Original file line number Diff line number Diff line change
@@ -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<RXTXPort> {

@Override
public boolean isApplicable(String portName, Class<RXTXPort> 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<SerialPortIdentifier> getSerialPortIdentifiers() {
@SuppressWarnings("unchecked")
final Enumeration<CommPortIdentifier> 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<T> extends Spliterators.AbstractSpliterator<T> {
private final Enumeration<T> e;

public SplitIteratorForEnumeration(final Enumeration<T> e) {
super(Long.MAX_VALUE, Spliterator.ORDERED);
this.e = e;
}

@Override
@NonNullByDefault({})
public boolean tryAdvance(Consumer<? super T> action) {
if (e.hasMoreElements()) {
action.accept(e.nextElement());
return true;
}
return false;
}

@Override
@NonNullByDefault({})
public void forEachRemaining(Consumer<? super T> action) {
while (e.hasMoreElements()) {
action.accept(e.nextElement());
}
}
}
}
Loading

0 comments on commit 0c11583

Please sign in to comment.