/** * UPnP PortMapper - A tool for managing port forwardings via UPnP * Copyright (C) 2015 Christoph Pirkl <christoph at users.sourceforge.net> * * This program 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. * * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. */ package org.chris.portmapper.router.cling; import java.net.URI; import java.util.Collection; import org.chris.portmapper.model.PortMapping; import org.chris.portmapper.model.Protocol; import org.chris.portmapper.router.AbstractRouter; import org.chris.portmapper.router.RouterException; import org.chris.portmapper.router.cling.action.ActionService; import org.chris.portmapper.router.cling.action.AddPortMappingAction; import org.chris.portmapper.router.cling.action.DeletePortMappingAction; import org.chris.portmapper.router.cling.action.GetExternalIpAction; import org.fourthline.cling.controlpoint.ControlPoint; import org.fourthline.cling.model.meta.RemoteService; import org.fourthline.cling.model.meta.Service; import org.fourthline.cling.model.meta.UDAVersion; import org.fourthline.cling.registry.Registry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ClingRouter extends AbstractRouter { /** * The maximum number of port mappings that we will try to retrieve from the router. */ private final static int MAX_NUM_PORTMAPPINGS = 500; private final Logger logger = LoggerFactory.getLogger(this.getClass()); private final RemoteService service; private final Registry registry; private final ActionService actionService; public ClingRouter(final RemoteService service, final Registry registry, final ControlPoint controlPoint) { super(getName(service)); this.service = service; this.registry = registry; actionService = new ActionService(service, controlPoint); } private static String getName(final Service<?, ?> service) { return service.getDevice().getDisplayString(); } @Override public String getExternalIPAddress() throws RouterException { return actionService.run(new GetExternalIpAction(service)); } @Override public String getInternalHostName() { final URI uri = getUri(); return uri != null ? uri.getHost() : null; } @Override public int getInternalPort() throws RouterException { final URI uri = getUri(); return uri != null ? uri.getPort() : null; } private URI getUri() { if (service.getDevice().getDetails().getPresentationURI() != null) { return service.getDevice().getDetails().getPresentationURI(); } if (service.getControlURI() != null) { return service.getControlURI(); } if (service.getDescriptorURI() != null) { return service.getDescriptorURI(); } if (service.getEventSubscriptionURI() != null) { return service.getEventSubscriptionURI(); } return null; } @Override public Collection<PortMapping> getPortMappings() throws RouterException { return new ClingPortMappingExtractor(actionService, MAX_NUM_PORTMAPPINGS).getPortMappings(); } @Override public void logRouterInfo() throws RouterException { logger.info("Service id: " + service.getServiceId()); logger.info("Reference: " + service.getReference()); logger.info("Display name: " + service.getDevice().getDisplayString()); final UDAVersion version = service.getDevice().getVersion(); logger.info("Version: " + version.getMajor() + "." + version.getMinor()); logger.info("Control uri: {}", service.getControlURI()); logger.info("Descriptor uri: {}", service.getDescriptorURI()); logger.info("Event subscription uri: {}", service.getEventSubscriptionURI()); logger.info("Device base url: {}", service.getDevice().getDetails().getBaseURL()); logger.info("Device presentation uri: {}", service.getDevice().getDetails().getPresentationURI()); } @Override public void addPortMappings(final Collection<PortMapping> mappings) throws RouterException { for (final PortMapping portMapping : mappings) { addPortMapping(portMapping); } } @Override public void addPortMapping(final PortMapping mapping) throws RouterException { actionService.run(new AddPortMappingAction(service, mapping)); } @Override public void removeMapping(final PortMapping mapping) throws RouterException { actionService.run(new DeletePortMappingAction(service, mapping)); } @Override public void removePortMapping(final Protocol protocol, final String remoteHost, final int externalPort) throws RouterException { removeMapping(new PortMapping(protocol, remoteHost, externalPort, null, 0, null)); } @Override public void disconnect() { logger.debug("Shutdown registry"); registry.shutdown(); } }