/* * @(#)APInterface.java * * Copyright 2010 by University of Pittsburgh, released under GPLv3. * */ package interfaces; import java.util.*; import core.*; /** *

A NetworkInterface that acts as an access point such that it bridges two * mobile hosts across a wired network. The collection of all APInterface * instances collectively manage a collection of hosts within range of any * AP. When a new host comes in range of one of them, instead of creating a new * connection between the AP node and the mobile node, multiple connections are * created to all the other mobile hosts in range of any AP.

* *

Each AP can listen on multiple interface types, configurable with the * interfaceCount and interface{i} settings, where {i} * is replaced by a number. If these settings are not supplied, the instances * will search for an attach to all the interface types defined for other node * groups. In either case, then, the APs act as a bridge not only across a * distance but also across different interfaces.

* * *

Facilitating this paradigm required some modification to the * NetworkInterface superclass and the other known subclasses of it. It is * necessary to prevent the NetworkInterface instances residing on other nodes * from successfully creating a Connection object with any APInterface instance * as the other endpoint in the connection, yet instances of APInterface still * had to be active as defined by isActive() in order for the simulator to * execute their update() functions.

* * @author PJ Dillon, Unversity of Pittsburgh * */ public class APInterface extends NetworkInterface { /** Number of interfaces to which to add these APs-setting id {@value} */ public static final String INTERFACE_COUNT_S = "interfaceCount"; /** Settings to define each interface to which to add these APs -setting id * {@value} */ public static final String INTERFACE_S_PREFIX = "interface"; protected static String[] interfaceTypes; /** * Collection of all hosts in range of an AP. */ protected static Map> connectedHosts; protected ConnectivityOptimizer[] optimizers = null; public APInterface(Settings settings) { super(settings); if(settings.contains(INTERFACE_COUNT_S)) { /* * Read each of type of interface the APs should service */ int gCount = settings.getInt(INTERFACE_COUNT_S); interfaceTypes = new String[gCount]; for(int i = 1; i <= gCount; i++) { interfaceTypes[i] = settings.getSetting(INTERFACE_S_PREFIX + i); } } else { /* * If the interfaces to which we're suppose to attach the APs isn't * explicitly declared, we search through all host groups looking for * declared instances of network interfaces. */ Settings s = new Settings(); int nrOfHostGroups = s.getInt("Scenario.nrofHostGroups"); Set interfaces = new HashSet(); for(int i = 1; i <= nrOfHostGroups; i++) { s.setNameSpace(core.SimScenario.GROUP_NS+i); s.setSecondaryNamespace(core.SimScenario.GROUP_NS); int nrofInterfaces = s.getInt(core.SimScenario.NROF_INTERF_S); for(int j = 1; j <= nrofInterfaces; j++) { interfaces.add(s.getSetting(core.SimScenario.INTERFACENAME_S+j)); } } interfaceTypes = new String[interfaces.size()]; int i = 0; for(String str : interfaces) interfaceTypes[i++] = str; } if(connectedHosts == null) connectedHosts = new HashMap>(); /* * Note that we specifically don't add this instance of APInterface to the * connectedHosts map here because this instance is a prototype instance * that is not actually used during simulation. */ } public APInterface(APInterface ni) { super(ni); this.optimizers = new ConnectivityOptimizer[interfaceTypes.length]; connectedHosts.put(this, new HashSet()); } @Override public NetworkInterface replicate() { return new APInterface(this); } @Override public void setHost(DTNHost host) { this.host = host; ModuleCommunicationBus comBus = host.getComBus(); comBus.subscribe(SCAN_INTERVAL_ID, this); comBus.subscribe(RANGE_ID, this); comBus.subscribe(SPEED_ID, this); // Instead of creating an new interface type, we add the instance to some // of or all of the other declared interface types for(int i = 0; i < interfaceTypes.length; i++) { optimizers[i] = ConnectivityGrid.ConnectivityGridFactory( interfaceTypes[i].hashCode(), transmitRange); optimizers[i].addInterface(this); } } @Override public void connect(NetworkInterface anotherInterface) { Collection myCollection = connectedHosts.get(this); if(anotherInterface.isActive() && isWithinRange(anotherInterface) && !myCollection.contains(anotherInterface) && !(anotherInterface instanceof APInterface)) { for(Map.Entry> entry : connectedHosts.entrySet()) { NetworkInterface farAP = entry.getKey(); if(farAP == this) continue; for(NetworkInterface ni : entry.getValue()) { int conSpeed = anotherInterface.getTransmitSpeed(); if (conSpeed > this.transmitSpeed) { conSpeed = this.transmitSpeed; } if(conSpeed > ni.getTransmitSpeed()) { conSpeed = ni.getTransmitSpeed(); } DTNHost nearEndpoint = anotherInterface.getHost(); DTNHost farEndpoint = ni.getHost(); /* * Connection Diagram: * * Host: nearEndpoint farEndpoint * \ / * Intermediary: anotherInterface ni * \ / * AP: this---------------farAP */ Connection con = new ProxiedCBRConnection(farEndpoint, ni, farAP, nearEndpoint, anotherInterface, this, conSpeed); ni.notifyConnectionListeners(CON_UP, anotherInterface.getHost()); // add con to end point connection lists anotherInterface.getConnections().add(con); ni.getConnections().add(con); // inform host routers about connection nearEndpoint.connectionUp(con); farEndpoint.connectionUp(con); } } myCollection.add(anotherInterface); } } @Override public void update() { for(int i = 0; i < optimizers.length; i++){ optimizers[i].updateLocation(this); } // First break the old ones for (Iterator i = connectedHosts.get(this).iterator(); i.hasNext();) { NetworkInterface anotherInterface = i.next(); if (!isWithinRange(anotherInterface)) { i.remove(); } } // Then find new possible connections for(int j = 0; j < optimizers.length; j++){ Collection interfaces = optimizers[j].getNearInterfaces(this); for (NetworkInterface i : interfaces) { connect(i); } } } @Override public void createConnection(NetworkInterface anotherInterface) { Collection myCollection = connectedHosts.get(this); if (!isConnected(anotherInterface) && !myCollection.contains(anotherInterface)) { for(NetworkInterface ni : myCollection) { // connection speed is the lower one of the two speeds int conSpeed = anotherInterface.getTransmitSpeed(); if (conSpeed > this.transmitSpeed) { conSpeed = this.transmitSpeed; } Connection con = new CBRConnection( anotherInterface.getHost(), anotherInterface, ni.getHost(), this, conSpeed); connect(con,anotherInterface); } } } @Override public boolean isActive() { return true; } @Override public boolean acceptingConnections() { return false; } }