/*
This file is part of jpcsp.
Jpcsp 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.
Jpcsp 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 Jpcsp. If not, see <http://www.gnu.org/licenses/>.
*/
package jpcsp.network.proonline;
import java.util.LinkedList;
import java.util.List;
import jpcsp.HLE.modules.sceNetApctl;
import jpcsp.network.upnp.UPnP;
/**
* @author gid15
*
*/
public class PortManager {
private List<String> hosts = new LinkedList<String>();
private List<PortInfo> portInfos = new LinkedList<PortInfo>();
private UPnP upnp;
private String localIPAddress;
private final static int portLeaseDuration = 0;
private final static String portDescription = "Jpcsp ProOnline Network";
private final static boolean SUPPORTS_MAPPING_FOR_MULTIPLE_REMOTE_HOSTS = false;
private final static String ALL_REMOTE_HOSTS = "";
private static class PortInfo {
int port;
String protocol;
public PortInfo(int port, String protocol) {
this.port = port;
this.protocol = protocol;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof PortInfo) {
PortInfo portInfo = (PortInfo) obj;
return port == portInfo.port && protocol.equals(portInfo.protocol);
}
return super.equals(obj);
}
}
public PortManager(UPnP upnp) {
this.upnp = upnp;
localIPAddress = sceNetApctl.getLocalHostIP();
}
protected String getLocalIPAddress() {
return localIPAddress;
}
public synchronized void addHost(String host) {
if (hosts.contains(host)) {
return;
}
if (SUPPORTS_MAPPING_FOR_MULTIPLE_REMOTE_HOSTS) {
// Open all the ports to this new host
for (PortInfo portInfo : portInfos) {
upnp.getIGD().addPortMapping(upnp, host, portInfo.port, portInfo.protocol, portInfo.port, getLocalIPAddress(), portDescription, portLeaseDuration);
}
} else {
if (hosts.isEmpty()) {
for (PortInfo portInfo : portInfos) {
upnp.getIGD().addPortMapping(upnp, ALL_REMOTE_HOSTS, portInfo.port, portInfo.protocol, portInfo.port, getLocalIPAddress(), portDescription, portLeaseDuration);
}
}
}
hosts.add(host);
}
public synchronized void removeHost(String host) {
if (!hosts.contains(host)) {
return;
}
hosts.remove(host);
if (SUPPORTS_MAPPING_FOR_MULTIPLE_REMOTE_HOSTS) {
// Remove all the port mappings from this host
for (PortInfo portInfo : portInfos) {
upnp.getIGD().deletePortMapping(upnp, host, portInfo.port, portInfo.protocol);
}
} else {
if (hosts.isEmpty()) {
for (PortInfo portInfo : portInfos) {
upnp.getIGD().deletePortMapping(upnp, ALL_REMOTE_HOSTS, portInfo.port, portInfo.protocol);
}
}
}
}
public synchronized void addPort(int port, String protocol) {
PortInfo portInfo = new PortInfo(port, protocol);
if (portInfos.contains(portInfo)) {
return;
}
if (SUPPORTS_MAPPING_FOR_MULTIPLE_REMOTE_HOSTS) {
// All the new port mapping for all the hosts
for (String host : hosts) {
upnp.getIGD().addPortMapping(upnp, host, port, protocol, port, getLocalIPAddress(), portDescription, portLeaseDuration);
}
} else {
upnp.getIGD().addPortMapping(upnp, ALL_REMOTE_HOSTS, port, protocol, port, getLocalIPAddress(), portDescription, portLeaseDuration);
}
portInfos.add(portInfo);
}
public synchronized void removePort(int port, String protocol) {
PortInfo portInfo = new PortInfo(port, protocol);
if (!portInfos.contains(portInfo)) {
return;
}
if (SUPPORTS_MAPPING_FOR_MULTIPLE_REMOTE_HOSTS) {
// Remove the port mapping for all the hosts
for (String host : hosts) {
upnp.getIGD().deletePortMapping(upnp, host, port, protocol);
}
} else {
upnp.getIGD().deletePortMapping(upnp, ALL_REMOTE_HOSTS, port, protocol);
}
portInfos.remove(portInfo);
}
public synchronized void clear() {
// Remove all the hosts
while (!hosts.isEmpty()) {
String host = hosts.get(0);
removeHost(host);
}
// ...and remove all the ports
while (!portInfos.isEmpty()) {
PortInfo portInfo = portInfos.get(0);
removePort(portInfo.port, portInfo.protocol);
}
}
}