├── data ├── cluster │ ├── origin.wkt │ └── ferryroute.wkt ├── HelsinkiMedium │ ├── B_meetingspots.wkt │ ├── C_meetingspots.wkt │ ├── D_meetingspots.wkt │ ├── E_meetingspots.wkt │ ├── A_meetingspots.wkt │ ├── F_meetingspots.wkt │ ├── G_meetingspots.wkt │ ├── D_bus.wkt │ ├── A_bus.wkt │ ├── C_bus.wkt │ ├── E_bus.wkt │ ├── B_offices.wkt │ ├── F_bus.wkt │ ├── B_bus.wkt │ ├── G_bus.wkt │ ├── H_bus.wkt │ ├── D_offices.wkt │ ├── C_offices.wkt │ ├── E_offices.wkt │ ├── A_offices.wkt │ ├── G_offices.wkt │ └── F_offices.wkt ├── helsinki_underlay.png ├── WestPOIs.wkt ├── CentralPOIs.wkt ├── tram10.wkt ├── throwboxes.wkt ├── tram4.wkt ├── tram3.wkt ├── ParkPOIs.wkt ├── Manhattan │ └── bus.wkt ├── demo_bus.wkt └── pedestrian_paths.wkt ├── lib ├── ECLA.jar └── DTNConsoleConnection.jar ├── one.bat ├── example_settings ├── epidemic_settings.txt ├── snw_settings.txt ├── connect_connector_test.txt ├── snw_comparison_settings.txt ├── ping_app_settings.txt ├── wlan-interface.txt └── prophet_settings.txt ├── one.sh ├── src ├── gui │ ├── buttonGraphics │ │ ├── Play16.gif │ │ ├── Play24.gif │ │ ├── Zoom16.gif │ │ ├── Zoom24.gif │ │ ├── Pause16.gif │ │ ├── Pause24.gif │ │ ├── FastForward16.gif │ │ ├── FastForward24.gif │ │ ├── StepForward16.gif │ │ └── StepForward24.gif │ ├── package.html │ ├── playfield │ │ ├── package.html │ │ ├── MessageGraphic.java │ │ ├── MapGraphic.java │ │ ├── PathGraphic.java │ │ ├── ScaleReferenceGraphic.java │ │ └── PlayFieldGraphic.java │ ├── nodefilter │ │ ├── NodeFilter.java │ │ └── NodeMessageFilter.java │ └── EventLogControl.java ├── util │ ├── package.html │ ├── Tuple.java │ ├── ParetoRNG.java │ └── Range.java ├── routing │ ├── maxprop │ │ └── package.html │ ├── package.html │ ├── DirectDeliveryRouter.java │ ├── PassiveRouter.java │ ├── EpidemicRouter.java │ ├── util │ │ └── RoutingInfo.java │ ├── FirstContactRouter.java │ └── schedule │ │ ├── ScheduleEntry.java │ │ └── ScheduleOracle.java ├── test │ ├── package.html │ ├── CoordTest.java │ ├── MessageTest.java │ ├── StationaryMovement.java │ ├── WKTPointReaderTest.java │ ├── ActivenessHandlerTest.java │ ├── TestSettings.java │ ├── TestDTNHost.java │ ├── AllTests.java │ ├── ExternalMovementReaderTest.java │ ├── MessageGraphvizReportTest.java │ ├── MapNodeTest.java │ ├── DijkstraPathFinderTest.java │ ├── TestInterface.java │ └── DistanceDelayReportTest.java ├── ui │ ├── package.html │ └── DTNSimTextUI.java ├── input │ ├── package.html │ ├── ExternalEventsReader.java │ ├── EventQueue.java │ ├── MessageEvent.java │ ├── MessageDeleteEvent.java │ ├── MessageCreateEvent.java │ ├── ConnectionEvent.java │ ├── ExternalEvent.java │ ├── MessageRelayEvent.java │ ├── OneToEachMessageGenerator.java │ └── OneFromEachMessageGenerator.java ├── movement │ ├── map │ │ └── package.html │ ├── TransportMovement.java │ ├── package.html │ ├── SwitchableMovement.java │ ├── ModifiedRandomDirection.java │ ├── RandomWaypoint.java │ ├── StationaryMovement.java │ ├── CarMovement.java │ ├── ClusterMovement.java │ ├── RandomWalk.java │ ├── ShortestPathMapBasedMovement.java │ ├── BusMovement.java │ └── ExtendedMovementModel.java ├── core │ ├── Constants.java │ ├── package.html │ ├── SettingsError.java │ ├── SimError.java │ ├── ModuleCommunicationListener.java │ ├── UpdateListener.java │ ├── ConnectionListener.java │ ├── MovementListener.java │ ├── ApplicationListener.java │ ├── MessageListener.java │ ├── SimClock.java │ └── ArithmeticCondition.java ├── report │ ├── package.html │ ├── LocationSnapshotReport.java │ ├── MovementListenerTestReport.java │ ├── EnergyLevelReport.java │ ├── InterContactTimesReport.java │ ├── MessageCopyCountReport.java │ ├── ContactsPerHourReport.java │ ├── CreatedMessagesReport.java │ ├── MessageReport.java │ ├── TotalEncountersReport.java │ ├── ConnectivityDtnsim2Report.java │ ├── EncountersVSUniqueEncountersReport.java │ ├── ConnectivityONEReport.java │ ├── MessageDeliveryReport.java │ ├── UniqueEncountersReport.java │ ├── MessageDelayReport.java │ ├── MessageGraphvizReport.java │ ├── DeliveredMessagesReport.java │ ├── PingAppReporter.java │ ├── TotalContactTimeReport.java │ └── BufferOccupancyReport.java └── interfaces │ └── ConnectivityOptimizer.java ├── target └── gui │ └── buttonGraphics │ ├── Pause16.gif │ ├── Pause24.gif │ ├── Play16.gif │ ├── Play24.gif │ ├── Zoom16.gif │ ├── Zoom24.gif │ ├── FastForward16.gif │ ├── FastForward24.gif │ ├── StepForward16.gif │ └── StepForward24.gif ├── toolkit ├── dtnsim2patches │ ├── README.txt │ ├── DummyEpidemicHandler.java.diff │ └── EpidemicKnowledgeHandler.java.diff ├── messageAvailabilityAnalyzer.pl ├── Common.pm ├── createCircles.pl ├── transimsParser.pl ├── messageCopyCountPlotter.pl ├── dtnsim2parser.pl ├── getAverages.pl ├── getStatsAverages.pl ├── createCreates.pl └── delProb.pl ├── doc └── create_docs.sh ├── .gitignore ├── README.md ├── compile.sh ├── .gitattributes ├── compile.bat ├── CONTRIBUTING.md ├── wdm_settings └── WDM_conf_help.txt └── ee └── 70_events_100_nodes_700ks.txt /data/cluster/origin.wkt: -------------------------------------------------------------------------------- 1 | LINESTRING (0 0, 100 -100) 2 | -------------------------------------------------------------------------------- /lib/ECLA.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeranen/the-one/HEAD/lib/ECLA.jar -------------------------------------------------------------------------------- /data/cluster/ferryroute.wkt: -------------------------------------------------------------------------------- 1 | LINESTRING (100 -100, 600 -100, 350 -533, 100 -100) 2 | -------------------------------------------------------------------------------- /data/HelsinkiMedium/B_meetingspots.wkt: -------------------------------------------------------------------------------- 1 | POINT (2548669.62194887 6672165.182219516) 2 | -------------------------------------------------------------------------------- /one.bat: -------------------------------------------------------------------------------- 1 | java -Xmx512M -cp target;lib/ECLA.jar;lib/DTNConsoleConnection.jar core.DTNSim %* -------------------------------------------------------------------------------- /example_settings/epidemic_settings.txt: -------------------------------------------------------------------------------- 1 | Scenario.name = Epidemic 2 | Group.router = EpidemicRouter 3 | -------------------------------------------------------------------------------- /data/helsinki_underlay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeranen/the-one/HEAD/data/helsinki_underlay.png -------------------------------------------------------------------------------- /lib/DTNConsoleConnection.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeranen/the-one/HEAD/lib/DTNConsoleConnection.jar -------------------------------------------------------------------------------- /one.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | java -Xmx512M -cp target:lib/ECLA.jar:lib/DTNConsoleConnection.jar core.DTNSim $* 3 | -------------------------------------------------------------------------------- /src/gui/buttonGraphics/Play16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeranen/the-one/HEAD/src/gui/buttonGraphics/Play16.gif -------------------------------------------------------------------------------- /src/gui/buttonGraphics/Play24.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeranen/the-one/HEAD/src/gui/buttonGraphics/Play24.gif -------------------------------------------------------------------------------- /src/gui/buttonGraphics/Zoom16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeranen/the-one/HEAD/src/gui/buttonGraphics/Zoom16.gif -------------------------------------------------------------------------------- /src/gui/buttonGraphics/Zoom24.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeranen/the-one/HEAD/src/gui/buttonGraphics/Zoom24.gif -------------------------------------------------------------------------------- /src/gui/buttonGraphics/Pause16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeranen/the-one/HEAD/src/gui/buttonGraphics/Pause16.gif -------------------------------------------------------------------------------- /src/gui/buttonGraphics/Pause24.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeranen/the-one/HEAD/src/gui/buttonGraphics/Pause24.gif -------------------------------------------------------------------------------- /target/gui/buttonGraphics/Pause16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeranen/the-one/HEAD/target/gui/buttonGraphics/Pause16.gif -------------------------------------------------------------------------------- /target/gui/buttonGraphics/Pause24.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeranen/the-one/HEAD/target/gui/buttonGraphics/Pause24.gif -------------------------------------------------------------------------------- /target/gui/buttonGraphics/Play16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeranen/the-one/HEAD/target/gui/buttonGraphics/Play16.gif -------------------------------------------------------------------------------- /target/gui/buttonGraphics/Play24.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeranen/the-one/HEAD/target/gui/buttonGraphics/Play24.gif -------------------------------------------------------------------------------- /target/gui/buttonGraphics/Zoom16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeranen/the-one/HEAD/target/gui/buttonGraphics/Zoom16.gif -------------------------------------------------------------------------------- /target/gui/buttonGraphics/Zoom24.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeranen/the-one/HEAD/target/gui/buttonGraphics/Zoom24.gif -------------------------------------------------------------------------------- /toolkit/dtnsim2patches/README.txt: -------------------------------------------------------------------------------- 1 | Patches that have to be applied to dtnsim2 sources for dtnsim2parser to work properly. 2 | -------------------------------------------------------------------------------- /src/gui/buttonGraphics/FastForward16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeranen/the-one/HEAD/src/gui/buttonGraphics/FastForward16.gif -------------------------------------------------------------------------------- /src/gui/buttonGraphics/FastForward24.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeranen/the-one/HEAD/src/gui/buttonGraphics/FastForward24.gif -------------------------------------------------------------------------------- /src/gui/buttonGraphics/StepForward16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeranen/the-one/HEAD/src/gui/buttonGraphics/StepForward16.gif -------------------------------------------------------------------------------- /src/gui/buttonGraphics/StepForward24.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeranen/the-one/HEAD/src/gui/buttonGraphics/StepForward24.gif -------------------------------------------------------------------------------- /target/gui/buttonGraphics/FastForward16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeranen/the-one/HEAD/target/gui/buttonGraphics/FastForward16.gif -------------------------------------------------------------------------------- /target/gui/buttonGraphics/FastForward24.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeranen/the-one/HEAD/target/gui/buttonGraphics/FastForward24.gif -------------------------------------------------------------------------------- /target/gui/buttonGraphics/StepForward16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeranen/the-one/HEAD/target/gui/buttonGraphics/StepForward16.gif -------------------------------------------------------------------------------- /target/gui/buttonGraphics/StepForward24.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akeranen/the-one/HEAD/target/gui/buttonGraphics/StepForward24.gif -------------------------------------------------------------------------------- /data/HelsinkiMedium/C_meetingspots.wkt: -------------------------------------------------------------------------------- 1 | POINT (2551019.4859670075 6675223.744247892) 2 | 3 | POINT (2551776.083972117 6676132.332795221) 4 | -------------------------------------------------------------------------------- /data/HelsinkiMedium/D_meetingspots.wkt: -------------------------------------------------------------------------------- 1 | POINT (2553423.037969719 6674726.15003564) 2 | 3 | POINT (2551506.1838812567 6676962.873428298) 4 | -------------------------------------------------------------------------------- /data/HelsinkiMedium/E_meetingspots.wkt: -------------------------------------------------------------------------------- 1 | POINT (2552080.145394281 6673330.999808344) 2 | 3 | POINT (2552531.1145652616 6673268.445450311) 4 | -------------------------------------------------------------------------------- /data/WestPOIs.wkt: -------------------------------------------------------------------------------- 1 | POINT (2550854.3137440286 6672591.750129179) 2 | 3 | POINT (2551121.9534618445 6672693.903576347) 4 | 5 | POINT (2550700.913609861 6672866.723243455) 6 | -------------------------------------------------------------------------------- /example_settings/snw_settings.txt: -------------------------------------------------------------------------------- 1 | Scenario.name = SprayAndWait 2 | Group.router = SprayAndWaitRouter 3 | SprayAndWaitRouter.nrofCopies = 10 4 | SprayAndWaitRouter.binaryMode = true 5 | -------------------------------------------------------------------------------- /doc/create_docs.sh: -------------------------------------------------------------------------------- 1 | javadoc -classpath ../target:../lib/ECLA.jar:../lib/DTNConsoleConnection.jar -sourcepath ../src/ -subpackages core:ui:gui:input:movement:report:routing:applications:interfaces:util 2 | -------------------------------------------------------------------------------- /src/gui/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Contains the classes of Graphical User Interface. 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/util/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Contains utility classes used in different contexts. 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/routing/maxprop/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Contains MaxProp routing module specific classes. 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/test/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Provides some unit and integration tests for the classes. 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /data/CentralPOIs.wkt: -------------------------------------------------------------------------------- 1 | POINT (2552448.388211649 6673384.4020657055) 2 | 3 | POINT (2552275.9398973365 6673509.820852942) 4 | 5 | POINT (2552361.289603607 6673630.088457832) 6 | 7 | POINT (2552782.3212060533 6673285.5993876355) 8 | -------------------------------------------------------------------------------- /src/ui/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Contains superclass for all user interfaces and a simple user interface(s). 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/input/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Provides interfaces and classes for reading input data from external sources. 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /data/HelsinkiMedium/A_meetingspots.wkt: -------------------------------------------------------------------------------- 1 | POINT (2551832.205570006 6673236.458108292) 2 | 3 | POINT (2552398.0412894213 6673352.814815518) 4 | 5 | POINT (2552271.1386670014 6673506.220026447) 6 | 7 | POINT (2552747.310172474 6672343.373119477) 8 | -------------------------------------------------------------------------------- /data/HelsinkiMedium/F_meetingspots.wkt: -------------------------------------------------------------------------------- 1 | POINT (2551753.9422157253 6673510.250951662) 2 | 3 | POINT (2552669.1210640236 6673406.247079767) 4 | 5 | POINT (2550808.454569743 6675266.964168113) 6 | 7 | POINT (2550105.5033015246 6676255.961171506) 8 | -------------------------------------------------------------------------------- /data/HelsinkiMedium/G_meetingspots.wkt: -------------------------------------------------------------------------------- 1 | POINT (2552399.5592041663 6675863.2110239975) 2 | 3 | POINT (2552122.746001586 6673002.154328803) 4 | 5 | POINT (2552677.906820565 6673285.539373861) 6 | 7 | POINT (2552459.211603745 6673074.480929848) 8 | -------------------------------------------------------------------------------- /data/HelsinkiMedium/D_bus.wkt: -------------------------------------------------------------------------------- 1 | LINESTRING (2553320.273491563 6674457.528379207, 2553719.84804916 6675104.546888653, 2553670.9035481643 6675714.12680486, 2553683.145860566 6676146.346011659, 2553528.33505563 6676650.701775882, 2553727.5943640824 6677300.7809878485) 2 | -------------------------------------------------------------------------------- /src/movement/map/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Sub package for MapBasedMovement movement model's (and its sub classes) 6 | helper classes. 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /data/tram10.wkt: -------------------------------------------------------------------------------- 1 | LINESTRING (2552787.726166266 6672530.040305593, 2552686.56058452 6672754.707532612, 2552579.465099618 6673027.760206092, 2552440.104393391 6673297.548247428, 2552172.432960881 6673639.590638857, 2551943.3598269443 6674056.316289438, 2551761.5729668215 6674388.38925647) 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled files 2 | *.class 3 | 4 | # Simulation report files 5 | *reports*/*.txt 6 | 7 | # Javadocs 8 | *.html 9 | doc/stylesheet.css 10 | doc/resources/*.gif 11 | doc/package-list 12 | 13 | # Eclipse IDE files 14 | .classpath 15 | .project 16 | /target/ 17 | .settings/org.eclipse.* 18 | -------------------------------------------------------------------------------- /toolkit/dtnsim2patches/DummyEpidemicHandler.java.diff: -------------------------------------------------------------------------------- 1 | 255c255,256 2 | < network.vprint("Removing copy of " + m + " - ACKed or delivered to final destination."); 3 | --- 4 | > network.vprint("Removing copy of " + m + " at " + this.parent.getName()); 5 | > // ACKed or delivered to final destination. 6 | -------------------------------------------------------------------------------- /src/gui/playfield/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Contains the classes of Graphical User Interface's playfield -view 6 | (the graphical presentation of the nodes' locations and other information). 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /example_settings/connect_connector_test.txt: -------------------------------------------------------------------------------- 1 | Report.nrofReports = 1 2 | Report.report1 = ConnectivityReportConnector 3 | ConnectivityReportConnector.address = localhost 4 | ConnectivityReportConnector.port = 50042 5 | # How many digits in connection speed 6 | ConnectivityReportConnector.precision = 0 7 | 8 | Optimization.realtime = true -------------------------------------------------------------------------------- /src/core/Constants.java: -------------------------------------------------------------------------------- 1 | package core; 2 | 3 | /** 4 | * Global constants. 5 | * 6 | * @author teemuk 7 | */ 8 | public final class Constants { 9 | /** Disallow instantiation */ 10 | private Constants() {} 11 | 12 | /** Enable/disable debug mode. Used to compile out debug logging etc. */ 13 | public static final boolean DEBUG = false; 14 | } 15 | -------------------------------------------------------------------------------- /data/throwboxes.wkt: -------------------------------------------------------------------------------- 1 | LINESTRING (2553039.1292822366 6673301.743093083) 2 | 3 | LINESTRING (2552275.9398973365 6673509.820852942) 4 | 5 | LINESTRING (2552559.517719977 6673146.45745054) 6 | 7 | LINESTRING (2552017.9191392646 6673946.871168619) 8 | 9 | LINESTRING (2551949.8274636846 6673239.518810811) 10 | 11 | LINESTRING (2552473.318311431 6673253.912114491) 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The ONE 2 | 3 | The Opportunistic Network Environment simulator. 4 | 5 | For introduction and releases, see [the ONE homepage at GitHub](http://akeranen.github.io/the-one/). 6 | 7 | For instructions on how to get started, see [the README](https://github.com/akeranen/the-one/wiki/README). 8 | 9 | The [wiki page](https://github.com/akeranen/the-one/wiki) has the latest information. 10 | -------------------------------------------------------------------------------- /compile.sh: -------------------------------------------------------------------------------- 1 | targetdir=target 2 | 3 | if [ ! -d "$targetdir" ]; then mkdir $targetdir; fi 4 | 5 | javac -sourcepath src -d $targetdir -cp lib/ECLA.jar:lib/DTNConsoleConnection.jar src/core/*.java src/movement/*.java src/report/*.java src/routing/*.java src/gui/*.java src/input/*.java src/applications/*.java src/interfaces/*.java 6 | 7 | if [ ! -d "$targetdir/gui/buttonGraphics" ]; then cp -R src/gui/buttonGraphics target/gui/; fi 8 | 9 | -------------------------------------------------------------------------------- /data/tram4.wkt: -------------------------------------------------------------------------------- 1 | LINESTRING (2554383.251038637 6673258.043062663, 2554164.2258403506 6673085.173384075, 2553841.6277093147 6673119.391238062, 2553707.4902432454 6673207.421443538, 2553241.3996715695 6673442.8554824535, 2552930.1703346907 6673422.44040407, 2552720.809051393 6673409.434952837, 2552480.8583879373 6673392.573941387, 2552172.432960881 6673639.590638857, 2551943.3598269443 6674056.316289438, 2 | 2551761.5729668215 6674388.38925647) 3 | -------------------------------------------------------------------------------- /src/core/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Contains core classes and interfaces of the simulator. 6 | 7 | Almost all of these classes are needed for every run of the simulator. 8 | DTNSim is the main class of the program. It starts up a proper user interface 9 | which in turn starts the simulation. 10 | 11 | @see ui.DTNSimUI 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /data/HelsinkiMedium/A_bus.wkt: -------------------------------------------------------------------------------- 1 | LINESTRING (2553558.1158829676 6674022.108437747, 2553256.4880741183 6674002.824011413, 2552932.8422519267 6673978.828503751, 2552757.3251099777 6673680.650063182, 2552363.5334775783 6673567.544102095, 2552275.651163554 6673509.600802434, 2551892.3364427104 6673318.977048773, 2552122.746001586 6673002.154328803, 2552264.671030261 6672803.6187591525, 2552483.811722061 6672500.92928317, 2 | 2552253.088680792 6672172.793966631) 3 | -------------------------------------------------------------------------------- /data/HelsinkiMedium/C_bus.wkt: -------------------------------------------------------------------------------- 1 | LINESTRING (2551844.6623703605 6674216.3330179015, 2551557.9002265697 6674544.118254086, 2551245.6800126503 6674810.619423806, 2551126.16072554 6675032.970459795, 2551042.675414555 6675236.6272049025, 2550817.5785572873 6675557.160776621, 2550277.86912047 6675871.0628262125, 2549830.537995156 6676063.476990825, 2549305.5374822007 6676406.915819961, 2548940.256248493 6676559.490840337, 2 | 2548569.3983280044 6677113.988113486) 3 | -------------------------------------------------------------------------------- /example_settings/snw_comparison_settings.txt: -------------------------------------------------------------------------------- 1 | Scenario.name = SNWComp-%%SprayAndWaitRouter.nrofCopies%%-B%%SprayAndWaitRouter.binaryMode%% 2 | 3 | Group.router = SprayAndWaitRouter 4 | 5 | SprayAndWaitRouter.nrofCopies = [1;2;3;4;5;6;7;8;9;10;11] 6 | SprayAndWaitRouter.binaryMode = [true;false] 7 | 8 | 9 | MovementModel.rngSeed = 0 10 | Report.nrofReports = 1 11 | Report.report1 = MessageStatsReport 12 | 13 | Report.reportDir = snwcomp_reports/ 14 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Keep EOLs consistent 2 | 3 | * text=auto 4 | 5 | *.java text 6 | *.txt text 7 | *.md text 8 | *.bat text 9 | *.sh text 10 | *.pl text 11 | *.pm text 12 | *.py text 13 | 14 | # Windows batch files should retain CRLF 15 | *.bat text eol=crlf 16 | 17 | *.class binary 18 | *.gif binary 19 | *.png binary 20 | *.jar binary 21 | -------------------------------------------------------------------------------- /src/movement/TransportMovement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package movement; 6 | 7 | import core.Coord; 8 | 9 | /** 10 | * MovementModels used for transportation should implement this interface 11 | * 12 | * @author Frans Ekman 13 | */ 14 | public interface TransportMovement extends SwitchableMovement { 15 | 16 | public void setNextRoute(Coord nodeLocation, Coord nodeDestination); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /compile.bat: -------------------------------------------------------------------------------- 1 | set targetdir=target 2 | 3 | IF NOT EXIST "%targetdir%" mkdir %targetdir% 4 | 5 | javac -sourcepath src -d %targetdir% -cp lib/ECLA.jar;lib/DTNConsoleConnection.jar src/core/*.java src/movement/*.java src/report/*.java src/routing/*.java src/gui/*.java src/input/*.java src/applications/*.java src/interfaces/*.java 6 | 7 | 8 | 9 | IF NOT EXIST "%targetdir%\gui\buttonGraphics" ( 10 | mkdir %targetdir%\gui\buttonGraphics 11 | copy src\gui\buttonGraphics\* %targetdir%\gui\buttonGraphics\ 12 | ) 13 | -------------------------------------------------------------------------------- /data/HelsinkiMedium/E_bus.wkt: -------------------------------------------------------------------------------- 1 | LINESTRING (2548008.8175634407 6672181.105874455, 2547920.7125119264 6672681.830805297, 2548383.8002522583 6672630.819096636, 2549125.219109916 6672924.776568371, 2550869.4433942605 6673004.914962448, 2551317.2612422374 6672889.818544494, 2551612.3884162 6672988.061093998, 2551699.751009415 6673299.7926453985, 2551893.5491245994 6673447.066448992, 2552153.657015446 6673654.484057328, 2 | 2552256.454491749 6673534.296470803, 2552719.2287496882 6673650.273090789, 2553233.3316247175 6673542.7184038805) 3 | -------------------------------------------------------------------------------- /src/core/SettingsError.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package core; 6 | 7 | /** 8 | * Settings related error 9 | * 10 | */ 11 | public class SettingsError extends SimError { 12 | 13 | public SettingsError(String cause) { 14 | super(cause); 15 | } 16 | 17 | public SettingsError(String cause, Exception e) { 18 | super(cause,e); 19 | } 20 | 21 | public SettingsError(Exception e) { 22 | super(e); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /data/tram3.wkt: -------------------------------------------------------------------------------- 1 | LINESTRING (2552480.8583879373 6673392.573941387, 2552720.809051393 6673409.434952837, 2552930.1703346907 6673422.44040407, 2553055.669603237 6673293.861283979, 2553058.119715625 6673058.3372244015, 2553281.9791423935 6672606.85359586, 2553180.9635660085 6672364.467961353, 2552883.7245106613 6672239.799346303, 2552708.001130296 6672220.484913082, 2552440.7491407027 6672213.753367998, 2 | 2552483.811722061 6672500.92928317, 2552341.7794494093 6672696.104081427, 2552261.900555275 6672932.613958296, 2552508.7708714856 6673110.496865532) 3 | -------------------------------------------------------------------------------- /data/HelsinkiMedium/B_offices.wkt: -------------------------------------------------------------------------------- 1 | POINT (2547765.695468574 6671861.002401457) 2 | 3 | POINT (2547876.3630028493 6671967.746902404) 4 | 5 | POINT (2548337.0088803307 6671880.666915031) 6 | 7 | POINT (2548821.3804252422 6671791.406427169) 8 | 9 | POINT (2549000.560361468 6672094.435981209) 10 | 11 | POINT (2549328.726929748 6672406.747665767) 12 | 13 | POINT (2548973.5431289105 6672751.016685456) 14 | 15 | POINT (2549125.4665960157 6671310.466037451) 16 | 17 | POINT (2548899.0168147366 6671469.6525753625) 18 | 19 | POINT (2549038.92070693 6671689.052934085) 20 | -------------------------------------------------------------------------------- /toolkit/dtnsim2patches/EpidemicKnowledgeHandler.java.diff: -------------------------------------------------------------------------------- 1 | 212c212,213 2 | < network.vprint("Removing copy of " + m + " - ACKed or delivered to final destination."); 3 | --- 4 | > network.vprint("Removing copy of " + m + " at " + this.parent.getName()); 5 | > // ACKed or delivered to final destination. 6 | 312c313,314 7 | < parent.getNetwork().vprint("DROPPED epidemic " + m + " to free buffer space for " + forMsg); 8 | --- 9 | > parent.getNetwork().vprint("DROPPED epidemic " + m + " to free buffer space for " + forMsg + 10 | > " at " + parent.getName()); 11 | -------------------------------------------------------------------------------- /data/HelsinkiMedium/F_bus.wkt: -------------------------------------------------------------------------------- 1 | LINESTRING (2552951.6016982887 6671978.96947831, 2552883.7245106613 6672239.799346303, 2552821.9107324784 6672739.764102663, 2552599.255738062 6672877.725768852, 2552478.6805102592 6673256.062608091, 2552288.5451893513 6673519.573091362, 2552063.959803357 6673790.795344708, 2551861.5739205102 6674198.388899207, 2551681.816516719 6674680.479552944, 2551335.641209913 6675218.222980602, 2 | 2551083.634364065 6675615.144085466, 2550671.0337880836 6675975.426780757, 2550010.88111605 6676239.047289281, 2549500.1028042943 6676330.738335026, 2548940.256248493 6676559.490840337) 3 | -------------------------------------------------------------------------------- /src/report/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Contains all the report classes. Reports can be used to create e.g. statistics 6 | and visualizations of the simulation. All report classes must be in this 7 | package and must extend the {@link report.Report} class so they can be 8 | dynamically loaded to the simulator. The classes to load can be specified 9 | trough {@link core.Settings} class' settings source. See Report class and 10 | classes extending it for details about the settings. 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /data/ParkPOIs.wkt: -------------------------------------------------------------------------------- 1 | POINT (2553143.9097474786 6672121.598159393) 2 | 3 | POINT (2553290.179181832 6672173.0340217315) 4 | 5 | POINT (2553205.4575377535 6672050.908441204) 6 | 7 | POINT (2553015.3458680497 6672745.815491632) 8 | 9 | POINT (2553072.3655058085 6672628.625246054) 10 | 11 | POINT (2552990.331251769 6672620.934534737) 12 | 13 | POINT (2553248.9572028136 6671937.993476591) 14 | 15 | POINT (2553249.4343082923 6672094.541162056) 16 | 17 | POINT (2552785.543273026 6673249.298489128) 18 | 19 | POINT (2552729.0506920097 6673245.719605062) 20 | 21 | POINT (2552841.676618883 6673253.251878758) 22 | -------------------------------------------------------------------------------- /example_settings/ping_app_settings.txt: -------------------------------------------------------------------------------- 1 | # This configuration file adds Ping application for all the nodes and 2 | # a report module that counts the number of pings & pongs sent & received 3 | 4 | # Define new application 5 | pingApp.type = PingApplication 6 | pingApp.interval = 500 7 | pingApp.destinationRange = 0,125 8 | pingApp.pingSize = 5 9 | pingApp.pongSize = 5 10 | pingApp.passive = false 11 | 12 | # Set Ping app for all nodes 13 | Group.nrofApplications = 1 14 | Group.application1 = pingApp 15 | 16 | # Add report for Ping app 17 | Report.nrofReports = 2 18 | Report.report2 = PingAppReporter 19 | 20 | -------------------------------------------------------------------------------- /example_settings/wlan-interface.txt: -------------------------------------------------------------------------------- 1 | 2 | wlanInterface.type = DistanceCapacityInterface 3 | 4 | # values from http://www.xirrus.com/cdn/pdf/wifi-demystified/documents_posters_range_plotter 5 | # 0-50ft:54Mbps, 75-100ft:48 Mbps, 125ft:36Mbps, 150ft:24 Mbps, 175ft:18Mbps, 6 | # 200ft:12Mbps, 225ft:9Mbps, 250ft:6Mbps, 275ft:2Mbps, 300ft:1Mbps 7 | 8 | wlanInterface.transmitSpeeds = 6750k, 6750k, 6750k, 6000k, 6000k, 4500k, 3000k, 2250k, 1500k, 1125k, 750k, 250k, 125k 9 | wlanInterface.transmitRange = 91 10 | 11 | # dummy speed 12 | wlanInterface.transmitSpeed = 0 13 | 14 | Group.interface1 = wlanInterface 15 | -------------------------------------------------------------------------------- /data/HelsinkiMedium/B_bus.wkt: -------------------------------------------------------------------------------- 1 | LINESTRING (2549711.7116691247 6672521.834081425, 2549326.1448247735 6672446.546800818, 2548919.9211406293 6672451.737992347, 2548857.076170364 6672141.0166728245, 2549038.92070693 6671689.052934085, 2549125.4665960157 6671310.466037451, 2548826.6848773137 6671777.543245168, 2548721.940510359 6672165.17221722, 2548776.5689421124 6672470.202230424, 2548598.576939166 6672504.560116551, 2 | 2548409.3490672903 6672539.118048595, 2548204.9172993526 6672577.186786471, 2547920.50627351 6672635.070072358, 2547945.8323510517 6672417.580152135, 2548008.8175634407 6672181.105874455, 2547895.0977006014 6671978.22930842) 3 | -------------------------------------------------------------------------------- /src/input/ExternalEventsReader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package input; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * Interface for external event readers. 11 | */ 12 | public interface ExternalEventsReader { 13 | 14 | /** 15 | * Read events from the reader 16 | * @param nrof Maximum number of events to read 17 | * @return Events in a List 18 | */ 19 | public List readEvents(int nrof); 20 | 21 | /** 22 | * Closes the input file streams of the reader. 23 | */ 24 | public void close(); 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/core/SimError.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package core; 6 | 7 | /** 8 | * Error in the simulation 9 | * 10 | */ 11 | public class SimError extends AssertionError { 12 | private Exception e; 13 | 14 | public SimError(String cause) { 15 | super(cause); 16 | e = null; 17 | } 18 | 19 | public SimError(String cause, Exception e) { 20 | super(cause); 21 | this.e = e; 22 | } 23 | 24 | public SimError(Exception e) { 25 | this(e.getMessage(),e); 26 | } 27 | 28 | public Exception getException() { 29 | return e; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/routing/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Contains all the router classes who decide how to handle the messages. 6 | All router classes must be in this package and must extend the 7 | {@link routing.MessageRouter} (when creating new routers, extending 8 | {@link routing.ActiveRouter} might make sense) class so they can be 9 | dynamically loaded to the simulator. The classes to load can be specified 10 | through {@link core.Settings} class' settings source. See MessageRouter class 11 | and classes extending it for details about the settings. 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /data/Manhattan/bus.wkt: -------------------------------------------------------------------------------- 1 | LINESTRING (2549691.4669673573 6673187.82779412, 2550453.412051166 6673207.361937253, 2551222.2931330632 6673212.614600562, 2551968.1713229036 6673212.614600562, 2552703.235282084 6673187.82779412, 2552708.4879453927 6673891.68467749, 2552735.650626272 6674643.226953467, 2552724.8363956125 6675327.549693705, 2552730.089058921 6676020.901250457, 2551995.025099741 6676045.688056899, 2 | 2551249.1469099005 6676045.688056899, 2550480.265828003 6676040.4353935905, 2549718.3207441946 6676020.901250457, 2549713.068080886 6675327.549693705, 2549723.8823115453 6674643.226953467, 2549696.719630666 6673891.68467749, 2549691.4669673573 6673187.82779412) 3 | -------------------------------------------------------------------------------- /data/HelsinkiMedium/G_bus.wkt: -------------------------------------------------------------------------------- 1 | LINESTRING (2551217.6480870843 6672787.2850100845, 2551825.407951799 6673124.782475507, 2552378.5476342966 6673187.666909302, 2552978.882916019 6673298.132264293, 2552956.9143998967 6673618.665836011, 2552928.601990084 6674017.417361009, 2552890.282892305 6674615.774701311, 2553233.0593900075 6674893.908541065, 2553448.322799578 6675165.300833439, 2553667.3479978647 6675699.133363432, 2 | 2553672.2564721764 6676175.662740696, 2553528.33505563 6676650.701775882, 2553570.820169422 6677006.193371478, 2553044.7884643846 6677290.308584129, 2552610.153375988 6677178.372891653, 2552800.0082126497 6676643.68016422, 2552847.575041023 6676242.638113479) 3 | -------------------------------------------------------------------------------- /src/gui/nodefilter/NodeFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | 6 | package gui.nodefilter; 7 | 8 | import core.DTNHost; 9 | 10 | /** 11 | * Interface for node filtering classes 12 | */ 13 | public interface NodeFilter { 14 | 15 | /** 16 | * Returns true if the given node should be included in the filtered set 17 | * @param node The node to check 18 | * @return true if the node should be included, false if not 19 | */ 20 | public boolean filterNode(DTNHost node); 21 | 22 | /** 23 | * Returns a String presentations of the filter 24 | */ 25 | public String toString(); 26 | } 27 | -------------------------------------------------------------------------------- /src/core/ModuleCommunicationListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package core; 6 | 7 | /** 8 | * This interface should be implemented by classes that want to be notified 9 | * of variable value changes in ModuleCommunicationBuses. 10 | */ 11 | public interface ModuleCommunicationListener { 12 | 13 | /** 14 | * This method is called whenever a variable, whose changes the module has 15 | * registered to, changes. 16 | * @param key The name of the variable 17 | * @param newValue New value for the variable 18 | */ 19 | public void moduleValueChanged(String key, Object newValue); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/movement/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Contains different movement models and related classes for the simulator. 6 | All movement models have to be in this package and must extend the 7 | {@link movement.MovementModel} class so they can be dynamically 8 | loaded to the simulator. The classes to load can be specified trough 9 | {@link core.Settings} class' settings source. See MovementModel class and 10 | classes extending it for details about the settings. 11 | 12 | 13 | Complex movement models can store their other 14 | classes (the ones that don't extend MovementModel class) to sub packages. 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /data/demo_bus.wkt: -------------------------------------------------------------------------------- 1 | LINESTRING (2550592.003226894 6672735.4731177585, 2551115.9395496203 6672778.863077007, 2551733.574109715 6672719.2894031275, 2552056.98894488 6672339.2921827845, 2552443.66947668 6672192.648523826, 2552707.5061580963 6671918.555611582, 2553198.6258239946 6672295.572147773, 2553076.243947664 6672827.414220898, 2552788.4341127174 6673214.002954185, 2553299.34441706 6673391.583714101, 2 | 2553901.791580166 6673127.503099969, 2553449.865462933 6674015.21685593, 2552643.258766599 6673756.567488425, 2552068.1670670523 6673793.766026565, 2551642.8869532268 6674154.408804504, 2551301.966601272 6673840.286704404, 2551573.186617998 6673194.328438315, 2551303.7237525806 6672909.38303511, 2550592.003226894 6672735.4731177585) 3 | -------------------------------------------------------------------------------- /src/core/UpdateListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package core; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * Interface for classes that want to be informed about every single update 11 | * call to the World object.
12 | * NOTE: if update interval is large (if, e.g., no movement or 13 | * connection simulation is needed), update listeners may not get called at all 14 | * during the simulation. 15 | */ 16 | public interface UpdateListener { 17 | 18 | /** 19 | * Method is called on every update cycle. 20 | * @param hosts A list of all hosts in the world 21 | */ 22 | public void updated(List hosts); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /example_settings/prophet_settings.txt: -------------------------------------------------------------------------------- 1 | ## Test scenario using Prophet router and Points of Interest (POIs) 2 | 3 | Scenario.name = PRoPHET-%%ProphetRouter.secondsInTimeUnit%%siu 4 | Group.router = ProphetRouter 5 | 6 | ProphetRouter.secondsInTimeUnit = 30 7 | 8 | # Define POI data files 9 | PointsOfInterest.poiFile1 = data/ParkPOIs.wkt 10 | PointsOfInterest.poiFile2 = data/CentralPOIs.wkt 11 | PointsOfInterest.poiFile3 = data/WestPOIs.wkt 12 | PointsOfInterest.poiFile4 = data/shops.wkt 13 | 14 | # Define probabilities for different groups selecting POIs from different POI files 15 | Group1.pois = 1,0.3, 2,0.1, 3,0.1, 4, 0.1 16 | Group2.pois = 2,0.3, 3,0.1 17 | Group3.pois = 3,0.3, 2,0.1, 1,0.1, 4, 0.1 18 | Group4.pois = 4,0.3, 2,0.1, 3,0.1, 1, 0.1 19 | -------------------------------------------------------------------------------- /data/HelsinkiMedium/H_bus.wkt: -------------------------------------------------------------------------------- 1 | LINESTRING (2547673.3171570706 6672763.109461098, 2548776.5689421124 6672470.202230424, 2549545.178272597 6672487.866284834, 2550330.047439836 6672702.395525495, 2551005.1565218316 6672769.690971744, 2551733.574109715 6672719.2894031275, 2552249.4588846625 6672531.896391016, 2552747.310172474 6672343.373119477, 2552892.741254229 6673220.99455896, 2553296.217842666 6673446.466311243, 2 | 2552889.0537113426 6673977.008085913, 2552889.218702076 6674644.061193879, 2553352.5456789713 6675010.225239109, 2553526.313919149 6675457.6179286605, 2553675.4737914735 6675736.161862543, 2552982.6364551983 6676025.478269019, 2552089.5251174616 6676457.277379394, 2551257.212864899 6675722.818799925, 2550332.8522822997 6676228.294821279, 2549305.5374822007 6676406.915819961) 3 | -------------------------------------------------------------------------------- /src/report/LocationSnapshotReport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | 6 | package report; 7 | 8 | import core.Coord; 9 | import core.DTNHost; 10 | 11 | /** 12 | * Node location snapshot report. Reports the location of all 13 | * (or only some, see {@link SnapshotReport#REPORTED_NODES}) nodes every 14 | * configurable-amount-of seconds (see {@link SnapshotReport#GRANULARITY}). 15 | * Uses {@link Report#format} for location formatting. 16 | */ 17 | public class LocationSnapshotReport extends SnapshotReport { 18 | 19 | @Override 20 | protected void writeSnapshot(DTNHost h) { 21 | Coord location = h.getLocation(); 22 | write(h.toString() + " " + format(location.getX()) + 23 | " " + format(location.getY())); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/core/ConnectionListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package core; 6 | 7 | /** 8 | * Interface for classes that want to be informed about connections 9 | * between hosts. 10 | */ 11 | public interface ConnectionListener { 12 | 13 | /** 14 | * Method is called when two hosts are connected. 15 | * @param host1 Host that initiated the connection 16 | * @param host2 Host that was connected to 17 | */ 18 | public void hostsConnected(DTNHost host1, DTNHost host2); 19 | 20 | /** 21 | * Method is called when connection between hosts is disconnected. 22 | * @param host1 Host that initiated the disconnection 23 | * @param host2 Host at the other end of the connection 24 | */ 25 | public void hostsDisconnected(DTNHost host1, DTNHost host2); 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/test/CoordTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package test; 6 | 7 | import junit.framework.TestCase; 8 | import core.Coord; 9 | 10 | public class CoordTest extends TestCase { 11 | 12 | public void testHashCode() { 13 | Coord c1 = new Coord(1,1); 14 | Coord c2 = new Coord(1,1); 15 | Coord c3 = new Coord(2,3); 16 | Coord c4 = new Coord(3,2); 17 | Coord c5 = new Coord(-2,-3); 18 | Coord c6 = new Coord(-2,-3); 19 | 20 | assertTrue(c1.hashCode() == c2.hashCode()); 21 | assertTrue(c1.hashCode() != c3.hashCode()); 22 | assertTrue(c3.hashCode() != c4.hashCode()); 23 | assertTrue(c5.hashCode() == c6.hashCode()); 24 | assertTrue(c3.hashCode() != c5.hashCode()); 25 | 26 | c5.translate(1, 1); 27 | assertTrue(c5.hashCode() != c6.hashCode()); 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/gui/nodefilter/NodeMessageFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | 6 | package gui.nodefilter; 7 | 8 | import core.DTNHost; 9 | 10 | /** 11 | * Node filter that filters nodes by the messages they have in their buffer 12 | */ 13 | public class NodeMessageFilter implements NodeFilter { 14 | private String messageId; 15 | 16 | /** 17 | * Creates a new filter with the given message ID 18 | * @param messageId The message ID used for filtering 19 | */ 20 | public NodeMessageFilter(String messageId) { 21 | this.messageId = messageId; 22 | } 23 | 24 | public boolean filterNode(DTNHost node) { 25 | return node.getRouter().hasMessage(messageId); 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | return "Filters nodes with message ID " + messageId; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/report/MovementListenerTestReport.java: -------------------------------------------------------------------------------- 1 | package report; 2 | 3 | import core.Coord; 4 | import core.DTNHost; 5 | import core.MovementListener; 6 | 7 | /** 8 | * Class used by MovementListenerTest. Not for simulation use. 9 | * 10 | * @author teemuk 11 | */ 12 | public final class MovementListenerTestReport 13 | extends Report 14 | implements MovementListener { 15 | private static MovementListener DELEGATE; 16 | 17 | public static void setDelegate(final MovementListener delegate) { 18 | DELEGATE = delegate; 19 | } 20 | 21 | @Override 22 | public void newDestination(DTNHost host, Coord destination, double speed) { 23 | if (DELEGATE != null) { 24 | DELEGATE.newDestination(host, destination, speed); 25 | } 26 | } 27 | 28 | @Override 29 | public void initialLocation(DTNHost host, Coord location) { 30 | if (DELEGATE != null) { 31 | DELEGATE.initialLocation(host, location); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | If you would like to contribute to the development of the ONE simulator, please fork us on GitHub and send your contributions as pull requests. 4 | 5 | If you are not sure where to start, new tests are always very welcome! Bugfixes are also highly appreciated. 6 | 7 | If you want to add new features, there are some things to take into consideration: 8 | 9 | * The preferred way to extend the ONE is by making new movement, routing, network interface, reporting, or application modules. See the existing modules for examples. 10 | * If the new feature requires changes to existing classes, make sure the feature is generic and shared by many use cases. 11 | * In particular one should avoid features that slow down simulation even when the new feature is not in use (e.g., if it requires checks for each simulation round) 12 | 13 | When doing contributions, please try to follow the coding style of the existing code. 14 | -------------------------------------------------------------------------------- /src/core/MovementListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package core; 6 | 7 | /** 8 | * Interface for classes that want to be informed about node movement. 9 | */ 10 | public interface MovementListener { 11 | 12 | /** 13 | * Method is called every time a host receives a new destination from its 14 | * movement model. 15 | * @param host The host that got a new destination 16 | * @param destination Coordinates of the destination 17 | * @param speed Speed towards that destination 18 | */ 19 | public void newDestination(DTNHost host, Coord destination, double speed); 20 | 21 | /** 22 | * Method is called when a host receives its initial location from 23 | * movement model. 24 | * @param host The host that got the location 25 | * @param location Coordinates of the location 26 | */ 27 | public void initialLocation(DTNHost host, Coord location); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/input/EventQueue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package input; 6 | 7 | /** 8 | * Interface for event queues. Any class that is not a movement model or a 9 | * routing module but wishes to provide events for the simulation (like creating 10 | * messages) must implement this interface and register itself to the 11 | * simulator. See the {@link EventQueueHandler} class for configuration 12 | * instructions. 13 | */ 14 | public interface EventQueue { 15 | 16 | /** 17 | * Returns the next event in the queue or ExternalEvent with time of 18 | * double.MAX_VALUE if there are no events left. 19 | * @return The next event 20 | */ 21 | public ExternalEvent nextEvent(); 22 | 23 | /** 24 | * Returns next event's time or Double.MAX_VALUE if there are no 25 | * events left in the queue. 26 | * @return Next event's time 27 | */ 28 | public double nextEventsTime(); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/util/Tuple.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package util; 6 | 7 | /** 8 | * A generic key-value tuple. 9 | */ 10 | public class Tuple { 11 | private K key; 12 | private V value; 13 | 14 | /** 15 | * Creates a new tuple. 16 | * @param key The key of the tuple 17 | * @param value The value of the tuple 18 | */ 19 | public Tuple(K key, V value) { 20 | this.key = key; 21 | this.value = value; 22 | } 23 | 24 | /** 25 | * Returns the key 26 | * @return the key 27 | */ 28 | public K getKey() { 29 | return key; 30 | } 31 | 32 | /** 33 | * Returns the value 34 | * @return the value 35 | */ 36 | public V getValue() { 37 | return value; 38 | } 39 | 40 | /** 41 | * Returns a string representation of the tuple 42 | * @return a string representation of the tuple 43 | */ 44 | public String toString() { 45 | return key.toString() + ":" + value.toString(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/routing/DirectDeliveryRouter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package routing; 6 | 7 | import core.Settings; 8 | 9 | /** 10 | * Router that will deliver messages only to the final recipient. 11 | */ 12 | public class DirectDeliveryRouter extends ActiveRouter { 13 | 14 | public DirectDeliveryRouter(Settings s) { 15 | super(s); 16 | } 17 | 18 | protected DirectDeliveryRouter(DirectDeliveryRouter r) { 19 | super(r); 20 | } 21 | 22 | @Override 23 | public void update() { 24 | super.update(); 25 | if (isTransferring() || !canStartTransfer()) { 26 | return; // can't start a new transfer 27 | } 28 | 29 | // Try only the messages that can be delivered to final recipient 30 | if (exchangeDeliverableMessages() != null) { 31 | return; // started a transfer 32 | } 33 | } 34 | 35 | @Override 36 | public DirectDeliveryRouter replicate() { 37 | return new DirectDeliveryRouter(this); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/movement/SwitchableMovement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package movement; 6 | 7 | import core.Coord; 8 | 9 | /** 10 | 11 | * Movement models to be used by ExtendedMovementModels should implement this 12 | * interface 13 | * 14 | * @author Frans Ekman 15 | */ 16 | public interface SwitchableMovement { 17 | 18 | /** 19 | * Tell the movement model what its current location is 20 | * @param lastWaypoint 21 | */ 22 | public void setLocation(Coord lastWaypoint); 23 | 24 | /** 25 | * Get the last location the getPath() of this movement model has returned 26 | * @return the last location 27 | */ 28 | public Coord getLastLocation(); 29 | 30 | /** 31 | * Checks if the movement model is finished doing its task and it's time to 32 | * switch to the next movement model. The method should be called between 33 | * getPath() calls. 34 | * @return true if ready 35 | */ 36 | public boolean isReady(); 37 | } 38 | -------------------------------------------------------------------------------- /src/input/MessageEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package input; 6 | 7 | /** 8 | * A message related external event 9 | */ 10 | public abstract class MessageEvent extends ExternalEvent { 11 | /** address of the node the message is from */ 12 | protected int fromAddr; 13 | /** address of the node the message is to */ 14 | protected int toAddr; 15 | /** identifier of the message */ 16 | protected String id; 17 | 18 | /** 19 | * Creates a message event 20 | * @param from Where the message comes from 21 | * @param to Who the message goes to 22 | * @param id ID of the message 23 | * @param time Time when the message event occurs 24 | */ 25 | public MessageEvent(int from, int to, String id, double time) { 26 | super(time); 27 | this.fromAddr = from; 28 | this.toAddr= to; 29 | this.id = id; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return "MSG @" + this.time + " " + id; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/report/EnergyLevelReport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package report; 6 | 7 | 8 | import core.DTNHost; 9 | import core.SimError; 10 | import core.UpdateListener; 11 | 12 | /** 13 | * Node energy level report. Reports the energy level of all 14 | * (or only some, see {@link #REPORTED_NODES}) nodes every 15 | * configurable-amount-of seconds (see {@link #GRANULARITY}). 16 | * Works only if all nodes use energy model; see 17 | * {@link routing.util.EnergyModel}. 18 | */ 19 | public class EnergyLevelReport extends SnapshotReport 20 | implements UpdateListener { 21 | 22 | @Override 23 | protected void writeSnapshot(DTNHost h) { 24 | Double value = (Double)h.getComBus(). 25 | getProperty(routing.util.EnergyModel.ENERGY_VALUE_ID); 26 | if (value == null) { 27 | throw new SimError("Host " + h + 28 | " is not using energy model"); 29 | } 30 | write(h.toString() + " " + format(value)); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/routing/PassiveRouter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package routing; 6 | 7 | import core.Connection; 8 | import core.Settings; 9 | 10 | /** 11 | * Passive router that doesn't send anything unless commanded. This is useful 12 | * for external event -controlled routing or dummy nodes. 13 | * For implementation specifics, see MessageRouter class. 14 | */ 15 | public class PassiveRouter extends MessageRouter { 16 | 17 | public PassiveRouter(Settings s) { 18 | super(s); 19 | } 20 | 21 | /** 22 | * Copy-constructor. 23 | * @param r Router to copy the settings from. 24 | */ 25 | protected PassiveRouter(PassiveRouter r) { 26 | super(r); 27 | } 28 | 29 | @Override 30 | public void update() { 31 | super.update(); 32 | } 33 | 34 | @Override 35 | public void changedConnection(Connection con) { 36 | // -"- 37 | } 38 | 39 | @Override 40 | public MessageRouter replicate() { 41 | return new PassiveRouter(this); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/core/ApplicationListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package core; 6 | 7 | /** 8 | *

9 | * Interface for classes that want to be informed about messages 10 | * between hosts. 11 | *

12 | * 13 | *

14 | * Report classes wishing to receive application events should implement this 15 | * interface. Note that the application event names are defined by the 16 | * applications so any class wishing to interpret them must know the 17 | * application. 18 | *

19 | * 20 | * @author teemuk 21 | * @author mjpitka 22 | */ 23 | public interface ApplicationListener { 24 | 25 | /** 26 | * Application has generated an event. 27 | * 28 | * @param event Event name. 29 | * @param params Additional parameters for the event 30 | * @param app Application instance that generated the event. 31 | * @param host The host this application instance is running on. 32 | */ 33 | public void gotEvent(String event, Object params, Application app, 34 | DTNHost host); 35 | } 36 | -------------------------------------------------------------------------------- /src/report/InterContactTimesReport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package report; 6 | 7 | import core.DTNHost; 8 | 9 | /** 10 | * Reports the inter-contact time (i.e., the time between the end of previous 11 | * contact and the beginning of a new contact between two hosts) distribution. 12 | * The syntax of the report file is the same as in {@link ContactTimesReport}. 13 | */ 14 | public class InterContactTimesReport extends ContactTimesReport { 15 | 16 | @Override 17 | public void hostsConnected(DTNHost host1, DTNHost host2) { 18 | ConnectionInfo ci = this.removeConnection(host1, host2); 19 | 20 | if (ci != null) { // connected again 21 | newEvent(); 22 | ci.connectionEnd(); 23 | increaseTimeCount(ci.getConnectionTime()); 24 | } 25 | } 26 | 27 | @Override 28 | public void hostsDisconnected(DTNHost host1, DTNHost host2) { 29 | if (isWarmup()) { 30 | return; 31 | } 32 | // start counting time to next connection 33 | this.addConnection(host1, host2); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /data/HelsinkiMedium/D_offices.wkt: -------------------------------------------------------------------------------- 1 | POINT (2553394.2553363172 6675336.7501860205) 2 | 3 | POINT (2553062.029996001 6675431.351899847) 4 | 5 | POINT (2553052.246045524 6675578.855756246) 6 | 7 | POINT (2553218.944432785 6676004.253397298) 8 | 9 | POINT (2553362.2306350083 6676160.339223506) 10 | 11 | POINT (2553258.8721902124 6676270.974617526) 12 | 13 | POINT (2553108.3923920225 6676400.944449359) 14 | 15 | POINT (2553363.6083076303 6676465.00915406) 16 | 17 | POINT (2553496.8795723505 6676603.560955702) 18 | 19 | POINT (2553370.8101531332 6676594.448864214) 20 | 21 | POINT (2553458.708966231 6676375.618636353) 22 | 23 | POINT (2553520.0360217514 6676177.143080477) 24 | 25 | POINT (2553447.770080622 6676247.48922695) 26 | 27 | POINT (2553113.0533802346 6676122.790605012) 28 | 29 | POINT (2553020.4605807783 6676178.553404187) 30 | 31 | POINT (2552477.071850611 6676504.3081743205) 32 | 33 | POINT (2552841.833363509 6675831.963851868) 34 | 35 | POINT (2553890.89394224 6675364.116467373) 36 | 37 | POINT (2554326.5684722555 6675869.682509391) 38 | 39 | POINT (2553932.7438417096 6677359.32442526) 40 | -------------------------------------------------------------------------------- /data/HelsinkiMedium/C_offices.wkt: -------------------------------------------------------------------------------- 1 | POINT (2551376.426919153 6674304.123168278) 2 | 3 | POINT (2550967.0766606154 6675000.773069562) 4 | 5 | POINT (2550697.3498100247 6675261.432898526) 6 | 7 | POINT (2550544.1476647374 6675483.043764625) 8 | 9 | POINT (2551431.6740661557 6675050.304438443) 10 | 11 | POINT (2551206.618456572 6675407.336387593) 12 | 13 | POINT (2551000.2975447397 6675718.547819612) 14 | 15 | POINT (2550689.6034951024 6675859.940273265) 16 | 17 | POINT (2550394.3855762365 6676057.865702871) 18 | 19 | POINT (2550193.3443678655 6676346.541962416) 20 | 21 | POINT (2550170.1466707815 6676695.852139196) 22 | 23 | POINT (2549568.351221071 6676074.7895873925) 24 | 25 | POINT (2548866.5796365947 6676319.20568795) 26 | 27 | POINT (2548591.7710714224 6676574.744341456) 28 | 29 | POINT (2548387.5455419016 6677245.3982759155) 30 | 31 | POINT (2549190.6544346926 6676779.691382726) 32 | 33 | POINT (2550699.494689556 6674935.358054927) 34 | 35 | POINT (2550826.0508314357 6675180.984433278) 36 | 37 | POINT (2550853.835270902 6674980.93851696) 38 | 39 | POINT (2550585.040617954 6675171.722307353) 40 | -------------------------------------------------------------------------------- /src/gui/playfield/MessageGraphic.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package gui.playfield; 6 | 7 | import java.awt.Color; 8 | import java.awt.Graphics2D; 9 | import java.awt.Polygon; 10 | 11 | import core.DTNHost; 12 | 13 | /** 14 | * Visualization of a message 15 | * 16 | */ 17 | public class MessageGraphic extends PlayFieldGraphic { 18 | private Color msgColor = Color.RED; 19 | 20 | private DTNHost from; 21 | private DTNHost to; 22 | 23 | public MessageGraphic(DTNHost from, DTNHost to) { 24 | this.to = to; 25 | this.from = from; 26 | } 27 | 28 | @Override 29 | public void draw(Graphics2D g2) { 30 | g2.setColor(msgColor); 31 | 32 | int fromX = scale(from.getLocation().getX()); 33 | int fromY = scale(from.getLocation().getY()); 34 | int toX = scale(to.getLocation().getX()); 35 | int toY = scale(to.getLocation().getY()); 36 | 37 | // line from "from host" to "to host" 38 | Polygon p = new Polygon(new int[] {fromX, toX}, 39 | new int[] {fromY,toY}, 2); 40 | 41 | g2.draw(p); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /data/HelsinkiMedium/E_offices.wkt: -------------------------------------------------------------------------------- 1 | POINT (2553785.2338767163 6673218.283936794) 2 | 3 | POINT (2552971.7305677356 6673425.081402789) 4 | 5 | POINT (2552065.320976905 6672790.54575852) 6 | 7 | POINT (2551613.0318800593 6673913.813580948) 8 | 9 | POINT (2551164.661313126 6671899.611263307) 10 | 11 | POINT (2551217.6480870843 6672787.2850100845) 12 | 13 | POINT (2553277.4088990847 6674161.500432238) 14 | 15 | POINT (2552270.379709629 6672251.59205307) 16 | 17 | POINT (2550839.241840553 6672755.957819589) 18 | 19 | POINT (2552844.266976823 6672450.797776541) 20 | 21 | POINT (2548291.694175465 6671876.545969155) 22 | 23 | POINT (2548973.5431289105 6672751.016685456) 24 | 25 | POINT (2548291.694175465 6671876.545969155) 26 | 27 | POINT (2548973.5431289105 6672751.016685456) 28 | 29 | POINT (2547971.0181864705 6672303.113878818) 30 | 31 | POINT (2552924.1307412153 6672763.979660833) 32 | 33 | POINT (2552892.741254229 6673220.99455896) 34 | 35 | POINT (2552952.212164001 6673697.553943111) 36 | 37 | POINT (2553376.452836208 6673806.188877968) 38 | 39 | POINT (2551923.44544545 6672987.520970024) 40 | 41 | POINT (2551768.7088863445 6672875.395233927) 42 | 43 | POINT (2552330.7745675067 6672982.3197762) 44 | -------------------------------------------------------------------------------- /src/movement/ModifiedRandomDirection.java: -------------------------------------------------------------------------------- 1 | package movement; 2 | 3 | import core.Settings; 4 | 5 | /** 6 | *

7 | * Modified Random Direction movement model as described in: 8 | * Elizabeth M. Royer, P. Michael Melliar-Smith, and Louise E. Moser, 9 | * "An Analysis of the Optimum Node Density for Ad hoc Mobile Networks" 10 | *

11 | * 12 | *

13 | * Similar to {@link RandomDirection}, except nodes will not move all the way 14 | * to the edge. Instead they will pick a random direction and move in that 15 | * direction for a random distance before pausing and picking another 16 | * direction. 17 | *

18 | * 19 | * @author teemuk 20 | */ 21 | public class ModifiedRandomDirection 22 | extends RandomDirection { 23 | 24 | public ModifiedRandomDirection( Settings settings ) { 25 | super( settings ); 26 | } 27 | 28 | public ModifiedRandomDirection( ModifiedRandomDirection other ) { 29 | super( other ); 30 | } 31 | 32 | @Override 33 | protected double getTravelFraction() { 34 | // Move a random fraction in the picked direction instead of all the 35 | // way to the edge. 36 | return MovementModel.rng.nextDouble(); 37 | } 38 | 39 | @Override 40 | public MovementModel replicate() { 41 | return new ModifiedRandomDirection( this ); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/gui/playfield/MapGraphic.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package gui.playfield; 6 | 7 | import java.awt.Color; 8 | import java.awt.Graphics2D; 9 | 10 | import movement.map.MapNode; 11 | import movement.map.SimMap; 12 | import core.Coord; 13 | 14 | /** 15 | * PlayfieldGraphic for SimMap visualization 16 | * 17 | */ 18 | public class MapGraphic extends PlayFieldGraphic { 19 | private SimMap simMap; 20 | private final Color PATH_COLOR = Color.LIGHT_GRAY; 21 | private final Color BG_COLOR = Color.WHITE; 22 | 23 | public MapGraphic(SimMap simMap) { 24 | this.simMap = simMap; 25 | 26 | } 27 | 28 | // TODO: draw only once and store to buffer 29 | @Override 30 | public void draw(Graphics2D g2) { 31 | Coord c,c2; 32 | 33 | if (simMap == null) { 34 | return; 35 | } 36 | 37 | g2.setColor(PATH_COLOR); 38 | g2.setBackground(BG_COLOR); 39 | 40 | // draws all edges between map nodes (bidirectional edges twice) 41 | for (MapNode n : simMap.getNodes()) { 42 | c = n.getLocation(); 43 | 44 | // draw a line to adjacent nodes 45 | for (MapNode n2 : n.getNeighbors()) { 46 | c2 = n2.getLocation(); 47 | g2.drawLine(scale(c2.getX()), scale(c2.getY()), 48 | scale(c.getX()), scale(c.getY())); 49 | } 50 | } 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/util/ParetoRNG.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package util; 6 | 7 | import java.util.Random; 8 | 9 | /** 10 | * A random number generator for a Pareto distribution 11 | * @author Frans Ekman 12 | */ 13 | public class ParetoRNG { 14 | private Random rng; 15 | private double xm; // min value (Xm) 16 | private double k; // coefficient 17 | private double maxValue; 18 | 19 | /** 20 | * Creates a new Pareto random number generator that makes use of a normal 21 | * random number generator 22 | * @param rng 23 | * @param k 24 | * @param minValue 25 | * @param maxValue 26 | */ 27 | public ParetoRNG(Random rng, double k, double minValue, double maxValue) { 28 | this.rng = rng; 29 | this.xm = minValue; 30 | this.k = k; 31 | if (maxValue == -1) { 32 | this.maxValue = Double.POSITIVE_INFINITY; 33 | } else { 34 | this.maxValue = maxValue; 35 | } 36 | } 37 | 38 | /** 39 | * Returns a Pareto distributed double value 40 | * @return a Pareto distributed double value 41 | */ 42 | public double getDouble() { 43 | if (xm == -1) { 44 | return Double.POSITIVE_INFINITY; 45 | } 46 | double x; 47 | do { 48 | x = xm * Math.pow((1 - rng.nextDouble()), (-1/k)); 49 | } while (x > maxValue); 50 | return x; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/gui/playfield/PathGraphic.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package gui.playfield; 6 | 7 | import java.awt.Color; 8 | import java.awt.Graphics2D; 9 | import java.util.List; 10 | 11 | import movement.Path; 12 | import core.Coord; 13 | 14 | /** 15 | * Visualization of a Path 16 | * 17 | */ 18 | public class PathGraphic extends PlayFieldGraphic { 19 | private final static Color PATH_COLOR = Color.RED; 20 | private List coords; 21 | 22 | public PathGraphic(Path path) { 23 | if (path == null) { 24 | this.coords = null; 25 | } 26 | else { 27 | this.coords = path.getCoords(); 28 | assert this.coords != null && this.coords.size() > 0 : 29 | "No coordinates in the path (" + path + ")"; 30 | } 31 | } 32 | 33 | /** 34 | * Draws a line trough all path's coordinates. 35 | * @param g2 The graphics context to draw to 36 | */ 37 | @Override 38 | public void draw(Graphics2D g2) { 39 | if (coords == null) { 40 | return; 41 | } 42 | 43 | g2.setColor(PATH_COLOR); 44 | Coord prev = coords.get(0); 45 | 46 | for (int i=1, n=coords.size(); i < n; i++) { 47 | Coord next = coords.get(i); 48 | g2.drawLine(scale(prev.getX()), scale(prev.getY()), 49 | scale(next.getX()), scale(next.getY())); 50 | prev = next; 51 | } 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/test/MessageTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package test; 6 | 7 | import junit.framework.TestCase; 8 | 9 | import org.junit.Before; 10 | import org.junit.Test; 11 | 12 | import core.DTNHost; 13 | import core.Message; 14 | import core.SimClock; 15 | 16 | public class MessageTest extends TestCase { 17 | 18 | private Message msg; 19 | private DTNHost from; 20 | private DTNHost to; 21 | private SimClock sc; 22 | 23 | @Before 24 | public void setUp() throws Exception { 25 | sc = SimClock.getInstance(); 26 | sc.setTime(10); 27 | 28 | msg = new Message(from, to, "M", 100); 29 | msg.setTtl(10); 30 | 31 | } 32 | 33 | @Test 34 | public void testGetTtl() { 35 | assertEquals(10, msg.getTtl()); 36 | 37 | sc.advance(50); 38 | assertEquals(9, msg.getTtl()); 39 | 40 | sc.advance(120); 41 | assertEquals(7, msg.getTtl()); 42 | 43 | sc.advance(180); 44 | assertEquals(4, msg.getTtl()); 45 | 46 | sc.advance(240); 47 | assertEquals(0, msg.getTtl()); 48 | 49 | 50 | } 51 | 52 | @Test 53 | public void testAddProperty() { 54 | String value1 = "value1"; 55 | String value2 = "value2"; 56 | msg.addProperty("foo", value1); 57 | msg.addProperty("bar", value2); 58 | 59 | assertEquals(value1, msg.getProperty("foo")); 60 | assertEquals(value2, msg.getProperty("bar")); 61 | } 62 | 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/test/StationaryMovement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package test; 6 | 7 | import movement.MovementModel; 8 | import movement.Path; 9 | import core.Coord; 10 | 11 | /** 12 | * A dummy stationary "movement" model where nodes do not move for testing 13 | * purposes 14 | */ 15 | public class StationaryMovement extends MovementModel { 16 | private Coord loc; 17 | 18 | public StationaryMovement(Coord location) { 19 | if (location == null) { 20 | this.loc = new Coord(0,0); 21 | } 22 | else { 23 | this.loc = location; 24 | } 25 | } 26 | 27 | /** 28 | * Returns the only location of this movement model 29 | * @return the only location of this movement model 30 | */ 31 | @Override 32 | public Coord getInitialLocation() { 33 | return loc; 34 | } 35 | 36 | @Override 37 | public boolean isActive() { 38 | return true; 39 | } 40 | 41 | /** 42 | * Returns a single coordinate path (using the only possible coordinate) 43 | * @return a single coordinate path 44 | */ 45 | @Override 46 | public Path getPath() { 47 | Path p = new Path(0); 48 | p.addWaypoint(loc); 49 | return p; 50 | } 51 | 52 | @Override 53 | public double nextPathAvailable() { 54 | return Double.MAX_VALUE; // no new paths available 55 | } 56 | 57 | @Override 58 | public StationaryMovement replicate() { 59 | return new StationaryMovement(loc); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/test/WKTPointReaderTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package test; 6 | 7 | import input.WKTReader; 8 | 9 | import java.io.StringReader; 10 | import java.util.List; 11 | 12 | import junit.framework.TestCase; 13 | import core.Coord; 14 | 15 | public class WKTPointReaderTest extends TestCase { 16 | 17 | private WKTReader r; 18 | 19 | private final String POINT_DATA = 20 | "POINT (2552448.388211649 6673384.4020657055) \n"+ 21 | "POINT (2552275.9398973365 6673509.820852942)\n"+ 22 | "POINT (2552361.289603607 6673630.088457832)\n"+ 23 | "LINESTRING (1.0 2.0, 2.0 3.0)\n"+ // should skip this line 24 | "POINT (2552782.3212060533 6673285.5993876355)\n"; 25 | 26 | private final Coord[] POINTS = { 27 | new Coord(2552448.388211649, 6673384.4020657055), 28 | new Coord(2552275.9398973365, 6673509.820852942), 29 | new Coord(2552361.289603607, 6673630.088457832), 30 | new Coord(2552782.3212060533, 6673285.5993876355) 31 | }; 32 | 33 | protected void setUp() throws Exception { 34 | super.setUp(); 35 | r = new WKTReader(); 36 | } 37 | 38 | public void testReader() throws Exception { 39 | StringReader input = new StringReader(POINT_DATA); 40 | List coords = r.readPoints(input); 41 | 42 | assertEquals(POINTS.length, coords.size()); 43 | 44 | for (int i=0; i hosts) { 28 | Map counts = new HashMap(); 29 | write("[" + (int) getSimTime() + "]"); /* write sim time stamp */ 30 | ArrayList keys; 31 | 32 | for (DTNHost host : hosts) { 33 | for (Message m : host.getMessageCollection()) { 34 | Integer oldCount; 35 | if (!isTracked(m)) { 36 | continue; 37 | } 38 | oldCount = counts.get(m.getId()); 39 | counts.put(m.getId(), (oldCount == null ? 1 : oldCount + 1)); 40 | } 41 | } 42 | 43 | keys = new ArrayList(counts.keySet()); 44 | Collections.sort(keys); 45 | 46 | for (String key : keys) { 47 | write(key + " " + counts.get(key)); 48 | } 49 | 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/interfaces/ConnectivityOptimizer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package interfaces; 6 | 7 | import java.util.Collection; 8 | 9 | import core.NetworkInterface; 10 | 11 | /** 12 | * A superclass for schemes for optimizing the location of possible contacts 13 | * with network interfaces of a specific range 14 | */ 15 | abstract public class ConnectivityOptimizer { 16 | 17 | /** 18 | * Adds a network interface to the optimizer (unless it is already present) 19 | */ 20 | abstract public void addInterface(NetworkInterface ni); 21 | 22 | /** 23 | * Adds a collection of network interfaces to the optimizer (except of those 24 | * already added 25 | */ 26 | abstract public void addInterfaces(Collection interfaces); 27 | 28 | /** 29 | * Updates a network interface's location 30 | */ 31 | abstract public void updateLocation(NetworkInterface ni); 32 | 33 | /** 34 | * Finds all network interfaces that might be located so that they can be 35 | * connected with the network interface 36 | * 37 | * @param ni network interface that needs to be connected 38 | * @return A collection of network interfaces within proximity 39 | */ 40 | abstract public Collection getNearInterfaces( 41 | NetworkInterface ni); 42 | 43 | /** 44 | * Finds all other interfaces that are registered to the 45 | * ConnectivityOptimizer 46 | */ 47 | abstract public Collection getAllInterfaces(); 48 | } 49 | -------------------------------------------------------------------------------- /src/report/ContactsPerHourReport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package report; 6 | 7 | import java.util.Iterator; 8 | import java.util.LinkedList; 9 | 10 | import core.ConnectionListener; 11 | import core.DTNHost; 12 | import core.SimClock; 13 | 14 | /** 15 | * This report counts the number of contacts each hour 16 | * 17 | * @author Frans Ekman 18 | */ 19 | public class ContactsPerHourReport extends Report implements ConnectionListener { 20 | 21 | private LinkedList contactCounts; 22 | private int currentHourCount; 23 | private int currentHour; 24 | 25 | public ContactsPerHourReport() { 26 | init(); 27 | } 28 | 29 | @Override 30 | public void init() { 31 | super.init(); 32 | contactCounts = new LinkedList(); 33 | } 34 | 35 | public void hostsConnected(DTNHost host1, DTNHost host2) { 36 | int time = SimClock.getIntTime() / 3600; 37 | while (Math.floor(time) > currentHour) { 38 | contactCounts.add(new Integer(currentHourCount)); 39 | currentHourCount = 0; 40 | currentHour++; 41 | } 42 | 43 | currentHourCount++; 44 | } 45 | 46 | public void hostsDisconnected(DTNHost host1, DTNHost host2) { 47 | // Do nothing 48 | } 49 | 50 | public void done() { 51 | Iterator iterator = contactCounts.iterator(); 52 | int hour = 0; 53 | while (iterator.hasNext()) { 54 | Integer count = (Integer)iterator.next(); 55 | write(hour + "\t" + count); 56 | hour++; 57 | } 58 | super.done(); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/input/MessageDeleteEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package input; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | import core.DTNHost; 11 | import core.Message; 12 | import core.World; 13 | 14 | /** 15 | * External event for deleting a message. 16 | */ 17 | 18 | public class MessageDeleteEvent extends MessageEvent { 19 | /** is the delete caused by a drop (not "normal" removing) */ 20 | private boolean drop; 21 | 22 | /** 23 | * Creates a message delete event 24 | * @param host Where to delete the message 25 | * @param id ID of the message 26 | * @param time Time when the message is deleted 27 | */ 28 | public MessageDeleteEvent(int host, String id, double time, 29 | boolean drop) { 30 | super(host, host, id, time); 31 | this.drop = drop; 32 | } 33 | 34 | /** 35 | * Deletes the message 36 | */ 37 | @Override 38 | public void processEvent(World world) { 39 | DTNHost host = world.getNodeByAddress(this.fromAddr); 40 | 41 | if (id.equals(StandardEventsReader.ALL_MESSAGES_ID)) { 42 | List ids = new ArrayList(); 43 | for (Message m : host.getMessageCollection()) { 44 | ids.add(m.getId()); 45 | } 46 | for (String nextId : ids) { 47 | host.deleteMessage(nextId, drop); 48 | } 49 | } else { 50 | host.deleteMessage(id, drop); 51 | } 52 | } 53 | 54 | @Override 55 | public String toString() { 56 | return super.toString() + " [" + fromAddr + "] DELETE"; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /toolkit/messageAvailabilityAnalyzer.pl: -------------------------------------------------------------------------------- 1 | #! /usr/bin/perl 2 | 3 | # Extracts statistics from MessageAvailabilityReport output 4 | 5 | package Toolkit; 6 | use strict; 7 | use warnings; 8 | use Getopt::Long; 9 | use FileHandle; 10 | 11 | my $help; 12 | 13 | my $usage = ' 14 | usage: [-help] 15 | '; 16 | 17 | GetOptions("help|?!" => \$help); 18 | 19 | if (not $help and not @ARGV) { 20 | print "Missing required parameter(s)\n"; 21 | print $usage; 22 | exit(); 23 | } 24 | 25 | if ($help) { 26 | print 'MessageAvailabilityReport analyzer. Counts how many instances of each message ID are found in the given report file(s). 27 | '; 28 | print "\n$usage"; 29 | print ' 30 | options: 31 | TBD 32 | '; 33 | exit(); 34 | } 35 | 36 | my %mCounts; 37 | 38 | my $fileCount = @ARGV; 39 | 40 | while (my $inFile = shift(@ARGV)) { 41 | open (INFILE, $inFile) or die "Can't open $inFile: $!"; 42 | 43 | while() { 44 | my ($idsStr) = m/\w+\d+ (.*)/; 45 | next unless $idsStr; 46 | 47 | foreach my $id (split(' ', $idsStr)) { 48 | $id = substr($id, 1); # remove message prefix 49 | if (not defined $mCounts{$id}) { 50 | $mCounts{$id} = 0; 51 | } 52 | $mCounts{$id}++; 53 | } 54 | } 55 | } 56 | 57 | my $sum = 0; 58 | my $idCount = 0; 59 | foreach my $key (sort {$a<=>$b} keys %mCounts) { 60 | print $key . ": " . $mCounts{$key} . "\n"; 61 | $sum += $mCounts{$key}; 62 | $idCount++; 63 | } 64 | 65 | print "Message ID count: $idCount\n"; 66 | print "Average count per ID: " . $sum / int(keys %mCounts) . "\n"; 67 | 68 | -------------------------------------------------------------------------------- /src/routing/EpidemicRouter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package routing; 6 | 7 | import core.Settings; 8 | 9 | /** 10 | * Epidemic message router with drop-oldest buffer and only single transferring 11 | * connections at a time. 12 | */ 13 | public class EpidemicRouter extends ActiveRouter { 14 | 15 | /** 16 | * Constructor. Creates a new message router based on the settings in 17 | * the given Settings object. 18 | * @param s The settings object 19 | */ 20 | public EpidemicRouter(Settings s) { 21 | super(s); 22 | //TODO: read&use epidemic router specific settings (if any) 23 | } 24 | 25 | /** 26 | * Copy constructor. 27 | * @param r The router prototype where setting values are copied from 28 | */ 29 | protected EpidemicRouter(EpidemicRouter r) { 30 | super(r); 31 | //TODO: copy epidemic settings here (if any) 32 | } 33 | 34 | @Override 35 | public void update() { 36 | super.update(); 37 | if (isTransferring() || !canStartTransfer()) { 38 | return; // transferring, don't try other connections yet 39 | } 40 | 41 | // Try first the messages that can be delivered to final recipient 42 | if (exchangeDeliverableMessages() != null) { 43 | return; // started a transfer, don't try others (yet) 44 | } 45 | 46 | // then try any/all message to any/all connection 47 | this.tryAllMessagesToAllConnections(); 48 | } 49 | 50 | 51 | @Override 52 | public EpidemicRouter replicate() { 53 | return new EpidemicRouter(this); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /toolkit/Common.pm: -------------------------------------------------------------------------------- 1 | package Toolkit; 2 | 3 | # Common methods (parseArgs & debug) for toolkit programs 4 | 5 | use strict; 6 | use warnings; 7 | 8 | our @EXPORT = qw(parseArgs debug); 9 | 10 | my $quietMode = 0; 11 | 12 | # Parses INFILE and OUTFILE from command line arguments 13 | # and shows help or toggles quiet mode if requested. 14 | sub parseArgs { 15 | my $progName = shift; 16 | my $infile; 17 | my $outfile; 18 | 19 | # show help with -h, -?, /h, /? or -help (etc.) 20 | if (defined $ARGV[0] and $ARGV[0] =~ m/^[-\/][h\?]/) { 21 | print "$progName\n"; 22 | print 'Usage: [-h] [-q] 23 | -h : show this help 24 | -q : quiet mode (nothing is printed to stderr) 25 | Default infile and outfile are stdin and stdout. 26 | Discarded lines and "errors" are printed to stderr. 27 | '; 28 | exit(); 29 | } 30 | 31 | if (defined $ARGV[0] and $ARGV[0] =~ m/^-q/) { 32 | $quietMode = 1; 33 | shift @ARGV; 34 | } 35 | 36 | $infile = shift @ARGV;; 37 | $outfile = shift @ARGV; 38 | 39 | if ($infile) { 40 | open(INFILE, $infile) or die "Can't open $infile : $!"; 41 | } 42 | else { 43 | open(INFILE, "<-") or die "Can't read from stdin"; 44 | } 45 | 46 | if ($outfile) { 47 | open OUTFILE, ">$outfile" or die "Can't open $outfile : $!"; 48 | } 49 | else { 50 | open(OUTFILE, ">-") or die "Can't open stdout"; 51 | } 52 | } 53 | 54 | # Prints errors and debug information to stderr (unless $quietMode is set) 55 | sub debug { 56 | my $txt = shift; 57 | print STDERR "$txt\n" unless $quietMode; 58 | } 59 | 60 | 1; 61 | -------------------------------------------------------------------------------- /toolkit/createCircles.pl: -------------------------------------------------------------------------------- 1 | #! /usr/bin/perl 2 | package Toolkit; 3 | 4 | use strict; 5 | use warnings; 6 | use Getopt::Long; 7 | use Math::Trig; 8 | 9 | # Creates node settings for a circular network with given number of rings 10 | 11 | # prefix of hosts 12 | my $hostPrefix = "g"; 13 | # number of rings 14 | 15 | my ($rings, $radius, $help); 16 | 17 | GetOptions("rings=n" => \$rings, 18 | "radius=n" => \$radius, 19 | "help|?!" => \$help); 20 | 21 | unless (defined($help)) { 22 | unless (defined($rings) and defined($radius)) { 23 | print "Missing required parameters\n"; 24 | $help = 1; 25 | } 26 | } 27 | 28 | if ($help) { 29 | print "Usage: 30 | -rings -radius \n"; 31 | exit(); 32 | } 33 | 34 | my $orig = $rings * $radius + 2*$radius; 35 | my $hostID = 1; 36 | for (my $ring = 0; $ring <= $rings; $ring++) { 37 | 38 | if ($ring==0) { 39 | my $nrOfHosts = 1; 40 | for (my $tmp = 1; $tmp <= $rings; $tmp++) { 41 | $nrOfHosts+= $tmp*6; 42 | } 43 | print "Scenario.nrofHostGroups = $nrOfHosts\n"; 44 | print "Group.movementModel = StationaryMovement\n"; 45 | print "Group.nrofHosts = 1\n"; 46 | print "Group.groupID = $hostPrefix\n"; 47 | print "Group$hostID.nodeLocation = $orig, $orig\n"; 48 | $hostID++; 49 | } else { 50 | my $nodes = $ring*6; 51 | my $angle = 2*pi/$nodes; 52 | for (my $node = 0; $node < $nodes; $node++) { 53 | my $x = int($orig + $ring*$radius*cos($node*$angle)); 54 | my $y = int($orig + $ring*$radius*sin($node*$angle)); 55 | print "Group$hostID.nodeLocation = $x , $y\n"; 56 | $hostID++; 57 | } 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/movement/RandomWaypoint.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package movement; 6 | 7 | import core.Coord; 8 | import core.Settings; 9 | 10 | /** 11 | * Random waypoint movement model. Creates zig-zag paths within the 12 | * simulation area. 13 | */ 14 | public class RandomWaypoint extends MovementModel { 15 | /** how many waypoints should there be per path */ 16 | private static final int PATH_LENGTH = 1; 17 | private Coord lastWaypoint; 18 | 19 | public RandomWaypoint(Settings settings) { 20 | super(settings); 21 | } 22 | 23 | protected RandomWaypoint(RandomWaypoint rwp) { 24 | super(rwp); 25 | } 26 | 27 | /** 28 | * Returns a possible (random) placement for a host 29 | * @return Random position on the map 30 | */ 31 | @Override 32 | public Coord getInitialLocation() { 33 | assert rng != null : "MovementModel not initialized!"; 34 | Coord c = randomCoord(); 35 | 36 | this.lastWaypoint = c; 37 | return c; 38 | } 39 | 40 | @Override 41 | public Path getPath() { 42 | Path p; 43 | p = new Path(generateSpeed()); 44 | p.addWaypoint(lastWaypoint.clone()); 45 | Coord c = lastWaypoint; 46 | 47 | for (int i=0; i" + toAddr + "] " + 52 | "size:" + size + " CREATE"; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/report/MessageReport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package report; 6 | 7 | import core.DTNHost; 8 | import core.Message; 9 | import core.MessageListener; 10 | 11 | /** 12 | * Reports delivered messages 13 | * report: 14 | * message_id creation_time deliver_time (duplicate) 15 | */ 16 | public class MessageReport extends Report implements MessageListener { 17 | public static final String HEADER = 18 | "# messages: ID, start time, end time"; 19 | /** all message delays */ 20 | 21 | /** 22 | * Constructor. 23 | */ 24 | public MessageReport() { 25 | init(); 26 | } 27 | 28 | @Override 29 | public void init() { 30 | super.init(); 31 | write(HEADER); 32 | } 33 | 34 | public void newMessage(Message m) {} 35 | 36 | public void messageTransferred(Message m, DTNHost from, DTNHost to, 37 | boolean firstDelivery) { 38 | if (firstDelivery) { 39 | write(m.getId() + " " 40 | + format(m.getCreationTime()) + " " 41 | + format(getSimTime())); 42 | } else { 43 | if (to.getAddress() == m.getTo().getAddress()) { 44 | write(m.getId() + " " 45 | + format(m.getCreationTime()) + " " 46 | + format(getSimTime()) + " duplicate"); 47 | } 48 | } 49 | } 50 | 51 | @Override 52 | public void done() { 53 | super.done(); 54 | } 55 | 56 | // nothing to implement for the rest 57 | public void messageDeleted(Message m, DTNHost where, boolean dropped) {} 58 | public void messageTransferAborted(Message m, DTNHost from, DTNHost to) {} 59 | public void messageTransferStarted(Message m, DTNHost from, DTNHost to) {} 60 | 61 | } 62 | -------------------------------------------------------------------------------- /wdm_settings/WDM_conf_help.txt: -------------------------------------------------------------------------------- 1 | meetingSpotsFile 2 | - WKT File containing the coordinates of meeting spots for evening activity 3 | 4 | officeLocationsFile 5 | - WKT File containing the coordinates of the office locations 6 | 7 | homeLocationsFile 8 | - WKT File containing the coordinates of home locations 9 | 10 | nrOfMeetingSpots 11 | - Only used if no meetingSpotsFile is specified, in which case the spots will be 12 | randomly placed on the map 13 | 14 | nrOfOffices 15 | - Same but for offices 16 | 17 | workDayLength 18 | - Length of the time spent at work 19 | 20 | probGoShoppingAfterWork 21 | - Probability to do evening activity 22 | 23 | officeWaitTimeParetoCoeff 24 | - The coefficient for the Pareto distribution controlling pause time inside office 25 | 26 | officeMinWaitTime 27 | - Min pause time inside office 28 | 29 | officeMaxWaitTime 30 | - Max pause time inside office 31 | 32 | officeSize 33 | - Size of the office in meters 34 | 35 | timeDiffSTD 36 | - Standard deviation for the normal distribution controlling differences in schedules nodes have 37 | 38 | minGroupSize 39 | - Minimum groups size for evening activity 40 | 41 | maxGroupSize 42 | - Maximum group size for evening activity 43 | 44 | minAfterShoppingStopTime 45 | - Minimum pause time after evening activity 46 | 47 | maxAfterShoppingStopTime 48 | - Maximum pause time after evening activity 49 | 50 | busControlSystemNr 51 | - The bus control system the node group is registered to (WDM nodes and Bus nodes) 52 | 53 | ownCarProb 54 | - Probability that the node owns a car 55 | 56 | shoppingControlSystemNr 57 | - The Evening activity control system the node group is registered to 58 | 59 | 60 | -------------------------------------------------------------------------------- /src/gui/EventLogControl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package gui; 6 | 7 | import javax.swing.JCheckBox; 8 | 9 | /** 10 | * Class capsulates the references to the controls one can add to 11 | * the EventLogControlPanel 12 | * 13 | */ 14 | public class EventLogControl { 15 | private JCheckBox show; 16 | private JCheckBox pause; 17 | 18 | /** 19 | * Constructor. 20 | * @param show The checkbox that controls showing this type of event 21 | * @param pause The checkbox that controls pausing on this type of event 22 | */ 23 | public EventLogControl(JCheckBox show, JCheckBox pause) { 24 | this.show = show; 25 | this.pause = pause; 26 | } 27 | 28 | /** 29 | * Returns true if this event type should be shown 30 | * @return true if this event type should be shown 31 | */ 32 | public boolean showEvent() { 33 | return this.show.isSelected(); 34 | } 35 | 36 | /** 37 | * Returns true if this event type should cause pause 38 | * @return true if this event type should cause pause 39 | */ 40 | 41 | public boolean pauseOnEvent() { 42 | return this.pause.isSelected(); 43 | } 44 | 45 | /** 46 | * Sets ought this event type should be shown (return true for 47 | * {@link #showEvent()} ) 48 | * @param show If true, events are set to be shown 49 | */ 50 | public void setShowEvent(boolean show) { 51 | this.show.setSelected(show); 52 | } 53 | 54 | /** 55 | * Sets ought this event type cause pause (return true for 56 | * {@link #pauseOnEvent()} ) 57 | * @param pause If true, events cause pause 58 | */ 59 | public void setPauseOnEvent(boolean pause) { 60 | this.pause.setSelected(pause); 61 | } 62 | 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/input/ConnectionEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package input; 6 | 7 | import core.DTNHost; 8 | import core.World; 9 | 10 | /** 11 | * A connection up/down event. 12 | */ 13 | public class ConnectionEvent extends ExternalEvent { 14 | /** address of the node the (dis)connection is from */ 15 | protected int fromAddr; 16 | /** address of the node the (dis)connection is to */ 17 | protected int toAddr; 18 | /** Is this a "connection up" event*/ 19 | protected boolean isUp; 20 | /** What is the interface number for this event*/ 21 | protected String interfaceId; 22 | 23 | /** 24 | * Creates a new connection event 25 | * @param from End point of connection 26 | * @param to Another end of connection 27 | * @param interf The number of interface for the connection 28 | * @param up If true, this was a "connection up" event, if false, this 29 | * was a "connection down" event 30 | * @param time Time when the Connection event occurs 31 | */ 32 | public ConnectionEvent(int from, int to, String interf, boolean up, double time) { 33 | super(time); 34 | assert to != from : "Can't self connect"; 35 | this.fromAddr = from; 36 | this.toAddr= to; 37 | this.isUp = up; 38 | this.interfaceId = interf; 39 | } 40 | 41 | @Override 42 | public void processEvent(World world) { 43 | DTNHost from = world.getNodeByAddress(this.fromAddr); 44 | DTNHost to = world.getNodeByAddress(this.toAddr); 45 | 46 | from.forceConnection(to, interfaceId, this.isUp); 47 | } 48 | 49 | @Override 50 | public String toString() { 51 | return "CONN " + (isUp ? "up" : "down") + " @" + this.time + " " + 52 | this.fromAddr+"<->"+this.toAddr; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/input/ExternalEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package input; 6 | 7 | import java.io.Serializable; 8 | 9 | import core.World; 10 | 11 | /** 12 | * Super class for all external events. All new classes of external events 13 | * must extend this class. This can also be used as a dummy event if only 14 | * an update request (and no further actions) to all hosts is needed. 15 | */ 16 | public class ExternalEvent implements Comparable, Serializable { 17 | /** Time of the event (simulated seconds) */ 18 | protected double time; 19 | 20 | public ExternalEvent(double time) { 21 | this.time = time; 22 | } 23 | 24 | /** 25 | * Processes the external event. 26 | * @param world World where the actors of the event are 27 | */ 28 | public void processEvent(World world) { 29 | // this is just a dummy event 30 | } 31 | 32 | /** 33 | * Returns the time when this event should happen. 34 | * @return Event's time 35 | */ 36 | public double getTime() { 37 | return this.time; 38 | } 39 | 40 | /** 41 | * Compares two external events by their time. 42 | * @return -1, zero, 1 if this event happens before, at the same time, 43 | * or after the other event 44 | * @param other The other external event 45 | */ 46 | public int compareTo(ExternalEvent other) { 47 | if (this.time == other.time) { 48 | return 0; 49 | } 50 | else if (this.time < other.time) { 51 | return -1; 52 | } 53 | else { 54 | return 1; 55 | } 56 | } 57 | 58 | /** 59 | * Returns a String representation of the event 60 | * @return a String representation of the event 61 | */ 62 | public String toString() { 63 | return "ExtEvent @ " + this.time; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/gui/playfield/ScaleReferenceGraphic.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package gui.playfield; 6 | 7 | import java.awt.Color; 8 | import java.awt.Font; 9 | import java.awt.Graphics2D; 10 | 11 | /** 12 | * Reference scale bar graphic. This is the small reference scale 13 | * on the upper left corner of the playfield. 14 | */ 15 | public class ScaleReferenceGraphic extends PlayFieldGraphic { 16 | /** minimum length of the reference bar (pixels) */ 17 | private final int MIN_LENGTH = 30; 18 | 19 | /** x position of the left end of the bar (pixels) */ 20 | private final int X_POS = 20; 21 | /** y position of the left end of the bar (pixels) */ 22 | private final int Y_POS = 20; 23 | /** height of the bar (pixels) */ 24 | private final int SIZE = 8; 25 | /** size of the font */ 26 | private final int FONT_SIZE = 10; 27 | /** color of the bar */ 28 | private final Color REF_COLOR = Color.BLACK; 29 | 30 | @Override 31 | public void draw(Graphics2D g2) { 32 | int meterLen = 1; 33 | String scaleUnit = "m"; 34 | double pixelLen = meterLen * scale; 35 | int endX; 36 | int h = SIZE/2; 37 | 38 | while (pixelLen < MIN_LENGTH) { 39 | meterLen *= 10; 40 | pixelLen = meterLen * scale; 41 | } 42 | if (meterLen >= 1000) { 43 | scaleUnit = "km"; 44 | meterLen /= 1000; 45 | } 46 | endX = X_POS + (int)pixelLen; 47 | 48 | g2.setFont(new Font(null, Font.PLAIN, FONT_SIZE)); 49 | 50 | g2.setColor(REF_COLOR); 51 | g2.drawLine(X_POS, Y_POS-h, X_POS, Y_POS+h); // left end 52 | g2.drawLine(X_POS, Y_POS, endX, Y_POS); // horizontal line 53 | g2.drawLine(endX, Y_POS-h, endX, Y_POS+h); 54 | 55 | g2.drawString(meterLen + scaleUnit, X_POS + 10, Y_POS - 1); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/routing/util/RoutingInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package routing.util; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | /** 11 | * Class for storing routing related information in a tree form for 12 | * user interface(s). 13 | */ 14 | public class RoutingInfo { 15 | private String text; 16 | private List moreInfo = null; 17 | 18 | /** 19 | * Creates a routing info based on a text. 20 | * @param infoText The text of the info 21 | */ 22 | public RoutingInfo(String infoText) { 23 | this.text = infoText; 24 | } 25 | 26 | /** 27 | * Creates a routing info based on any object. Object's 28 | * toString() method's output is used as the info text. 29 | * @param o The object this info is based on 30 | */ 31 | public RoutingInfo(Object o) { 32 | this.text = o.toString(); 33 | } 34 | 35 | /** 36 | * Adds child info object for this routing info. 37 | * @param info The info object to add. 38 | */ 39 | public void addMoreInfo(RoutingInfo info) { 40 | if (this.moreInfo == null) { // lazy creation 41 | this.moreInfo = new ArrayList(); 42 | } 43 | this.moreInfo.add(info); 44 | } 45 | 46 | /** 47 | * Returns the child routing infos of this info. 48 | * @return The children of this info or an empty list if this info 49 | * doesn't have any children. 50 | */ 51 | public List getMoreInfo() { 52 | if (this.moreInfo == null) { 53 | return new ArrayList(0); 54 | } 55 | return this.moreInfo; 56 | } 57 | 58 | /** 59 | * Returns the info text of this routing info. 60 | * @return The info text 61 | */ 62 | public String toString() { 63 | return this.text; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/report/TotalEncountersReport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package report; 6 | 7 | import java.util.List; 8 | 9 | import core.ConnectionListener; 10 | import core.DTNHost; 11 | import core.UpdateListener; 12 | 13 | /** 14 | * A report of the distribution of how many encounters (contacts) a node has had 15 | * 16 | * @author Frans Ekman 17 | */ 18 | public class TotalEncountersReport extends Report implements ConnectionListener, 19 | UpdateListener { 20 | 21 | private int[] encounters; 22 | 23 | public TotalEncountersReport() { 24 | 25 | } 26 | 27 | public void hostsConnected(DTNHost host1, DTNHost host2) { 28 | if (encounters == null) { 29 | return; 30 | } 31 | encounters[host1.getAddress()]++; 32 | encounters[host2.getAddress()]++; 33 | } 34 | 35 | public void hostsDisconnected(DTNHost host1, DTNHost host2) {} 36 | 37 | public void updated(List hosts) { 38 | if (encounters == null) { 39 | encounters = new int[hosts.size()]; 40 | } 41 | } 42 | 43 | @Override 44 | public void done() { 45 | 46 | int maxEncounters = -1; 47 | for (int i=0; i maxEncounters) { 49 | maxEncounters = encounters[i]; 50 | } 51 | } 52 | 53 | int[] distribution = new int[maxEncounters + 1]; 54 | 55 | for (int i=0; i " + h2; 65 | } 66 | else { 67 | return h2 + " <-> " + h1; 68 | } 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/report/EncountersVSUniqueEncountersReport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package report; 6 | 7 | import java.util.List; 8 | 9 | import core.ConnectionListener; 10 | import core.DTNHost; 11 | import core.UpdateListener; 12 | 13 | /** 14 | * The total- vs. the unique encounters for each node 15 | * 16 | * @author Frans Ekman 17 | */ 18 | public class EncountersVSUniqueEncountersReport extends Report 19 | implements ConnectionListener, UpdateListener { 20 | 21 | private TotalEncountersReport totalEncountersReport; 22 | private UniqueEncountersReport uniqueEncountersReport; 23 | 24 | public EncountersVSUniqueEncountersReport() { 25 | totalEncountersReport = new TotalEncountersReport(); 26 | uniqueEncountersReport = new UniqueEncountersReport(); 27 | } 28 | 29 | public void hostsConnected(DTNHost host1, DTNHost host2) { 30 | totalEncountersReport.hostsConnected(host1, host2); 31 | uniqueEncountersReport.hostsConnected(host1, host2); 32 | } 33 | 34 | public void hostsDisconnected(DTNHost host1, DTNHost host2) { 35 | totalEncountersReport.hostsDisconnected(host1, host2); 36 | uniqueEncountersReport.hostsDisconnected(host1, host2); 37 | } 38 | 39 | public void updated(List hosts) { 40 | totalEncountersReport.updated(hosts); 41 | uniqueEncountersReport.updated(hosts); 42 | } 43 | 44 | @Override 45 | public void done() { 46 | int[] totalEncounters = totalEncountersReport.getEncounters(); 47 | int[][] nodeRelationships = uniqueEncountersReport.getNodeRelationships(); 48 | 49 | for (int i=0; i 0) { 57 | count++; 58 | } 59 | } 60 | row += count; 61 | write(row); 62 | } 63 | 64 | super.done(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/test/TestSettings.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package test; 6 | 7 | import input.EventQueueHandler; 8 | 9 | import java.util.Properties; 10 | 11 | import movement.MovementModel; 12 | import core.SettingsError; 13 | import core.SimScenario; 14 | 15 | /** 16 | * Class for replacing Settings class in tests. 17 | * 18 | */ 19 | public class TestSettings extends core.Settings { 20 | 21 | public TestSettings() { 22 | init(null); 23 | 24 | /* put some test setting values to the Settings. These can be later 25 | * overridden by calls to putSetting(String, String) */ 26 | String sns = SimScenario.SCENARIO_NS + "."; 27 | String ens = EventQueueHandler.SETTINGS_NAMESPACE + "."; 28 | 29 | putSetting(sns + SimScenario.NROF_GROUPS_S, "1"); 30 | putSetting(sns + SimScenario.NAME_S, "TEST-Scenario"); 31 | putSetting(sns + SimScenario.END_TIME_S, "100"); 32 | putSetting(sns + SimScenario.UP_INT_S, "0.1"); 33 | putSetting(sns + SimScenario.SIM_CON_S, "true"); 34 | 35 | putSetting(ens + EventQueueHandler.NROF_SETTING, "0"); 36 | 37 | putSetting(MovementModel.MOVEMENT_MODEL_NS + "." + 38 | MovementModel.WORLD_SIZE, "1000,1000"); 39 | } 40 | 41 | public TestSettings(String ns) { 42 | super(ns); 43 | } 44 | 45 | public static void init(String propFile) throws SettingsError { 46 | props = new Properties(); 47 | } 48 | 49 | /** 50 | * Put a new setting or override an existing setting 51 | * @param key 52 | * @param value 53 | */ 54 | public void putSetting(String key, String value) { 55 | String nameSpace = getNameSpace(); 56 | if (nameSpace == null) { 57 | nameSpace = ""; 58 | } else { 59 | nameSpace += "."; 60 | } 61 | 62 | if (props == null) { 63 | try { 64 | init(null); 65 | } catch (SettingsError e) { 66 | e.printStackTrace(); 67 | System.exit(-1); 68 | } 69 | } 70 | 71 | props.put(nameSpace + key, value); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/movement/CarMovement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package movement; 6 | 7 | import java.util.List; 8 | 9 | import movement.map.DijkstraPathFinder; 10 | import movement.map.MapNode; 11 | import core.Coord; 12 | import core.Settings; 13 | 14 | /** 15 | * The CarMovement class representing the car movement submodel 16 | * 17 | * @author Frans Ekman 18 | */ 19 | public class CarMovement extends MapBasedMovement implements 20 | SwitchableMovement, TransportMovement { 21 | 22 | private Coord from; 23 | private Coord to; 24 | 25 | private DijkstraPathFinder pathFinder; 26 | 27 | /** 28 | * Car movement constructor 29 | * @param settings 30 | */ 31 | public CarMovement(Settings settings) { 32 | super(settings); 33 | pathFinder = new DijkstraPathFinder(getOkMapNodeTypes()); 34 | } 35 | 36 | /** 37 | * Construct a new CarMovement instance from a prototype 38 | * @param proto 39 | */ 40 | public CarMovement(CarMovement proto) { 41 | super(proto); 42 | this.pathFinder = proto.pathFinder; 43 | } 44 | 45 | /** 46 | * Sets the next route to be taken 47 | * @param nodeLocation 48 | * @param nodeDestination 49 | */ 50 | public void setNextRoute(Coord nodeLocation, Coord nodeDestination) { 51 | from = nodeLocation.clone(); 52 | to = nodeDestination.clone(); 53 | } 54 | 55 | @Override 56 | public Path getPath() { 57 | Path path = new Path(generateSpeed()); 58 | 59 | MapNode fromNode = getMap().getNodeByCoord(from); 60 | MapNode toNode = getMap().getNodeByCoord(to); 61 | 62 | List nodePath = pathFinder.getShortestPath(fromNode, toNode); 63 | 64 | for (MapNode node : nodePath) { // create a Path from the shortest path 65 | path.addWaypoint(node.getLocation()); 66 | } 67 | 68 | lastMapNode = toNode; 69 | 70 | return path; 71 | } 72 | 73 | /** 74 | * @see SwitchableMovement 75 | * @return true 76 | */ 77 | public boolean isReady() { 78 | return true; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/report/ConnectivityONEReport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package report; 6 | 7 | import core.ConnectionListener; 8 | import core.DTNHost; 9 | 10 | /** 11 | * Link connectivity report generator for ONE StandardEventsReader input. 12 | * Connections that start during the warm up period are ignored. 13 | */ 14 | public class ConnectivityONEReport extends Report 15 | implements ConnectionListener { 16 | 17 | /** 18 | * Constructor. 19 | */ 20 | public ConnectivityONEReport() { 21 | init(); 22 | } 23 | 24 | public void hostsConnected(DTNHost h1, DTNHost h2) { 25 | if (isWarmup()) { 26 | addWarmupID(connectionString(h1, h2)); 27 | return; 28 | } 29 | newEvent(); 30 | write(createTimeStamp() + " CONN " + connectionString(h1, h2) + " up"); 31 | } 32 | 33 | public void hostsDisconnected(DTNHost h1, DTNHost h2) { 34 | String conString = connectionString(h1, h2); 35 | 36 | if (isWarmup() || isWarmupID(conString)) { 37 | removeWarmupID(conString); 38 | return; 39 | } 40 | 41 | write(createTimeStamp() + " CONN " + conString + " down"); 42 | } 43 | 44 | /** 45 | * Creates and returns a "@" prefixed time stamp of the current simulation 46 | * time 47 | * @return time stamp of the current simulation time 48 | */ 49 | private String createTimeStamp() { 50 | return String.format("%.2f", getSimTime()); 51 | } 52 | 53 | /** 54 | * Creates and returns a String presentation of the connection where the 55 | * node with the lower network address is first 56 | * @param h1 The other node of the connection 57 | * @param h2 The other node of the connection 58 | * @return String presentation of the connection 59 | */ 60 | private String connectionString(DTNHost h1, DTNHost h2) { 61 | if (h1.getAddress() < h2.getAddress()) { 62 | return h1.getAddress() + " " + h2.getAddress(); 63 | } 64 | else { 65 | return h2.getAddress() + " " + h1.getAddress(); 66 | } 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/gui/playfield/PlayFieldGraphic.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package gui.playfield; 6 | 7 | import java.awt.Graphics2D; 8 | 9 | /** 10 | * Superclass for all graphics to be drawn on the "play field". 11 | */ 12 | public abstract class PlayFieldGraphic { 13 | /** Common scaling factor for all playfield graphics. 14 | * @see #setScale(double) 15 | */ 16 | protected static double scale = 1; 17 | 18 | /** 19 | * Set the zooming factor of the graphics to be drawn 20 | * @param newScale New scale 21 | */ 22 | public static void setScale(double newScale) { 23 | scale = newScale; 24 | } 25 | 26 | /** 27 | * Returns the currently used scaling factor 28 | * @return The scaling factor 29 | */ 30 | public static double getScale() { 31 | return scale; 32 | } 33 | 34 | /** 35 | * Draws the graphic component to the graphics context g2 36 | * @param g2 The context to draw the graphics to 37 | */ 38 | public abstract void draw(Graphics2D g2); 39 | 40 | 41 | /** 42 | * Scales the value according to current zoom level 43 | * @param value Value to scale 44 | * @return Scaled value bit-truncated (casted) to an integer 45 | */ 46 | public static int scale(double value) { 47 | return (int)Math.round(scale * value); 48 | } 49 | 50 | /** 51 | * Scales the value according to current zoom level 52 | * @param value Value to scale 53 | * @return Scaled value bit-truncated (casted) to an integer 54 | */ 55 | public static int scale(int value) { 56 | return (int)Math.round(scale * value); 57 | } 58 | 59 | /** 60 | * Performs an inverse of the scaling procedure with current scale. 61 | * NOTE: invScale(scale(value)) != value because of rounding to integer 62 | * at scale() -methods 63 | * @param value The value to inverse-scale 64 | * @return Inverse-scaled value 65 | * @see #scale(double) 66 | */ 67 | public static double invScale(double value) { 68 | return value/scale; 69 | } 70 | 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/report/MessageDeliveryReport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package report; 6 | 7 | import core.DTNHost; 8 | import core.Message; 9 | import core.MessageListener; 10 | 11 | /** 12 | * Report for of amount of messages delivered vs. time. A new report line 13 | * is created every time when either a message is created or delivered. 14 | * Messages created during the warm up period are ignored. 15 | * For output syntax, see {@link #HEADER}. 16 | */ 17 | public class MessageDeliveryReport extends Report implements MessageListener { 18 | public static String HEADER="# time created delivered delivered/created"; 19 | private int created; 20 | private int delivered; 21 | 22 | /** 23 | * Constructor. 24 | */ 25 | public MessageDeliveryReport() { 26 | init(); 27 | } 28 | 29 | @Override 30 | public void init() { 31 | super.init(); 32 | created = 0; 33 | delivered = 0; 34 | write(HEADER); 35 | } 36 | 37 | public void messageTransferred(Message m, DTNHost from, DTNHost to, 38 | boolean firstDelivery) { 39 | if (firstDelivery && !isWarmup() && !isWarmupID(m.getId())) { 40 | delivered++; 41 | reportValues(); 42 | } 43 | } 44 | 45 | public void newMessage(Message m) { 46 | if (isWarmup()) { 47 | addWarmupID(m.getId()); 48 | return; 49 | } 50 | created++; 51 | reportValues(); 52 | } 53 | 54 | /** 55 | * Writes the current values to report file 56 | */ 57 | private void reportValues() { 58 | double prob = (1.0 * delivered) / created; 59 | write(format(getSimTime()) + " " + created + " " + delivered + 60 | " " + format(prob)); 61 | } 62 | 63 | // nothing to implement for the rest 64 | public void messageDeleted(Message m, DTNHost where, boolean dropped) {} 65 | public void messageTransferAborted(Message m, DTNHost from, DTNHost to) {} 66 | public void messageTransferStarted(Message m, DTNHost from, DTNHost to) {} 67 | 68 | @Override 69 | public void done() { 70 | super.done(); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/core/MessageListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package core; 6 | 7 | /** 8 | * Interface for classes that want to be informed about messages 9 | * between hosts 10 | * 11 | */ 12 | public interface MessageListener { 13 | 14 | /** 15 | * Method is called when a new message is created 16 | * @param m Message that was created 17 | */ 18 | public void newMessage(Message m); 19 | 20 | /** 21 | * Method is called when a message's transfer is started 22 | * @param m The message that is going to be transferred 23 | * @param from Node where the message is transferred from 24 | * @param to Node where the message is transferred to 25 | */ 26 | public void messageTransferStarted(Message m, DTNHost from, DTNHost to); 27 | 28 | /** 29 | * Method is called when a message is deleted 30 | * @param m The message that was deleted 31 | * @param where The host where the message was deleted 32 | * @param dropped True if the message was dropped, false if removed 33 | */ 34 | public void messageDeleted(Message m, DTNHost where, boolean dropped); 35 | 36 | /** 37 | * Method is called when a message's transfer was aborted before 38 | * it finished 39 | * @param m The message that was being transferred 40 | * @param from Node where the message was being transferred from 41 | * @param to Node where the message was being transferred to 42 | */ 43 | public void messageTransferAborted(Message m, DTNHost from, DTNHost to); 44 | 45 | /** 46 | * Method is called when a message is successfully transferred from 47 | * a node to another. 48 | * @param m The message that was transferred 49 | * @param from Node where the message was transferred from 50 | * @param to Node where the message was transferred to 51 | * @param firstDelivery Was the target node final destination of the message 52 | * and received this message for the first time. 53 | */ 54 | public void messageTransferred(Message m, DTNHost from, DTNHost to, 55 | boolean firstDelivery); 56 | } 57 | -------------------------------------------------------------------------------- /src/movement/ClusterMovement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | 6 | /** 7 | * Random waypoint movement where the coordinates are restricted to circular 8 | * area defined by a central point and range. 9 | * @author teemuk 10 | */ 11 | package movement; 12 | 13 | import core.Coord; 14 | import core.Settings; 15 | 16 | public class ClusterMovement extends RandomWaypoint { 17 | /** Range of the cluster */ 18 | public static final String CLUSTER_RANGE = "clusterRange"; 19 | /** Center point of the cluster */ 20 | public static final String CLUSTER_CENTER = "clusterCenter"; 21 | 22 | private int p_x_center = 100, p_y_center = 100; 23 | private double p_range = 100.0; 24 | 25 | public ClusterMovement(Settings s) { 26 | super(s); 27 | 28 | if (s.contains(CLUSTER_RANGE)){ 29 | this.p_range = s.getDouble(CLUSTER_RANGE); 30 | } 31 | if (s.contains(CLUSTER_CENTER)){ 32 | int[] center = s.getCsvInts(CLUSTER_CENTER,2); 33 | this.p_x_center = center[0]; 34 | this.p_y_center = center[1]; 35 | } 36 | } 37 | 38 | private ClusterMovement(ClusterMovement cmv) { 39 | super(cmv); 40 | this.p_range = cmv.p_range; 41 | this.p_x_center = cmv.p_x_center; 42 | this.p_y_center = cmv.p_y_center; 43 | } 44 | 45 | @Override 46 | protected Coord randomCoord() { 47 | double x = (rng.nextDouble()*2 - 1)*this.p_range; 48 | double y = (rng.nextDouble()*2 - 1)*this.p_range; 49 | while (x*x + y*y>this.p_range*this.p_range) { 50 | x = (rng.nextDouble()*2 - 1)*this.p_range; 51 | y = (rng.nextDouble()*2 - 1)*this.p_range; 52 | } 53 | x += this.p_x_center; 54 | y += this.p_y_center; 55 | return new Coord(x,y); 56 | } 57 | 58 | @Override 59 | public int getMaxX() { 60 | return (int)Math.ceil(this.p_x_center + this.p_range); 61 | } 62 | 63 | @Override 64 | public int getMaxY() { 65 | return (int)Math.ceil(this.p_y_center + this.p_range); 66 | } 67 | 68 | @Override 69 | public ClusterMovement replicate() { 70 | return new ClusterMovement(this); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/test/TestDTNHost.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package test; 6 | 7 | import java.util.List; 8 | 9 | import routing.PassiveRouter; 10 | import core.Coord; 11 | import core.DTNHost; 12 | import core.Message; 13 | import core.ModuleCommunicationBus; 14 | import core.NetworkInterface; 15 | import core.Settings; 16 | import core.SimClock; 17 | 18 | /** 19 | * A test stub of DTNHost for testing. All fields are public so they can be 20 | * easily read from test cases. 21 | */ 22 | public class TestDTNHost extends DTNHost { 23 | public double lastUpdate = 0; 24 | public int nrofConnect = 0; 25 | public int nrofUpdate = 0; 26 | public Message recvMessage; 27 | public DTNHost recvFrom; 28 | public String abortedId; 29 | public DTNHost abortedFrom; 30 | public int abortedBytesRemaining; 31 | 32 | public String transferredId; 33 | public DTNHost transferredFrom; 34 | 35 | 36 | public TestDTNHost(List li, 37 | ModuleCommunicationBus comBus, Settings testSettings) { 38 | super(null,null,"TST", li, comBus, 39 | new StationaryMovement(new Coord(0,0)), 40 | new PassiveRouter( 41 | (testSettings == null ? new TestSettings() : 42 | testSettings))); 43 | } 44 | 45 | @Override 46 | public void connect(DTNHost anotherHost) { 47 | this.nrofConnect++; 48 | } 49 | 50 | @Override 51 | public void update(boolean up) { 52 | this.nrofUpdate++; 53 | this.lastUpdate = SimClock.getTime(); 54 | } 55 | 56 | @Override 57 | public int receiveMessage(Message m, DTNHost from) { 58 | this.recvMessage = m; 59 | this.recvFrom = from; 60 | return routing.MessageRouter.RCV_OK; 61 | } 62 | 63 | @Override 64 | public void messageAborted(String id, DTNHost from, int bytesRemaining) { 65 | this.abortedId = id; 66 | this.abortedFrom = from; 67 | this.abortedBytesRemaining = bytesRemaining; 68 | } 69 | 70 | @Override 71 | public void messageTransferred(String id, DTNHost from) { 72 | this.transferredId = id; 73 | this.transferredFrom = from; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/util/Range.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package util; 6 | 7 | /** 8 | * Range of values 9 | * @author Ari 10 | */ 11 | public class Range { 12 | 13 | private double min; 14 | private double max; 15 | 16 | /** 17 | * Creates a new range 18 | * @param min The minimum bound of the range 19 | * @param max The maximum bound 20 | */ 21 | public Range(double min, double max) { 22 | this.min = min; 23 | this.max = max; 24 | checkRangeValidity(min, max); 25 | } 26 | 27 | /** 28 | * Parses a range from the given string 29 | * @param str The string to parse 30 | * @throws NumberFormatException if the range didn't contain numeric values 31 | */ 32 | public Range(String str) throws NumberFormatException { 33 | if (str.indexOf("-") != str.lastIndexOf("-")) { 34 | /* TODO */ 35 | throw new Error("Ranges with negative values not supported"); 36 | } 37 | 38 | if (str.substring(1).contains("-")) { 39 | /* has "-" but not as the first char -> range */ 40 | String[] vals = str.split("-"); 41 | this.min = Double.parseDouble(vals[0]); 42 | this.max = Double.parseDouble(vals[1]); 43 | } else { 44 | this.min = this.max = Double.parseDouble(str); 45 | } 46 | checkRangeValidity(min, max); 47 | } 48 | 49 | /** 50 | * Checks if the given values for a valid range 51 | * @param min The minimum value 52 | * @param max The maximum value 53 | * @throws Error if min > max 54 | */ 55 | private void checkRangeValidity(double min, double max) { 56 | if (min > max) { 57 | throw new Error("Minimum value is larger than maximum"); 58 | } 59 | } 60 | 61 | /** 62 | * Returns true if the given value is within this range [min, max], 63 | * min and max included 64 | * @param value The value to check 65 | * @return True if the given value is in the range, false if not 66 | */ 67 | public boolean isInRange(double value) { 68 | return (value >= min && value <= max); 69 | } 70 | 71 | @Override 72 | public String toString() { 73 | return "Range [" + min + ", " + max + "]"; 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/report/UniqueEncountersReport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package report; 6 | 7 | import java.util.List; 8 | 9 | import core.ConnectionListener; 10 | import core.DTNHost; 11 | import core.UpdateListener; 12 | 13 | /** 14 | * UniqueEncountersReport class creates a report of the distribution of how 15 | * many promilles of the other nodes a node has encountered. 16 | * 17 | * @author Frans Ekman 18 | */ 19 | public class UniqueEncountersReport extends Report implements 20 | ConnectionListener, UpdateListener { 21 | 22 | private int[][] nodeRelationships; 23 | 24 | public UniqueEncountersReport() { 25 | 26 | } 27 | 28 | public void hostsConnected(DTNHost host1, DTNHost host2) { 29 | if (nodeRelationships == null) { 30 | return; 31 | } 32 | nodeRelationships[host1.getAddress()][host2.getAddress()]++; 33 | nodeRelationships[host2.getAddress()][host1.getAddress()]++; 34 | } 35 | 36 | public void hostsDisconnected(DTNHost host1, DTNHost host2) {} 37 | 38 | public void updated(List hosts) { 39 | if (nodeRelationships == null) { 40 | nodeRelationships = new int[hosts.size()][hosts.size()]; 41 | } 42 | } 43 | 44 | @Override 45 | public void done() { 46 | int[] distribution = new int[1000]; 47 | 48 | if (nodeRelationships == null) { 49 | super.done(); 50 | return; 51 | } 52 | 53 | for (int i=0; i 0) { 57 | count++; 58 | } 59 | } 60 | 61 | int promille = (count * 1000)/nodeRelationships.length; 62 | distribution[promille]++; 63 | } 64 | 65 | // print distribution 66 | for (int i=0; i; 17 | my $firstLine = ; 18 | 19 | my ($x, $y, $z, $time, $id) = parseLine($firstLine); 20 | initMinMax(0,$time); 21 | initMinMax(1, $x); 22 | initMinMax(2, $y); 23 | initMinMax(3, $z); 24 | $initLocs{$id} = [$x, $y, $z]; 25 | 26 | while() { 27 | ($x, $y, $z, $time, $id) = parseLine($_); 28 | if (not defined($x)) { 29 | debug("Invalid line '$_'"); 30 | next; 31 | } 32 | 33 | $initLocs{$id} = [$x, $y, $z] unless $initLocs{$id}; 34 | 35 | upMinMax(0,$time); 36 | upMinMax(1,$x); 37 | upMinMax(2,$y); 38 | upMinMax(3,$z); 39 | } 40 | 41 | print OUTFILE "@limits\n"; 42 | 43 | seek(INFILE,0,0) or die "Can't seek input file"; 44 | $header = ; 45 | 46 | while ( my ($k, $v) = each %initLocs) { 47 | print OUTFILE "$limits[0] $k @$v\n"; 48 | } 49 | 50 | while () { 51 | my ($x, $y, $z, $time, $id) = parseLine($_); 52 | next unless defined $x; 53 | if ($time > $limits[0]) { # min time location are already there 54 | print OUTFILE "$time $id $x $y $z\n"; 55 | } 56 | } 57 | 58 | sub initMinMax { 59 | my $index = shift; 60 | my $val = shift; 61 | 62 | $index *= 2; 63 | $limits[$index] = $val; 64 | $limits[$index+1] = $val; 65 | } 66 | 67 | sub upMinMax { 68 | my $index = shift; 69 | my $val = shift; 70 | 71 | $index *= 2; 72 | 73 | if ($val < $limits[$index]) { # update min 74 | #print "up min at $index $limits[$index] to $val\n"; 75 | $limits[$index] = $val; 76 | } 77 | 78 | if ($val > $limits[$index+1]) { # update max 79 | #print "up max at $index $limits[$index+1] to $val\n"; 80 | $limits[$index+1] = $val; 81 | } 82 | } 83 | 84 | sub parseLine { 85 | my $line = shift; 86 | my @data = split(/\s+/, $line); 87 | return ($data[4],$data[9],$data[5],$data[11], $data[3]); 88 | } 89 | -------------------------------------------------------------------------------- /src/test/ExternalMovementReaderTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package test; 6 | 7 | import input.ExternalMovementReader; 8 | 9 | import java.io.File; 10 | import java.io.PrintWriter; 11 | import java.util.List; 12 | 13 | import util.Tuple; 14 | 15 | import junit.framework.TestCase; 16 | import core.Coord; 17 | 18 | public class ExternalMovementReaderTest extends TestCase { 19 | private ExternalMovementReader r; 20 | private static final String INPUT = 21 | "0 0 0 0 0 0\n"+ 22 | "10 1 10 10\n"+ 23 | "10 2 10 20 1010\n" + 24 | "10 3 10 30\n" + 25 | "20 1 20 10 dummyData\n" + 26 | "20 2 20 20\n" + 27 | "\n"+ 28 | "20 3 30 30\n" + 29 | "30 1 30 20\n" + 30 | "30 2 30 30\n" + 31 | "30 3 40 30"; 32 | private static final String [] ids = {"1","2","3"}; 33 | private static final double [] times = {10,20,30}; 34 | private static final Coord [][] coords = 35 | { {new Coord(10,10), new Coord(10,20), new Coord(10,30)}, 36 | {new Coord(20,10), new Coord(20,20), new Coord(30,30)}, 37 | {new Coord(30,20), new Coord(30,30), new Coord(40,30)} }; 38 | 39 | 40 | protected void setUp() throws Exception { 41 | super.setUp(); 42 | 43 | File tmpFile = File.createTempFile("EMRTest","tmp"); 44 | tmpFile.deleteOnExit(); 45 | 46 | PrintWriter pw = new PrintWriter(tmpFile); 47 | pw.println(INPUT); 48 | pw.close(); 49 | 50 | r = new ExternalMovementReader(tmpFile.getAbsolutePath()); 51 | } 52 | 53 | public void testReader() { 54 | List> list; 55 | 56 | for (int i=0; i> list, String[] ids, 67 | Coord[] coords) { 68 | 69 | assertEquals(ids.length, list.size()); 70 | 71 | for (int i=0; i String representation mapping */ 24 | public static final String[] STAGE_STRINGS = {"SENDING", 25 | "TRANSFERRED", "ABORTED"}; 26 | 27 | /** 28 | * Creates a message relaying event 29 | * @param from Where the message comes from (at this hop) 30 | * @param to Who the message goes to (at this hop) 31 | * @param id ID of the message 32 | * @param time Time when this event happens 33 | * @param stage The stage of the event (SENDING, TRANSFERRED, or ABORTED) 34 | */ 35 | public MessageRelayEvent(int from, int to, String id, double time, 36 | int stage) { 37 | super(from, to, id, time); 38 | this.stage = stage; 39 | } 40 | 41 | /** 42 | * Relays the message 43 | */ 44 | public void processEvent(World world) { 45 | // get DTNHosts and pass messages between them 46 | DTNHost from = world.getNodeByAddress(this.fromAddr); 47 | DTNHost to = world.getNodeByAddress(this.toAddr); 48 | 49 | switch(stage) { 50 | case SENDING: 51 | from.sendMessage(id, to); 52 | break; 53 | case TRANSFERRED: 54 | to.messageTransferred(id, from); 55 | break; 56 | case ABORTED: 57 | to.messageAborted(id, from, -1); 58 | break; 59 | default: 60 | assert false : "Invalid stage (" + stage + ") for " + this; 61 | } 62 | } 63 | 64 | @Override 65 | public String toString() { 66 | return super.toString() + " [" + fromAddr + "->" + toAddr + "] " + 67 | STAGE_STRINGS[stage-1]; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /ee/70_events_100_nodes_700ks.txt: -------------------------------------------------------------------------------- 1 | 10403.6 C M1 68 75 705189 2 | 22828.0 C M2 91 60 334117 3 | 45827.0 C M3 37 40 216100 4 | 66567.1 C M4 18 40 285882 5 | 70516.0 C M5 70 95 434904 6 | 72037.6 C M6 10 72 794199 7 | 74826.1 C M7 65 60 5520 8 | 76436.1 C M8 55 44 807579 9 | 77929.1 C M9 39 22 693824 10 | 79001.1 C M10 60 54 269002 11 | 82176.1 C M11 10 31 722650 12 | 88897.1 C M12 29 37 516052 13 | 106512.9 C M13 66 96 481182 14 | 111643.1 C M14 15 37 203618 15 | 162748.3 C M15 65 43 238528 16 | 166179.5 C M16 10 32 268916 17 | 167586.0 C M17 87 15 328930 18 | 176849.8 C M18 35 19 457799 19 | 182089.4 C M19 76 9 956895 20 | 208708.8 C M20 66 73 476028 21 | 216143.6 C M21 37 72 672786 22 | 230857.0 C M22 81 72 725607 23 | 245544.3 C M23 27 36 464891 24 | 247153.8 C M24 16 69 670170 25 | 257030.3 C M25 33 7 295683 26 | 258708.1 C M26 86 60 936977 27 | 262352.4 C M27 2 69 178141 28 | 268475.6 C M28 10 5 356531 29 | 270691.2 C M29 56 68 154934 30 | 271328.9 C M30 76 57 46363 31 | 276814.2 C M31 82 31 645088 32 | 283504.6 C M32 62 9 807252 33 | 293447.6 C M33 90 37 897702 34 | 298798.4 C M34 86 45 917059 35 | 301102.4 C M35 66 80 189446 36 | 319110.4 C M36 22 74 228270 37 | 331688.8 C M37 74 97 348840 38 | 352754.0 C M38 59 21 247652 39 | 360890.3 C M39 46 98 436984 40 | 375571.9 C M40 12 69 198701 41 | 390358.8 C M41 16 2 898281 42 | 451682.3 C M42 33 5 445482 43 | 464822.4 C M43 42 33 947919 44 | 479024.0 C M44 83 12 45508 45 | 487031.6 C M45 53 12 30278 46 | 490618.8 C M46 18 6 676473 47 | 492988.2 C M47 90 86 774031 48 | 503872.9 C M48 45 73 799338 49 | 516052.0 C M49 98 59 952608 50 | 516423.1 C M50 5 80 364339 51 | 536950.5 C M51 64 60 884147 52 | 547342.6 C M52 72 32 602849 53 | 558327.7 C M53 59 51 197374 54 | 574178.9 C M54 37 44 886555 55 | 584131.4 C M55 28 40 326896 56 | 586986.7 C M56 5 30 832354 57 | 590952.2 C M57 40 26 424089 58 | 610442.8 C M58 3 77 451858 59 | 615411.2 C M59 31 53 791071 60 | 620397.7 C M60 14 96 850065 61 | 635527.1 C M61 79 51 399811 62 | 639019.9 C M62 97 66 495214 63 | 663977.8 C M63 46 23 300723 64 | 670328.0 C M64 38 6 900630 65 | 679497.4 C M65 70 1 761630 66 | 680160.1 C M66 36 2 391930 67 | 682689.2 C M67 99 4 196145 68 | 684784.6 C M68 91 53 169498 69 | 686225.9 C M69 8 18 56664 70 | 695255.0 C M70 22 29 874383 71 | -------------------------------------------------------------------------------- /src/ui/DTNSimTextUI.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package ui; 6 | 7 | import core.SimClock; 8 | 9 | /** 10 | * Simple text-based user interface. 11 | */ 12 | public class DTNSimTextUI extends DTNSimUI { 13 | private long lastUpdateRt; // real time of last ui update 14 | private long startTime; // simulation start time 15 | /** How often the UI view is updated (milliseconds) */ 16 | public static final long UI_UP_INTERVAL = 60000; 17 | 18 | protected void runSim() { 19 | double simTime = SimClock.getTime(); 20 | double endTime = scen.getEndTime(); 21 | 22 | print("Running simulation '" + scen.getName()+"'"); 23 | 24 | startTime = System.currentTimeMillis(); 25 | lastUpdateRt = startTime; 26 | 27 | while (simTime < endTime && !simCancelled){ 28 | try { 29 | world.update(); 30 | } catch (AssertionError e) { 31 | e.printStackTrace(); 32 | done(); 33 | return; 34 | } 35 | simTime = SimClock.getTime(); 36 | this.update(false); 37 | } 38 | 39 | double duration = (System.currentTimeMillis() - startTime)/1000.0; 40 | 41 | simDone = true; 42 | done(); 43 | this.update(true); // force final UI update 44 | 45 | print("Simulation done in " + String.format("%.2f", duration) + "s"); 46 | 47 | } 48 | 49 | /** 50 | * Updates user interface if the long enough (real)time (update interval) 51 | * has passed from the previous update. 52 | * @param forced If true, the update is done even if the next update 53 | * interval hasn't been reached. 54 | */ 55 | private void update(boolean forced) { 56 | long now = System.currentTimeMillis(); 57 | long diff = now - this.lastUpdateRt; 58 | double dur = (now - startTime)/1000.0; 59 | if (forced || (diff > UI_UP_INTERVAL)) { 60 | // simulated seconds/second calc 61 | double ssps = ((SimClock.getTime() - lastUpdate)*1000) / diff; 62 | print(String.format("%.1f %d: %.2f 1/s", dur, 63 | SimClock.getIntTime(),ssps)); 64 | 65 | this.lastUpdateRt = System.currentTimeMillis(); 66 | this.lastUpdate = SimClock.getTime(); 67 | } 68 | } 69 | 70 | private void print(String txt) { 71 | System.out.println(txt); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/report/MessageDelayReport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package report; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | import core.DTNHost; 11 | import core.Message; 12 | import core.MessageListener; 13 | 14 | /** 15 | * Reports delivered messages' delays (one line per delivered message) 16 | * and cumulative delivery probability sorted by message delays. 17 | * Ignores the messages that were created during the warm up period. 18 | */ 19 | public class MessageDelayReport extends Report implements MessageListener { 20 | public static final String HEADER = 21 | "# messageDelay cumulativeProbability"; 22 | /** all message delays */ 23 | private List delays; 24 | private int nrofCreated; 25 | 26 | /** 27 | * Constructor. 28 | */ 29 | public MessageDelayReport() { 30 | init(); 31 | } 32 | 33 | @Override 34 | public void init() { 35 | super.init(); 36 | write(HEADER); 37 | this.delays = new ArrayList(); 38 | this.nrofCreated = 0; 39 | } 40 | 41 | public void newMessage(Message m) { 42 | if (isWarmup()) { 43 | addWarmupID(m.getId()); 44 | } 45 | else { 46 | this.nrofCreated++; 47 | } 48 | } 49 | 50 | public void messageTransferred(Message m, DTNHost from, DTNHost to, 51 | boolean firstDelivery) { 52 | if (firstDelivery && !isWarmupID(m.getId())) { 53 | this.delays.add(getSimTime() - m.getCreationTime()); 54 | } 55 | 56 | } 57 | 58 | @Override 59 | public void done() { 60 | if (delays.size() == 0) { 61 | write("# no messages delivered in sim time "+format(getSimTime())); 62 | super.done(); 63 | return; 64 | } 65 | double cumProb = 0; // cumulative probability 66 | 67 | java.util.Collections.sort(delays); 68 | 69 | for (int i=0; i < delays.size(); i++) { 70 | cumProb += 1.0/nrofCreated; 71 | write(format(delays.get(i)) + " " + format(cumProb)); 72 | } 73 | super.done(); 74 | } 75 | 76 | // nothing to implement for the rest 77 | public void messageDeleted(Message m, DTNHost where, boolean dropped) {} 78 | public void messageTransferAborted(Message m, DTNHost from, DTNHost to) {} 79 | public void messageTransferStarted(Message m, DTNHost from, DTNHost to) {} 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/report/MessageGraphvizReport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package report; 6 | 7 | import java.util.List; 8 | import java.util.Vector; 9 | 10 | import core.DTNHost; 11 | import core.Message; 12 | import core.MessageListener; 13 | 14 | /** 15 | * Creates a graphviz compatible graph of messages that were passed. 16 | * Messages created during the warm up period are ignored. 17 | */ 18 | public class MessageGraphvizReport extends Report implements MessageListener { 19 | /** Name of the graphviz report ({@value})*/ 20 | public static final String GRAPH_NAME = "msggraph"; 21 | private Vector deliveredMessages; 22 | 23 | /** 24 | * Constructor. 25 | */ 26 | public MessageGraphvizReport() { 27 | init(); 28 | } 29 | 30 | protected void init() { 31 | super.init(); 32 | this.deliveredMessages = new Vector(); 33 | } 34 | 35 | public void newMessage(Message m) { 36 | if (isWarmup()) { 37 | addWarmupID(m.getId()); 38 | } 39 | } 40 | 41 | public void messageTransferred(Message m, DTNHost from, 42 | DTNHost to, boolean firstDelivery) { 43 | if (firstDelivery && !isWarmupID(m.getId())) { 44 | newEvent(); 45 | this.deliveredMessages.add(m); 46 | } 47 | } 48 | 49 | /* nothing to implement for these */ 50 | public void messageDeleted(Message m, DTNHost where, boolean dropped) { } 51 | public void messageTransferAborted(Message m, DTNHost from, DTNHost to) {} 52 | public void messageTransferStarted(Message m, DTNHost from, DTNHost to) {} 53 | 54 | @Override 55 | public void done() { 56 | write("/* scenario " + getScenarioName() + "\n" + 57 | deliveredMessages.size() + " messages delivered at " + 58 | "sim time " + getSimTime() + " */") ; 59 | write("digraph " + GRAPH_NAME + " {"); 60 | setPrefix("\t"); // indent following lines by one tab 61 | 62 | for (Message m : deliveredMessages) { 63 | List path = m.getHops(); 64 | String pathString = path.remove(0).toString(); // start node 65 | 66 | for (DTNHost next : path) { 67 | pathString += "->" + next.toString(); 68 | } 69 | 70 | write (pathString + ";"); 71 | } 72 | 73 | setPrefix(""); // don't indent anymore 74 | write("}"); 75 | 76 | super.done(); 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/movement/RandomWalk.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package movement; 6 | 7 | import core.Coord; 8 | import core.Settings; 9 | 10 | /** 11 | * Random Walk movement model 12 | * 13 | * @author Frans Ekman 14 | */ 15 | public class RandomWalk extends MovementModel implements SwitchableMovement { 16 | 17 | private Coord lastWaypoint; 18 | private double minDistance; 19 | private double maxDistance; 20 | 21 | public RandomWalk(Settings settings) { 22 | super(settings); 23 | minDistance = 0; 24 | maxDistance = 50; 25 | } 26 | 27 | private RandomWalk(RandomWalk rwp) { 28 | super(rwp); 29 | minDistance = rwp.minDistance; 30 | maxDistance = rwp.maxDistance; 31 | } 32 | 33 | /** 34 | * Returns a possible (random) placement for a host 35 | * @return Random position on the map 36 | */ 37 | @Override 38 | public Coord getInitialLocation() { 39 | assert rng != null : "MovementModel not initialized!"; 40 | double x = rng.nextDouble() * getMaxX(); 41 | double y = rng.nextDouble() * getMaxY(); 42 | Coord c = new Coord(x,y); 43 | 44 | this.lastWaypoint = c; 45 | return c; 46 | } 47 | 48 | @Override 49 | public Path getPath() { 50 | Path p; 51 | p = new Path(generateSpeed()); 52 | p.addWaypoint(lastWaypoint.clone()); 53 | double maxX = getMaxX(); 54 | double maxY = getMaxY(); 55 | 56 | Coord c = null; 57 | while (true) { 58 | 59 | double angle = rng.nextDouble() * 2 * Math.PI; 60 | double distance = minDistance + rng.nextDouble() * 61 | (maxDistance - minDistance); 62 | 63 | double x = lastWaypoint.getX() + distance * Math.cos(angle); 64 | double y = lastWaypoint.getY() + distance * Math.sin(angle); 65 | 66 | c = new Coord(x,y); 67 | 68 | if (x > 0 && y > 0 && x < maxX && y < maxY) { 69 | break; 70 | } 71 | } 72 | 73 | p.addWaypoint(c); 74 | 75 | this.lastWaypoint = c; 76 | return p; 77 | } 78 | 79 | @Override 80 | public RandomWalk replicate() { 81 | return new RandomWalk(this); 82 | } 83 | 84 | public Coord getLastLocation() { 85 | return lastWaypoint; 86 | } 87 | 88 | public void setLocation(Coord lastWaypoint) { 89 | this.lastWaypoint = lastWaypoint; 90 | } 91 | 92 | public boolean isReady() { 93 | return true; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/movement/ShortestPathMapBasedMovement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package movement; 6 | 7 | import java.util.List; 8 | 9 | import movement.map.DijkstraPathFinder; 10 | import movement.map.MapNode; 11 | import movement.map.PointsOfInterest; 12 | import core.Settings; 13 | 14 | /** 15 | * Map based movement model that uses Dijkstra's algorithm to find shortest 16 | * paths between two random map nodes and Points Of Interest 17 | */ 18 | public class ShortestPathMapBasedMovement extends MapBasedMovement implements 19 | SwitchableMovement { 20 | /** the Dijkstra shortest path finder */ 21 | private DijkstraPathFinder pathFinder; 22 | 23 | /** Points Of Interest handler */ 24 | private PointsOfInterest pois; 25 | 26 | /** 27 | * Creates a new movement model based on a Settings object's settings. 28 | * @param settings The Settings object where the settings are read from 29 | */ 30 | public ShortestPathMapBasedMovement(Settings settings) { 31 | super(settings); 32 | this.pathFinder = new DijkstraPathFinder(getOkMapNodeTypes()); 33 | this.pois = new PointsOfInterest(getMap(), getOkMapNodeTypes(), 34 | settings, rng); 35 | } 36 | 37 | /** 38 | * Copyconstructor. 39 | * @param mbm The ShortestPathMapBasedMovement prototype to base 40 | * the new object to 41 | */ 42 | protected ShortestPathMapBasedMovement(ShortestPathMapBasedMovement mbm) { 43 | super(mbm); 44 | this.pathFinder = mbm.pathFinder; 45 | this.pois = mbm.pois; 46 | } 47 | 48 | @Override 49 | public Path getPath() { 50 | Path p = new Path(generateSpeed()); 51 | MapNode to = pois.selectDestination(); 52 | 53 | List nodePath = pathFinder.getShortestPath(lastMapNode, to); 54 | 55 | // this assertion should never fire if the map is checked in read phase 56 | assert nodePath.size() > 0 : "No path from " + lastMapNode + " to " + 57 | to + ". The simulation map isn't fully connected"; 58 | 59 | for (MapNode node : nodePath) { // create a Path from the shortest path 60 | p.addWaypoint(node.getLocation()); 61 | } 62 | 63 | lastMapNode = to; 64 | 65 | return p; 66 | } 67 | 68 | @Override 69 | public ShortestPathMapBasedMovement replicate() { 70 | return new ShortestPathMapBasedMovement(this); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/report/DeliveredMessagesReport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package report; 6 | 7 | import java.util.List; 8 | 9 | import core.DTNHost; 10 | import core.Message; 11 | import core.MessageListener; 12 | 13 | /** 14 | * Report information about all delivered messages. Messages created during 15 | * the warm up period are ignored. 16 | * For output syntax, see {@link #HEADER}. 17 | */ 18 | public class DeliveredMessagesReport extends Report implements MessageListener { 19 | public static String HEADER = "# time ID size hopcount deliveryTime " + 20 | "fromHost toHost remainingTtl isResponse path"; 21 | 22 | /** 23 | * Constructor. 24 | */ 25 | public DeliveredMessagesReport() { 26 | init(); 27 | } 28 | 29 | @Override 30 | public void init() { 31 | super.init(); 32 | write(HEADER); 33 | } 34 | 35 | /** 36 | * Returns the given messages hop path as a string 37 | * @param m The message 38 | * @return hop path as a string 39 | */ 40 | private String getPathString(Message m) { 41 | List hops = m.getHops(); 42 | String str = m.getFrom().toString(); 43 | 44 | for (int i=1; i \$help, 20 | "foreach" => \$doForEach, 21 | "countplot" => \$countPlot, 22 | "verbose" => \$verbose); 23 | 24 | if (not $help and (not @ARGV)) { 25 | print "Missing required parameter(s)\n"; 26 | print $usage; 27 | exit(); 28 | } 29 | 30 | $doForEach = 1 if defined $countPlot; 31 | 32 | if ($help) { 33 | print 'MessageCopyCountReport analyzer.'; 34 | print "\n$usage"; 35 | print ' 36 | options: 37 | foreach Do analyzing per message, not per timestamp 38 | countplot Use output that is suitable for message lifetime plots 39 | '; 40 | exit(); 41 | } 42 | 43 | 44 | my ($time, $lastTime, @ids); 45 | my $timeSum = 0; 46 | my %foreachSums; 47 | my $timeStep = 0; 48 | 49 | # Input example: 50 | # [120] 51 | # M1 567 52 | # M2 678 53 | 54 | while (<>) { 55 | if (m/^\s*$/ or m/^#/) { 56 | next; # skip empty and comment lines 57 | } 58 | if (m/^\[(\d*)\]/) { # next timestamp 59 | $lastTime = $time; 60 | $time = $1; 61 | 62 | if (not defined $lastTime) { # first timestamp 63 | $timeStep = $time; 64 | next; 65 | } 66 | 67 | next; # not doing per time stamp but per message 68 | } 69 | 70 | my ($msgId, $count) = m/^\D+(\d+) (\d+)$/; 71 | die "No valid message count at line $_" unless (defined $msgId and defined $count); 72 | 73 | $foreachSums{$msgId} = [()] unless $foreachSums{$msgId}; 74 | push @{ $foreachSums{$msgId} }, $count; 75 | } 76 | 77 | if ($doForEach) { 78 | my @sortedKeys = sort {$a<=>$b} keys %foreachSums; 79 | my $valuesLeft = 1; 80 | print "# " . join (' ', @sortedKeys) . "\n"; 81 | 82 | while ($valuesLeft) { 83 | my $sum = 0; 84 | $valuesLeft = 0; 85 | foreach my $id (@sortedKeys) { 86 | my $value = shift @{ $foreachSums{$id} }; 87 | 88 | if (not defined $value) { 89 | $value = 0; 90 | } else { 91 | $valuesLeft = 1; # still values left 92 | } 93 | print "$value "; 94 | } 95 | 96 | print "\n"; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/report/PingAppReporter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | 6 | package report; 7 | 8 | import applications.PingApplication; 9 | import core.Application; 10 | import core.ApplicationListener; 11 | import core.DTNHost; 12 | 13 | /** 14 | * Reporter for the PingApplication. Counts the number of pings 15 | * and pongs sent and received. Calculates success probabilities. 16 | * 17 | * @author teemuk 18 | */ 19 | public class PingAppReporter extends Report implements ApplicationListener { 20 | 21 | private int pingsSent=0, pingsReceived=0; 22 | private int pongsSent=0, pongsReceived=0; 23 | 24 | public void gotEvent(String event, Object params, Application app, 25 | DTNHost host) { 26 | // Check that the event is sent by correct application type 27 | if (!(app instanceof PingApplication)) return; 28 | 29 | // Increment the counters based on the event type 30 | if (event.equalsIgnoreCase("GotPing")) { 31 | pingsReceived++; 32 | } 33 | if (event.equalsIgnoreCase("SentPong")) { 34 | pongsSent++; 35 | } 36 | if (event.equalsIgnoreCase("GotPong")) { 37 | pongsReceived++; 38 | } 39 | if (event.equalsIgnoreCase("SentPing")) { 40 | pingsSent++; 41 | } 42 | 43 | } 44 | 45 | 46 | @Override 47 | public void done() { 48 | write("Ping stats for scenario " + getScenarioName() + 49 | "\nsim_time: " + format(getSimTime())); 50 | double pingProb = 0; // ping probability 51 | double pongProb = 0; // pong probability 52 | double successProb = 0; // success probability 53 | 54 | if (this.pingsSent > 0) { 55 | pingProb = (1.0 * this.pingsReceived) / this.pingsSent; 56 | } 57 | if (this.pongsSent > 0) { 58 | pongProb = (1.0 * this.pongsReceived) / this.pongsSent; 59 | } 60 | if (this.pingsSent > 0) { 61 | successProb = (1.0 * this.pongsReceived) / this.pingsSent; 62 | } 63 | 64 | String statsText = "pings sent: " + this.pingsSent + 65 | "\npings received: " + this.pingsReceived + 66 | "\npongs sent: " + this.pongsSent + 67 | "\npongs received: " + this.pongsReceived + 68 | "\nping delivery prob: " + format(pingProb) + 69 | "\npong delivery prob: " + format(pongProb) + 70 | "\nping/pong success prob: " + format(successProb) 71 | ; 72 | 73 | write(statsText); 74 | super.done(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/movement/BusMovement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package movement; 6 | 7 | import java.util.LinkedList; 8 | import java.util.List; 9 | 10 | import movement.map.MapNode; 11 | import core.Coord; 12 | import core.Settings; 13 | 14 | /** 15 | * This class controls the movement of busses. It informs the bus control system 16 | * the bus is registered with every time the bus stops. 17 | * 18 | * @author Frans Ekman 19 | */ 20 | public class BusMovement extends MapRouteMovement { 21 | 22 | private BusControlSystem controlSystem; 23 | private int id; 24 | private static int nextID = 0; 25 | private boolean startMode; 26 | private List stops; 27 | 28 | /** 29 | * Creates a new instance of BusMovement 30 | * @param settings 31 | */ 32 | public BusMovement(Settings settings) { 33 | super(settings); 34 | int bcs = settings.getInt(BusControlSystem.BUS_CONTROL_SYSTEM_NR); 35 | controlSystem = BusControlSystem.getBusControlSystem(bcs); 36 | controlSystem.setMap(super.getMap()); 37 | this.id = nextID++; 38 | controlSystem.registerBus(this); 39 | startMode = true; 40 | stops = new LinkedList(); 41 | List stopNodes = super.getStops(); 42 | for (MapNode node : stopNodes) { 43 | stops.add(node.getLocation().clone()); 44 | } 45 | controlSystem.setBusStops(stops); 46 | } 47 | 48 | /** 49 | * Create a new instance from a prototype 50 | * @param proto 51 | */ 52 | public BusMovement(BusMovement proto) { 53 | super(proto); 54 | this.controlSystem = proto.controlSystem; 55 | this.id = nextID++; 56 | controlSystem.registerBus(this); 57 | startMode = true; 58 | } 59 | 60 | @Override 61 | public Coord getInitialLocation() { 62 | return (super.getInitialLocation()).clone(); 63 | } 64 | 65 | @Override 66 | public Path getPath() { 67 | Coord lastLocation = (super.getLastLocation()).clone(); 68 | Path path = super.getPath(); 69 | if (!startMode) { 70 | controlSystem.busHasStopped(id, lastLocation, path); 71 | } 72 | startMode = false; 73 | return path; 74 | } 75 | 76 | @Override 77 | public BusMovement replicate() { 78 | return new BusMovement(this); 79 | } 80 | 81 | /** 82 | * Returns unique ID of the bus 83 | * @return unique ID of the bus 84 | */ 85 | public int getID() { 86 | return id; 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /src/input/OneToEachMessageGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package input; 6 | 7 | import java.util.ArrayList; 8 | import java.util.Collections; 9 | import java.util.List; 10 | 11 | import core.Settings; 12 | import core.SettingsError; 13 | 14 | /** 15 | * Message creation -external events generator. Creates one message from 16 | * source node/nodes (defined with {@link MessageEventGenerator#HOST_RANGE_S}) 17 | * to all destination nodes (defined with 18 | * {@link MessageEventGenerator#TO_HOST_RANGE_S}). 19 | * The message size, first messages time and the intervals between creating 20 | * messages can be configured like with {@link MessageEventGenerator}. End 21 | * time is not respected, but messages are created until there's a message for 22 | * every destination node. 23 | * @see MessageEventGenerator 24 | */ 25 | public class OneToEachMessageGenerator extends MessageEventGenerator { 26 | private List toIds; 27 | 28 | public OneToEachMessageGenerator(Settings s) { 29 | super(s); 30 | this.toIds = new ArrayList(); 31 | 32 | if (toHostRange == null) { 33 | throw new SettingsError("Destination host (" + TO_HOST_RANGE_S + 34 | ") must be defined"); 35 | } 36 | for (int i = toHostRange[0]; i < toHostRange[1]; i++) { 37 | toIds.add(i); 38 | } 39 | Collections.shuffle(toIds, rng); 40 | } 41 | 42 | /** 43 | * Returns the next message creation event 44 | * @see input.EventQueue#nextEvent() 45 | */ 46 | public ExternalEvent nextEvent() { 47 | int responseSize = 0; /* no responses requested */ 48 | int from; 49 | int to; 50 | 51 | from = drawHostAddress(hostRange); 52 | to = this.toIds.remove(0); 53 | 54 | if (to == from) { /* skip self */ 55 | if (this.toIds.size() == 0) { /* oops, no more from addresses */ 56 | this.nextEventsTime = Double.MAX_VALUE; 57 | return new ExternalEvent(Double.MAX_VALUE); 58 | } else { 59 | to = this.toIds.remove(0); 60 | } 61 | } 62 | 63 | if (this.toIds.size() == 0) { 64 | this.nextEventsTime = Double.MAX_VALUE; /* no messages left */ 65 | } else { 66 | this.nextEventsTime += drawNextEventTimeDiff(); 67 | } 68 | 69 | MessageCreateEvent mce = new MessageCreateEvent(from, to, getID(), 70 | drawMessageSize(), responseSize, this.nextEventsTime); 71 | 72 | return mce; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/test/MessageGraphvizReportTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package test; 6 | 7 | import java.io.BufferedReader; 8 | import java.io.File; 9 | import java.io.FileReader; 10 | import java.io.IOException; 11 | import java.util.Vector; 12 | 13 | import junit.framework.TestCase; 14 | import report.MessageGraphvizReport; 15 | import core.Coord; 16 | import core.DTNHost; 17 | import core.Message; 18 | import core.MessageListener; 19 | 20 | public class MessageGraphvizReportTest extends TestCase { 21 | private File outFile; 22 | private MessageGraphvizReport r; 23 | private TestUtils utils; 24 | 25 | public void setUp() throws IOException { 26 | TestSettings ts = new TestSettings(); 27 | outFile = File.createTempFile("mgtest", ".tmp"); 28 | outFile.deleteOnExit(); 29 | 30 | ts.putSetting("MessageGraphvizReport.output", outFile.getAbsolutePath()); 31 | ts.putSetting("MessageGraphvizReport.interval" , ""); 32 | 33 | Vector ml = new Vector(); 34 | r = new MessageGraphvizReport(); 35 | ml.add(r); 36 | utils = new TestUtils(null, ml, ts); 37 | } 38 | 39 | private void generateMessages() { 40 | Coord c1 = new Coord(0,0); 41 | Coord c2 = new Coord(1,0); 42 | Coord c3 = new Coord(2,0); 43 | 44 | utils.setTransmitRange(2); 45 | DTNHost h1 = utils.createHost(c1,"h1"); 46 | DTNHost h2 = utils.createHost(c2,"h2"); 47 | DTNHost h3 = utils.createHost(c3,"h3"); 48 | 49 | h1.createNewMessage(new Message(h1, h3, "M1", 1)); 50 | h1.sendMessage("M1", h2); 51 | h2.messageTransferred("M1", h1); 52 | h2.sendMessage("M1", h3); 53 | h3.messageTransferred("M1", h2); 54 | h3.createNewMessage(new Message(h3, h2, "M2", 1)); 55 | h3.sendMessage("M2", h2); 56 | h2.messageTransferred("M2", h3); 57 | } 58 | 59 | public void testDone() throws IOException{ 60 | BufferedReader reader; 61 | 62 | generateMessages(); 63 | r.done(); 64 | 65 | reader = new BufferedReader(new FileReader(outFile)); 66 | reader.readLine(); // read comment lines 67 | reader.readLine(); // read comment lines 68 | assertEquals("digraph " + MessageGraphvizReport.GRAPH_NAME + 69 | " {", reader.readLine()); 70 | assertEquals("\th1->h2->h3;",reader.readLine()); 71 | assertEquals("\th3->h2;",reader.readLine()); 72 | assertEquals("}",reader.readLine()); 73 | 74 | reader.close(); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/input/OneFromEachMessageGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package input; 6 | 7 | import java.util.ArrayList; 8 | import java.util.Collections; 9 | import java.util.List; 10 | 11 | import core.Settings; 12 | import core.SettingsError; 13 | 14 | /** 15 | * Message creation -external events generator. Creates one message from 16 | * every source node (defined with {@link MessageEventGenerator#HOST_RANGE_S}) 17 | * to one of the destination nodes (defined with 18 | * {@link MessageEventGenerator#TO_HOST_RANGE_S}). 19 | * The message size, first messages time and the intervals between creating 20 | * messages can be configured like with {@link MessageEventGenerator}. End 21 | * time is not respected, but messages are created until every from-node has 22 | * created a message. 23 | * @see MessageEventGenerator 24 | */ 25 | public class OneFromEachMessageGenerator extends MessageEventGenerator { 26 | private List fromIds; 27 | 28 | public OneFromEachMessageGenerator(Settings s) { 29 | super(s); 30 | this.fromIds = new ArrayList(); 31 | 32 | if (toHostRange == null) { 33 | throw new SettingsError("Destination host (" + TO_HOST_RANGE_S + 34 | ") must be defined"); 35 | } 36 | for (int i = hostRange[0]; i < hostRange[1]; i++) { 37 | fromIds.add(i); 38 | } 39 | Collections.shuffle(fromIds, rng); 40 | } 41 | 42 | /** 43 | * Returns the next message creation event 44 | * @see input.EventQueue#nextEvent() 45 | */ 46 | public ExternalEvent nextEvent() { 47 | int responseSize = 0; /* no responses requested */ 48 | int from; 49 | int to; 50 | 51 | from = this.fromIds.remove(0); 52 | to = drawToAddress(toHostRange, -1); 53 | 54 | if (to == from) { /* skip self */ 55 | if (this.fromIds.size() == 0) { /* oops, no more from addresses */ 56 | this.nextEventsTime = Double.MAX_VALUE; 57 | return new ExternalEvent(Double.MAX_VALUE); 58 | } else { 59 | from = this.fromIds.remove(0); 60 | } 61 | } 62 | 63 | if (this.fromIds.size() == 0) { 64 | this.nextEventsTime = Double.MAX_VALUE; /* no messages left */ 65 | } else { 66 | this.nextEventsTime += drawNextEventTimeDiff(); 67 | } 68 | 69 | MessageCreateEvent mce = new MessageCreateEvent(from, to, getID(), 70 | drawMessageSize(), responseSize, this.nextEventsTime); 71 | 72 | return mce; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /toolkit/dtnsim2parser.pl: -------------------------------------------------------------------------------- 1 | #! /usr/local/bin/perl 2 | 3 | package Toolkit; 4 | 5 | # dtnsim2 output parser v0.1 6 | 7 | # Apply patches to dtnsim2 and run it with verbose mode 8. 8 | # Then apply this script to dtnsim2's output and use the result 9 | # as the external events file for simulation. 10 | 11 | # This version should convert all events properly at least for 12 | # epidemic simulations. 13 | 14 | use strict; 15 | use warnings; 16 | use Common; # parseArgs and debug methods 17 | 18 | parseArgs("dtnsim2parser"); 19 | 20 | # actions that are mapped 21 | my %commandMapping = ( 22 | 'Sending' => 'C',# message created 23 | 'C_MSG_SENDING' => 'S', # started transfer 24 | 'ACCEPTED' => 'DE', # Accepted -> delivered 25 | 'C_DOWN_SEND_ABORT' => 'A', # aborted transfer 26 | 'REFUSED' => 'A', # Refusing -> aborting 27 | 'DROPPED epidemic' => 'DR', 28 | 'Removing copy of' => 'R' 29 | ); 30 | 31 | # actions that are ignored at the moment 32 | my %ignoreCommands = ('C_MSG_SENT' => 1, 33 | 'C_MSG_DELIVERED' => 1, 34 | 'DELIVERED_FIRST' => 1, 35 | 'DELIVERED_NEXT' => 1 36 | ); 37 | 38 | while() { 39 | # timestamp action msgId 40 | my ($time, $action, $id) = m/^(\d+\.\d+): ([\w\s]+):? (MSG_\d+_D_\d+)_\(\d+\)/; 41 | 42 | unless ($time and $action and $id) { 43 | debug ("Discarded: $_"); 44 | next; 45 | } 46 | 47 | my $actionCode = $commandMapping{$action}; 48 | 49 | die "Unknown action '" , $action,"'\n" unless $actionCode or $ignoreCommands{$action}; 50 | next unless $actionCode; 51 | 52 | my $lastPart; 53 | 54 | if ($actionCode eq 'C') { 55 | m/NODE_'(\w+)' => NODE_'(\w+)'\); Size: (\d+); result: (\w+)/; 56 | die "Couldn't parse CREATE line $_ \n" unless $1 and $2 and $3; 57 | my ($h1, $h2, $size, $result) = ($1, $2, $3, $4); 58 | 59 | if ($result ne "true") { 60 | debug ("Failed create: $_"); 61 | next; 62 | } 63 | 64 | $lastPart = "$h1\t$h2\t$size"; 65 | } 66 | elsif ($actionCode eq 'DR' or $actionCode eq 'R') { 67 | my ($host) = m/at (\w+)$/; 68 | die "Couldn't parse host from $_\n" unless $host; 69 | $lastPart = $host; 70 | } 71 | else { 72 | my ($h1, $h2) = m/CONTACT_'(\w+)->(\w+)'/; 73 | die "Couldn't parse contact from $_\n" unless $h1 and $h2; 74 | $lastPart = "$h1\t$h2"; 75 | } 76 | 77 | print OUTFILE "$time\t$actionCode\t$id\t$lastPart\n"; 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/test/MapNodeTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Aalto University, ComNet 3 | * Released under GPLv3. See LICENSE.txt for details. 4 | */ 5 | package test; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | import junit.framework.TestCase; 11 | import movement.map.MapNode; 12 | import movement.map.SimMap; 13 | import core.Coord; 14 | 15 | public class MapNodeTest extends TestCase { 16 | private MapNode n1,n2,n3,n4; 17 | private Coord c1,c2,c3,c4; 18 | private SimMap map; 19 | 20 | public void setUp() { 21 | c1 = new Coord(10,10); 22 | c2 = new Coord(20,20); 23 | c3 = new Coord(30,30); 24 | c4 = new Coord(2552448.388211649, 6673384.4020657055); 25 | 26 | n1 = new MapNode(c1); 27 | n2 = new MapNode(c2); 28 | n3 = new MapNode(c3); 29 | n4 = new MapNode(c4); 30 | 31 | Map cmMap = new HashMap(); 32 | cmMap.put(c1, n1); 33 | cmMap.put(c2, n2); 34 | cmMap.put(c3, n3); 35 | cmMap.put(c4, n4); 36 | 37 | map = new SimMap(cmMap); 38 | } 39 | 40 | public void testAddNeighbor() { 41 | assertTrue(n1.getNeighbors().size() == 0); 42 | assertTrue(n2.getNeighbors().size() == 0); 43 | 44 | // n1--n2 45 | n1.addNeighbor(n2); 46 | n2.addNeighbor(n1); 47 | assertTrue(n1.getNeighbors().size() == 1); 48 | assertTrue(n2.getNeighbors().size() == 1); 49 | 50 | // n1--n2--n3 51 | n2.addNeighbor(n3); 52 | n3.addNeighbor(n2); 53 | assertTrue(n2.getNeighbors().size() == 2); 54 | assertTrue(n3.getNeighbors().size() == 1); 55 | assertTrue(n1.getNeighbors().size() == 1); 56 | 57 | // add same again 58 | n2.addNeighbor(n3); 59 | n3.addNeighbor(n2); 60 | assertTrue(n2.getNeighbors().size() == 2); 61 | assertTrue(n3.getNeighbors().size() == 1); 62 | } 63 | 64 | public void testNodeByCoord() { 65 | Coord nearC1 = c1.clone(); 66 | nearC1.translate(0.1, 0.1); 67 | 68 | assertNull(map.getNodeByCoord(nearC1)); 69 | assertNull(map.getNodeByCoord(new Coord(1233213,123123123))); 70 | 71 | assertEquals(n1, map.getNodeByCoord(c1)); 72 | assertEquals(n3, map.getNodeByCoord(c3)); 73 | 74 | assertEquals(n1, map.getNodeByCoord(c1.clone())); 75 | assertEquals(n1, map.getNodeByCoord(new Coord(c1.getX(), c1.getY()))); 76 | assertEquals(n4, map.getNodeByCoord(new Coord(c4.getX(), c4.getY()))); 77 | 78 | Coord c4Clone = c4.clone(); 79 | Coord c4Clone2 = c4.clone(); 80 | 81 | c4Clone.setLocation(c4Clone.getX(), -c4Clone.getY()); 82 | c4Clone2.setLocation(c4Clone2.getX(), -c4Clone2.getY()); 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /toolkit/getAverages.pl: -------------------------------------------------------------------------------- 1 | #! /usr/bin/perl 2 | 3 | # Gets averages from multiple time-stamped files 4 | 5 | package Toolkit; 6 | use strict; 7 | use warnings; 8 | use Getopt::Long; 9 | use FileHandle; 10 | 11 | my $error; 12 | my $help; 13 | 14 | my $usage = ' 15 | usage: [-error] [-help] 16 | '; 17 | 18 | GetOptions("error!" => \$error, "help|?!" => \$help); 19 | 20 | if (not $help and not @ARGV) { 21 | print "Missing required parameter(s)\n"; 22 | print $usage; 23 | exit(); 24 | } 25 | 26 | if ($help) { 27 | print 'Report file value averager. Counts and prints out average for 28 | each line over multiple files. 29 | Expected syntax for input files: