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

Commit

Permalink
Converted NetUtil to a service and moved implementation
Browse files Browse the repository at this point in the history
Signed-off-by: Stefan Triller <stefan.triller@telekom.de>
  • Loading branch information
triller-telekom committed Aug 3, 2017
1 parent f675a46 commit d213661
Show file tree
Hide file tree
Showing 10 changed files with 135 additions and 94 deletions.
Expand Up @@ -4,11 +4,12 @@ Bundle-Name: Eclipse SmartHome Config Core
Bundle-SymbolicName: org.eclipse.smarthome.config.core
Bundle-Version: 0.9.0.qualifier
Bundle-Vendor: Eclipse.org/SmartHome
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: com.google.common.base,
com.google.common.collect,
com.google.gson,
org.apache.commons.lang.reflect,
org.apache.commons.net.util,
org.eclipse.smarthome.core.common,
org.eclipse.smarthome.core.common.osgi,
org.eclipse.smarthome.core.common.registry,
Expand Down
@@ -1,2 +1,2 @@
/org.eclipse.smarthome.config.core.internal.i18n.I18nConfigOptionsProvider.xml
/org.eclipse.smarthome.config.core.net.NetworkConfigOptionProvider.xml
/org.eclipse.smarthome.config.core.net.internal.NetworkConfigOptionProvider.xml
Expand Up @@ -5,19 +5,22 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.smarthome.config.core.net;
package org.eclipse.smarthome.config.core.net.internal;

import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;

import org.apache.commons.net.util.SubnetUtils;
import org.eclipse.smarthome.config.core.ConfigOptionProvider;
import org.eclipse.smarthome.config.core.ParameterOption;
import org.osgi.service.component.annotations.Component;
Expand All @@ -34,7 +37,7 @@
public class NetworkConfigOptionProvider implements ConfigOptionProvider {

static final URI CONFIG_URI = URI.create("system:network");
static final String PARAM_DEFAULT_INTERFACE = "defaultInterface";
static final String PARAM_PRIMARY_ADDRESS = "primaryAddress";

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

Expand All @@ -44,38 +47,53 @@ public Collection<ParameterOption> getParameterOptions(URI uri, String param, Lo
return null;
}

if (param.equals(PARAM_DEFAULT_INTERFACE)) {
return getInterfaces();
if (param.equals(PARAM_PRIMARY_ADDRESS)) {
return getIPv4Addresses();
}
return null;
}

private List<ParameterOption> getInterfaces() {
private List<ParameterOption> getIPv4Addresses() {
ArrayList<ParameterOption> interfaceOptions = new ArrayList<>();

HashSet<String> subnets = new HashSet<>();

try {
final Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
final NetworkInterface current = interfaces.nextElement();
if (!current.isUp() || current.isLoopback() || current.isVirtual()) {
continue;
}
final Enumeration<InetAddress> addresses = current.getInetAddresses();
while (addresses.hasMoreElements()) {
final InetAddress current_addr = addresses.nextElement();
if (current_addr.isLoopbackAddress() || (current_addr instanceof Inet6Address)) {

for (InterfaceAddress ifAddr : current.getInterfaceAddresses()) {
InetAddress addr = ifAddr.getAddress();

if (addr.isLoopbackAddress() || (addr instanceof Inet6Address)) {
continue;
}

String ipv4Address = current_addr.getHostAddress();
ParameterOption po = new ParameterOption(ipv4Address, ipv4Address + " (" + current.getName() + ")");
interfaceOptions.add(po);
String ipv4Address = addr.getHostAddress();

SubnetUtils su = new SubnetUtils(
ipv4Address + "/" + String.valueOf(ifAddr.getNetworkPrefixLength()));
String subNetString = su.getInfo().getNetworkAddress() + "/"
+ String.valueOf(ifAddr.getNetworkPrefixLength());

subnets.add(subNetString);
}
}
return interfaceOptions;
} catch (SocketException ex) {
logger.error("Could not retrieve network interface: {}", ex.getMessage(), ex);
return null;
}

for (String subnet : subnets) {
ParameterOption po = new ParameterOption(subnet, subnet);
interfaceOptions.add(po);
}

return interfaceOptions;
}

}
Expand Up @@ -5,12 +5,11 @@
http://eclipse.org/smarthome/schemas/config-description-1.0.0.xsd">

<config-description uri="system:network">
<parameter name="defaultInterface" type="text">
<label>Default Interface</label>
<description><![CDATA[
<p>The default network interface to be used.</p>
]]>
</description>
<parameter name="primaryAddress" type="text">
<label>Primary Address</label>
<description><![CDATA[<p>The primary network to be used</p>
<p>Alternative: Enter an IP address (XXX.XXX.XXX.XXX) manually</p>]]></description>
<limitToOptions>false</limitToOptions>
</parameter>
</config-description>

Expand Down
3 changes: 2 additions & 1 deletion bundles/core/org.eclipse.smarthome.core/META-INF/MANIFEST.MF
Expand Up @@ -28,7 +28,7 @@ Ignore-Package: org.eclipse.smarthome.core.internal.items,org.eclipse.smarthome.
nal,org.eclipse.smarthome.core.internal.events,org.eclipse.smarthome.core.internal.loggin
g
Bundle-Name: Eclipse SmartHome Core
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-Vendor: Eclipse.org/SmartHome
Bundle-Version: 0.9.0.qualifier
Bundle-ManifestVersion: 2
Expand All @@ -38,6 +38,7 @@ Import-Package: com.google.common.base,
com.google.gson,
org.apache.commons.io,
org.apache.commons.lang,
org.apache.commons.net.util,
org.eclipse.smarthome.core.binding,
org.eclipse.smarthome.core.binding.dto,
org.eclipse.smarthome.core.common,
Expand Down
Expand Up @@ -13,10 +13,16 @@
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.commons.net.util.SubnetUtils;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Modified;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -25,12 +31,51 @@
*
* @author Markus Rathgeb - Initial contribution and API
* @author Mark Herwege - Added methods to find broadcast address(es)
* @author Stefan Triller - Converted to OSGi service with primary ipv4 conf
*/
public class NetUtil {
@Component(name = "org.eclipse.smarthome.network", property = { "service.config.description.uri=system:network",
"service.config.label=Network Settings", "service.config.category=system" })
public class NetUtil implements NetworkAddressProvider {

private static final String PRIMARY_ADDRESS = "primaryAddress";
private static final Logger LOGGER = LoggerFactory.getLogger(NetUtil.class);

private NetUtil() {
private String primaryAddress;

@SuppressWarnings("unchecked")
protected void activate(ComponentContext componentContext) {
Dictionary<String, Object> props = componentContext.getProperties();
modified((Map<String, Object>) props);
}

@Modified
public synchronized void modified(Map<String, Object> config) {
String defaultInterfaceConfig = (String) config.get(PRIMARY_ADDRESS);
if (defaultInterfaceConfig == null || defaultInterfaceConfig.equals("")) {
// if none is specified we return the default one for backward compatibility
primaryAddress = NetUtil.getLocalIpv4HostAddress();
} else {
String primaryAddressConf = (String) config.get(PRIMARY_ADDRESS);

String[] addrString = primaryAddressConf.split("/");
if (addrString.length > 1) {
String ip = getIPv4inSubnet(primaryAddressConf);
if (ip == null) {
// an error has occurred, used first interface like nothing has been configured
LOGGER.warn("Error in IP configuration, will continue to use first interface");
NetUtil.getLocalIpv4HostAddress();
} else {
primaryAddress = ip;
}
} else {
primaryAddress = addrString[0];
}
}
}

@Override
public String getPrimaryIpv4HostAddress() {
return primaryAddress;
}

/**
Expand Down Expand Up @@ -104,4 +149,40 @@ public static String getBroadcastAddress() {
}
}

private String getIPv4inSubnet(String subnet) {
try {
final Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
final NetworkInterface current = interfaces.nextElement();
if (!current.isUp() || current.isLoopback() || current.isVirtual()) {
continue;
}

for (InterfaceAddress ifAddr : current.getInterfaceAddresses()) {
InetAddress addr = ifAddr.getAddress();

if (addr.isLoopbackAddress() || (addr instanceof Inet6Address)) {
continue;
}

String ipv4Address = addr.getHostAddress();

SubnetUtils su = new SubnetUtils(
ipv4Address + "/" + String.valueOf(ifAddr.getNetworkPrefixLength()));
String subNetString = su.getInfo().getNetworkAddress() + "/"
+ String.valueOf(ifAddr.getNetworkPrefixLength());

// use first IP within this subnet
if (subNetString.equals(subnet)) {
return ipv4Address;
}
}
}
} catch (SocketException ex) {
LOGGER.error("Could not retrieve network interface: {}", ex.getMessage(), ex);
return null;
}
return null;
}

}
Expand Up @@ -8,18 +8,12 @@
package org.eclipse.smarthome.core.net;

/**
* Service that provides information about local network interfaces
* Interface that provides access to configured network addresses
*
* @author Stefan Triller - initial contribution
*
*/
public interface NetworkInterfaceService {

/**
* Obtain the local IPv4 address
*
* @return IPv4 address as string
*/
String getLocalIpv4HostAddress();
public interface NetworkAddressProvider {

public String getPrimaryIpv4HostAddress();
}

This file was deleted.

Expand Up @@ -18,5 +18,5 @@
<provide interface="org.eclipse.smarthome.core.thing.binding.ThingHandlerFactory"/>
</service>
<reference bind="setAudioHTTPServer" cardinality="1..1" interface="org.eclipse.smarthome.core.audio.AudioHTTPServer" name="AudioHTTPServer" policy="static" unbind="unsetAudioHTTPServer"/>
<reference bind="setNetworkInterfaceService" cardinality="1..1" interface="org.eclipse.smarthome.core.net.NetworkInterfaceService" name="NetworkInterfaceService" policy="static" unbind="unsetNetworkInterfaceService"/>
<reference bind="setNetworkAddressProvider" cardinality="1..1" interface="org.eclipse.smarthome.core.net.NetworkAddressProvider" name="NetworkAddressProvider" policy="static" unbind="unsetNetworkAddressProvider"/>
</scr:component>
Expand Up @@ -21,7 +21,7 @@
import org.eclipse.smarthome.core.audio.AudioHTTPServer;
import org.eclipse.smarthome.core.audio.AudioSink;
import org.eclipse.smarthome.core.net.HttpServiceUtil;
import org.eclipse.smarthome.core.net.NetworkInterfaceService;
import org.eclipse.smarthome.core.net.NetworkAddressProvider;
import org.eclipse.smarthome.core.thing.Thing;
import org.eclipse.smarthome.core.thing.ThingTypeUID;
import org.eclipse.smarthome.core.thing.ThingUID;
Expand All @@ -46,7 +46,7 @@ public class SonosHandlerFactory extends BaseThingHandlerFactory {
private UpnpIOService upnpIOService;
private DiscoveryServiceRegistry discoveryServiceRegistry;
private AudioHTTPServer audioHTTPServer;
private NetworkInterfaceService networkInterfaceService;
private NetworkAddressProvider networkAddressprovider;

private Map<String, ServiceRegistration<AudioSink>> audioSinkRegistrations = new ConcurrentHashMap<>();

Expand Down Expand Up @@ -111,7 +111,7 @@ private String createCallbackUrl() {
if (callbackUrl != null) {
return callbackUrl;
} else {
final String ipAddress = networkInterfaceService.getLocalIpv4HostAddress();
final String ipAddress = networkAddressprovider.getPrimaryIpv4HostAddress();
if (ipAddress == null) {
logger.warn("No network interface could be found.");
return null;
Expand Down Expand Up @@ -172,12 +172,12 @@ protected void unsetAudioHTTPServer(AudioHTTPServer audioHTTPServer) {
this.audioHTTPServer = null;
}

protected void setNetworkInterfaceService(NetworkInterfaceService networkInterfaceService) {
this.networkInterfaceService = networkInterfaceService;
protected void setNetworkAddressProvider(NetworkAddressProvider networkUtil) {
this.networkAddressprovider = networkUtil;
}

protected void unsetNetworkInterfaceService(NetworkInterfaceService networkInterfaceService) {
this.networkInterfaceService = null;
protected void unsetNetworkAddressProvider(NetworkAddressProvider networkUtil) {
this.networkAddressprovider = null;
}

}

0 comments on commit d213661

Please sign in to comment.