diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 7c3dcb0e7..3bf45997e 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,6 +1,6 @@
# Contributing
-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.
+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.
If you are not sure where to start, new tests are always very welcome! Bugfixes are also highly appreciated.
@@ -10,4 +10,4 @@ If you want to add new features, there are some things to take into consideratio
* If the new feature requires changes to existing classes, make sure the feature is generic and shared by many use cases.
* 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)
-When doing contributions, please try to follow the coding style of the existing code.
\ No newline at end of file
+When doing contributions, please try to follow the coding style of the existing code.
diff --git a/HISTORY.txt b/HISTORY.txt
index 0e90d4166..10fa566c2 100644
--- a/HISTORY.txt
+++ b/HISTORY.txt
@@ -1,205 +1,205 @@
-HISTORY
-
-This document describes the main changes between each release version.
-
-
-Version 1.6.0 (Oct 2015)
- - Migrated code to github: https://github.com/akeranen/the-one
- - New interface module: DistanceCapacityInterface for modeling
- interfaces where transfer capacity depends on the distance between
- nodes (see also example_settings/wifi-interface.txt)
- - New report module: BufferOccupancyReport
- - New movement modules: RandomDirection and ModifiedRandomDirection
- - moved all example settings except default_settings.txt to example_settings
- - Lots of small bug fixes
-
-
-Version 1.5.0 (Dec 2011 - Nov 2013)
- - New movement models
- - GridLocation for static grid formations
- - LinearMovement for nodes moving on a line
- - Path-based external movement model and reader (ExternalPathMovement)
- - New router modules
- - WaveRouter for forwarding messages in waves
- - LifeRouter for "Conway's game of life"-kind of routing
- - ProphetV2Router with updated PRoPHET algorithm (by Samo Grasic)
- - New Report modules: MessageCopyCountReport & MessageAvailabilityReport
- (and analyzing/plotting scripts for them)
- - Generic energy awareness feature for all routing modules
- - Message Transfer Accept Policy for defining which messages and from who
- the nodes should accept for transfers (with any routing module)
- - Configuration settings improvements
- - Ability to define ranges as setting values
- - Ability to define arithmetic expressions as setting values
- - Default-getters for various settings types
- - Optimization option to simulate connections only once (see World class)
- - Sub-namespace support
- - Group-specific network interface related settings (e.g., activePeriods
- and scanInterval) are now in "net" sub-namespace
- - GUI fixes & updates
- - Offset to playfield view and dynamic scaling of distance reference bar
- - Option to disable (by default) the node name string
- - Autorefresh-feature and keeping the expanded-state to routing info window
- - Showing of radio coverages, connections and message count is configurable
- - New GUI features
- - Focus nodes by clicking on the playfield (see "Playfield options" menu)
- - GUI node filters feature and one message based filter (see "Tools" menu)
- - Bugfixes
- - Scan intervals work also without MessageCommunicationBus;
- thanks to Matthew Orlinski
- - Connections are properly cleared when ActivenessHandler is used
- - MaxProp doesn't send messages to hosts that have already received the
- message even if they have then deleted it
- - Fix to scanning intervals (works with only the 1st interface though)
- - Fixed cellSizeMultiplier in ConnectivityGrid class
- - Message blacklisting for messages that have been rejected by application
- - Typo fix to initialEnergy setting (need to update config files using this)
- - Refactoring (may break some third party code)
- - Moved utility classes to util and routing.util packages
- - Renamed getOldestMessage method to getNextMessageToRemove in ActiveRouter
-
-
-Version 1.4.1 (31 Jan 2011)
- - Bugfixes
- - External connectivity traces now properly clear connections; thanks to CS
- - InterferenceLimitedInterface speeds are updated; thanks to Jad Makhlouta
- - CarMovement reads speed properly from settings
- - Warmup time fix to connectivity reports
- - Fixed initial location (was off by one stop) in MapRoute movement model
- - dieselnetConverter.pl supports now also exponent format in the input data
- - GUI fixes
- - Fixed window resize issue and using spinner instead of dropdown for zoom
- levels; thanks to PJ
- - Set of javadoc, style, and other small fixes
-
-
-Version 1.4.0 (18 Mar 2010)
- - Added the possibility for each node having multiple interfaces
- * Requires changes to the configuration files, see default_settings.txt
- - New/improved routing algorithms
- * added parametrization for MaxProp (default alpha=1)
- * added Prophet and Maxprop routing algorithm versions that
- take timescale as a parameter, and estimate the needed routing algorithm
- parameters based on that
- * see Karvo and Ott, Time Scales and Delay-Tolerant Routing Protocols,
- CHANTS 2008, for more information.
- * added new (unrealistic) EpidemicOracleRouter that transfers messages
- immediately and deletes all replicas from buffers when the message is
- delivered
- * added maximum meeting probability set size support for MaxProp to improve
- its performance in scenarios with many nodes
- - Added MessageReport class for reporting message deliveries,
- CreatedMessagesReport for message creations and EventLogReport for
- reporting everything (in a StandardEventsReader-compatible format)
- - Added application layer
- * applications can be created by extending the Application class
- * multiple applications can run in the nodes
- * report modules can register for application events
- * see PingApplication and PingAppReporter for an example
- - Added ClusterMovement for creating clusters of nodes and LinearFormation
- for lines of nodes
- - ExternalMovementReader supports comment lines (starting with "#")
- - "Delete all" message event and support for this in StandardEventsReader
- - Possibility to choose first route stop for MapRouteMovement
- - Added new message event generators: OneFromEachMessageGenerator and
- OneToEachMessageGenerator
- - Added time range setting to MessageEventGenerator
- - GUI improvements
- * highlighting of pause-events to EventLogPanel
- * GUI starts paused by default
- * hh:mm:ss display for simulation time (right-click the simulation time)
- - Improved and new analysis scripts
- * added "log", "total", and "index" options for the ccdfPlotter.pl
- * added getStatsAverages.pl
- - Bugfixes
- * host range checking in MessageEventGenerator
- * command line option -b doesn't require range anymore
-
-
-
-Version 1.3.0 (19 Jan 2009)
-- New Features
- - ModuleCommunicationBus for sharing information between different
- (types of) modules
- - EnergyAwareRouter demonstrating energy awareness possibilities and use of
- the ModuleCommunicationBus
- - EnergyLevelReport for reporting the energy levels
- - ConnectivityONEReport class for generating connectivity traces
- that can be read using the StandardEventsReader
-- Enhancements
- - Any number of input config files supported
- - Batch mode supports run index ranges (can start from any index)
- - small change in the command line syntax; see README for details
- - MessageEventGenerator supports message creation time and destination
- host ranges
- - NetworkLayer has configurable scanning intervals
- - ExternalEventsQueue can be configured like all the other event
- generators (though the old way is still supported too)
- - ccdfPlotter script has better help and can now also create CDFs
-- New toolkit scripts
- - messageLocationAnimator for creating GIF animations out of
- MessageLocation reports
- - dieselNetConverter for converting DieselNet traces into ONE
- mobility traces
- - getAverages for counting averages out of different time-stamped reports
- - splotEnergy for creating 3D plots from EnergyLevel reports
-- Fixed bugs in
- - handling of incoming messages with expired TTL
- - report directory creation; thanks to STARpio
- - BusTravellerMovement incState; thanks to Mehedi Bakht
- - MaxProp calcTreshold; thanks to Vasco Soares and STARpio
-
-
-Version 1.2.0 (25 Aug 2008)
-- New movement model (framework): Working Day Movement
- - see WDM_conf_help.txt for configuration help
- - sample configuration files can be found from the wdm_settings folder
- - for information about the model, see our paper at
- http://www.netlab.tkk.fi/tutkimus/distance/papers/
- 2008-mobmod-working-day-model.pdf
-- A "stationary movement model" StationaryMovement.
- - useful for running simulations with only connectivity trace input
- - createCircles.pl script for easily creating suitable configuration
- files for this movement model
-
-
-Version 1.1.0 (6 May 2008)
-- External Events Interface which allows event generator classes that
- can generate external events (such as creating new messages or
- setting up and tearing down connections). See EventQueueHandler
- class for details.
- - due to the EEI, some API changes (in e.g.,
- createNewMessage method)
- - external events file feature is now part of the new interface
- - MessageEventGenerator class for generating uniformly
- distributed message creation patterns
- - new event: ConnectionEvent (supported by StandardEventsReader)
-- Configurable message queue modes (random and FIFO)
-- Option to automatically delete messages that are already delivered
- to the final recipient
-- Small change in the ordering of checks whether transfer has
- already succeeded when the connection has gone down
-- Connection class has now getTransferDoneTime method
-- Settings class can validate range settings (assertValidRange)
-- Classes that need to reset static fields between batch runs can
- register to the "resetting service" at DTNSim class
- (registerForReset)
-- Experimental "update scheduling" functionality that can be used to
- dynamically insert "update points" between time steps for higher
- precision simulations
-- DTN2 connectivity (requires JDK 6 or higher)
-- Generic property adding feature for Message class (addProperty,
- getProperty and updateProperty)
- - SprayAndWait router uses this now for the copy count
-- New tests
-
-
-Version 1.0.1 (24 February 2008)
-- New warm up feature for the report modules that allows ignoring
- events and messages that were created during a configurable warm
- up time.
-- New routing module: First Contact
-
-
-Version 1.0.0 (27 November 2007)
-- First official public release
+HISTORY
+
+This document describes the main changes between each release version.
+
+
+Version 1.6.0 (Oct 2015)
+ - Migrated code to github: https://github.com/akeranen/the-one
+ - New interface module: DistanceCapacityInterface for modeling
+ interfaces where transfer capacity depends on the distance between
+ nodes (see also example_settings/wifi-interface.txt)
+ - New report module: BufferOccupancyReport
+ - New movement modules: RandomDirection and ModifiedRandomDirection
+ - moved all example settings except default_settings.txt to example_settings
+ - Lots of small bug fixes
+
+
+Version 1.5.0 (Dec 2011 - Nov 2013)
+ - New movement models
+ - GridLocation for static grid formations
+ - LinearMovement for nodes moving on a line
+ - Path-based external movement model and reader (ExternalPathMovement)
+ - New router modules
+ - WaveRouter for forwarding messages in waves
+ - LifeRouter for "Conway's game of life"-kind of routing
+ - ProphetV2Router with updated PRoPHET algorithm (by Samo Grasic)
+ - New Report modules: MessageCopyCountReport & MessageAvailabilityReport
+ (and analyzing/plotting scripts for them)
+ - Generic energy awareness feature for all routing modules
+ - Message Transfer Accept Policy for defining which messages and from who
+ the nodes should accept for transfers (with any routing module)
+ - Configuration settings improvements
+ - Ability to define ranges as setting values
+ - Ability to define arithmetic expressions as setting values
+ - Default-getters for various settings types
+ - Optimization option to simulate connections only once (see World class)
+ - Sub-namespace support
+ - Group-specific network interface related settings (e.g., activePeriods
+ and scanInterval) are now in "net" sub-namespace
+ - GUI fixes & updates
+ - Offset to playfield view and dynamic scaling of distance reference bar
+ - Option to disable (by default) the node name string
+ - Autorefresh-feature and keeping the expanded-state to routing info window
+ - Showing of radio coverages, connections and message count is configurable
+ - New GUI features
+ - Focus nodes by clicking on the playfield (see "Playfield options" menu)
+ - GUI node filters feature and one message based filter (see "Tools" menu)
+ - Bugfixes
+ - Scan intervals work also without MessageCommunicationBus;
+ thanks to Matthew Orlinski
+ - Connections are properly cleared when ActivenessHandler is used
+ - MaxProp doesn't send messages to hosts that have already received the
+ message even if they have then deleted it
+ - Fix to scanning intervals (works with only the 1st interface though)
+ - Fixed cellSizeMultiplier in ConnectivityGrid class
+ - Message blacklisting for messages that have been rejected by application
+ - Typo fix to initialEnergy setting (need to update config files using this)
+ - Refactoring (may break some third party code)
+ - Moved utility classes to util and routing.util packages
+ - Renamed getOldestMessage method to getNextMessageToRemove in ActiveRouter
+
+
+Version 1.4.1 (31 Jan 2011)
+ - Bugfixes
+ - External connectivity traces now properly clear connections; thanks to CS
+ - InterferenceLimitedInterface speeds are updated; thanks to Jad Makhlouta
+ - CarMovement reads speed properly from settings
+ - Warmup time fix to connectivity reports
+ - Fixed initial location (was off by one stop) in MapRoute movement model
+ - dieselnetConverter.pl supports now also exponent format in the input data
+ - GUI fixes
+ - Fixed window resize issue and using spinner instead of dropdown for zoom
+ levels; thanks to PJ
+ - Set of javadoc, style, and other small fixes
+
+
+Version 1.4.0 (18 Mar 2010)
+ - Added the possibility for each node having multiple interfaces
+ * Requires changes to the configuration files, see default_settings.txt
+ - New/improved routing algorithms
+ * added parametrization for MaxProp (default alpha=1)
+ * added Prophet and Maxprop routing algorithm versions that
+ take timescale as a parameter, and estimate the needed routing algorithm
+ parameters based on that
+ * see Karvo and Ott, Time Scales and Delay-Tolerant Routing Protocols,
+ CHANTS 2008, for more information.
+ * added new (unrealistic) EpidemicOracleRouter that transfers messages
+ immediately and deletes all replicas from buffers when the message is
+ delivered
+ * added maximum meeting probability set size support for MaxProp to improve
+ its performance in scenarios with many nodes
+ - Added MessageReport class for reporting message deliveries,
+ CreatedMessagesReport for message creations and EventLogReport for
+ reporting everything (in a StandardEventsReader-compatible format)
+ - Added application layer
+ * applications can be created by extending the Application class
+ * multiple applications can run in the nodes
+ * report modules can register for application events
+ * see PingApplication and PingAppReporter for an example
+ - Added ClusterMovement for creating clusters of nodes and LinearFormation
+ for lines of nodes
+ - ExternalMovementReader supports comment lines (starting with "#")
+ - "Delete all" message event and support for this in StandardEventsReader
+ - Possibility to choose first route stop for MapRouteMovement
+ - Added new message event generators: OneFromEachMessageGenerator and
+ OneToEachMessageGenerator
+ - Added time range setting to MessageEventGenerator
+ - GUI improvements
+ * highlighting of pause-events to EventLogPanel
+ * GUI starts paused by default
+ * hh:mm:ss display for simulation time (right-click the simulation time)
+ - Improved and new analysis scripts
+ * added "log", "total", and "index" options for the ccdfPlotter.pl
+ * added getStatsAverages.pl
+ - Bugfixes
+ * host range checking in MessageEventGenerator
+ * command line option -b doesn't require range anymore
+
+
+
+Version 1.3.0 (19 Jan 2009)
+- New Features
+ - ModuleCommunicationBus for sharing information between different
+ (types of) modules
+ - EnergyAwareRouter demonstrating energy awareness possibilities and use of
+ the ModuleCommunicationBus
+ - EnergyLevelReport for reporting the energy levels
+ - ConnectivityONEReport class for generating connectivity traces
+ that can be read using the StandardEventsReader
+- Enhancements
+ - Any number of input config files supported
+ - Batch mode supports run index ranges (can start from any index)
+ - small change in the command line syntax; see README for details
+ - MessageEventGenerator supports message creation time and destination
+ host ranges
+ - NetworkLayer has configurable scanning intervals
+ - ExternalEventsQueue can be configured like all the other event
+ generators (though the old way is still supported too)
+ - ccdfPlotter script has better help and can now also create CDFs
+- New toolkit scripts
+ - messageLocationAnimator for creating GIF animations out of
+ MessageLocation reports
+ - dieselNetConverter for converting DieselNet traces into ONE
+ mobility traces
+ - getAverages for counting averages out of different time-stamped reports
+ - splotEnergy for creating 3D plots from EnergyLevel reports
+- Fixed bugs in
+ - handling of incoming messages with expired TTL
+ - report directory creation; thanks to STARpio
+ - BusTravellerMovement incState; thanks to Mehedi Bakht
+ - MaxProp calcTreshold; thanks to Vasco Soares and STARpio
+
+
+Version 1.2.0 (25 Aug 2008)
+- New movement model (framework): Working Day Movement
+ - see WDM_conf_help.txt for configuration help
+ - sample configuration files can be found from the wdm_settings folder
+ - for information about the model, see our paper at
+ http://www.netlab.tkk.fi/tutkimus/distance/papers/
+ 2008-mobmod-working-day-model.pdf
+- A "stationary movement model" StationaryMovement.
+ - useful for running simulations with only connectivity trace input
+ - createCircles.pl script for easily creating suitable configuration
+ files for this movement model
+
+
+Version 1.1.0 (6 May 2008)
+- External Events Interface which allows event generator classes that
+ can generate external events (such as creating new messages or
+ setting up and tearing down connections). See EventQueueHandler
+ class for details.
+ - due to the EEI, some API changes (in e.g.,
+ createNewMessage method)
+ - external events file feature is now part of the new interface
+ - MessageEventGenerator class for generating uniformly
+ distributed message creation patterns
+ - new event: ConnectionEvent (supported by StandardEventsReader)
+- Configurable message queue modes (random and FIFO)
+- Option to automatically delete messages that are already delivered
+ to the final recipient
+- Small change in the ordering of checks whether transfer has
+ already succeeded when the connection has gone down
+- Connection class has now getTransferDoneTime method
+- Settings class can validate range settings (assertValidRange)
+- Classes that need to reset static fields between batch runs can
+ register to the "resetting service" at DTNSim class
+ (registerForReset)
+- Experimental "update scheduling" functionality that can be used to
+ dynamically insert "update points" between time steps for higher
+ precision simulations
+- DTN2 connectivity (requires JDK 6 or higher)
+- Generic property adding feature for Message class (addProperty,
+ getProperty and updateProperty)
+ - SprayAndWait router uses this now for the copy count
+- New tests
+
+
+Version 1.0.1 (24 February 2008)
+- New warm up feature for the report modules that allows ignoring
+ events and messages that were created during a configurable warm
+ up time.
+- New routing module: First Contact
+
+
+Version 1.0.0 (27 November 2007)
+- First official public release
diff --git a/LICENSE.txt b/LICENSE.txt
index b03cc8a8b..77b0aee29 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,628 +1,628 @@
-This program (the ONE) is released under the GPLv3 (see details below).
-The included vector map data of the downtown Helsinki area is not GPL'ed
-and it should be used only with the ONE simulator
-(Copyright: Maanmittauslaitos, 2007).
-
-------------------------------------------------------------------------
-
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users. We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors. You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights. Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received. You must make sure that they, too, receive
-or can get the source code. And you must show them these terms so they
-know their rights.
-
- Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
- For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software. For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
- Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so. This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software. The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable. Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products. If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
- Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary. To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Use with the GNU Affero General Public License.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
+This program (the ONE) is released under the GPLv3 (see details below).
+The included vector map data of the downtown Helsinki area is not GPL'ed
+and it should be used only with the ONE simulator
+(Copyright: Maanmittauslaitos, 2007).
+
+------------------------------------------------------------------------
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
diff --git a/README.txt b/README.txt
index 900dd4354..1716269a7 100644
--- a/README.txt
+++ b/README.txt
@@ -1,723 +1,723 @@
-The ONE v1.6.0 - Readme
-=======================
-
-The ONE is a Opportunistic Network Environment simulator which provides a
-powerful tool for generating mobility traces, running DTN messaging
-simulations with different routing protocols, and visualizing both
-simulations interactively in real-time and results after their completion.
-
-
-Quick start
-===========
-
-Compiling
----------
-
-You can compile ONE from the source code using the included compile.bat
-script. That should work both in Windows and Unix/Linux environment with
-Java 6 JDK or later.
-
-If you want to use Eclipse for compiling the ONE, since version 1.1.0 you need
-to include some jar libraries in the project's build path. The libraries are
-located in the lib folder. To include them in Eclipse, assuming that you have
-an Eclipse Java project whose root folder is the folder where you extracted
-the ONE, do the following:
-
-select from menus: Project -> Properties -> Java Build Path
-Go to "Libraries" tab
-Click "Add JARs..."
-Select "DTNConsoleConnection.jar" under the "lib" folder
-Add the "ECLA.jar" the same way
-Press "OK".
-
-Now Eclipse should be able to compile the ONE without warnings.
-
-
-Running
--------
-
-ONE can be started using the included one.bat (for Windows) or one.sh (for
-Linux/Unix) script. Following examples assume you're using the Linux/Unix
-script (just replace "./one.sh" with "one.bat" for Windows).
-
-Synopsis:
-./one.sh [-b runcount] [conf-files]
-
-Options:
- -b Run simulation in batch mode. Doesn't start GUI but prints
-information about the progress to terminal. The option must be followed
-by the number of runs to perform in the batch mode or by a range of runs
-to perform, delimited with a colon (e.g, value 2:4 would perform runs 2,
-3 and 4). See section "Run indexing" for more information.
-
-Parameters:
- conf-files: The configuration file names where simulation parameters
-are read from. Any number of configuration files can be defined and they are
-read in the order given in the command line. Values in the later config files
-override values in earlier config files.
-
-
-Configuring
-===========
-
-All simulation parameters are given using configuration files. These files
-are normal text files that contain key-value pairs. Syntax for most of the
-variables is:
-Namespace.key = value
-
-I.e., the key is (usually) prefixed by a namespace, followed by a dot, and
-then key name. Key and value are separated by equals-sign. Namespaces
-start with capital letter and both namespace and keys are written in
-CamelCase (and are case sensitive). Namespace defines (loosely) the part
-of the simulation environment where the setting has effect on. Many, but
-not all, namespaces are equal to the class name where they are read.
-Especially movement models, report modules and routing modules follow this
-convention. In some cases the namespace is defined by the user: e.g., with
-network interfaces user can pick up any idenfitier, define interface specific
-settings in that namespace, and give the name of the namespace when
-configuring which interface each group should use.
-
-Numeric values use '.' as the decimal separator and can be suffixed with
-kilo (k) mega (M) or giga (G) suffix. Boolean settings accept "true",
-"false", "0", and "1" as values.
-
-Many settings define paths to external data files. The paths can be relative
-or absolute but the directory separator must be '/' in both Unix and Windows
-environment.
-
-Some variables contain comma-separated values, and for them the syntax is:
-Namespace.key = value1, value2, value3, etc.
-
-For run-indexed values the syntax is:
-Namespace.key = [run1value; run2value; run3value; etc]
-I.e., all values are given in brackets and values for different run are
-separated by semicolon. Each value can also be a comma-separated value.
-For more information about run indexing, go to section "Run indexing".
-
-Setting files can contain comments too. A comment line must start with "#"
-character. Rest of the line is skipped when the settings are read. This can
-be also useful for disabling settings easily.
-
-Some values (scenario and report names at the moment) support "value
-filling". With this feature, you can construct e.g., scenario name
-dynamically from the setting values. This is especially useful when using
-run indexing. Just put setting key names in the value part prefixed and
-suffixed by two percent (%) signs. These placeholders are replaces by the
-current setting value from the configuration file. See the included
-snw_comparison_settings.txt for an example.
-
-File "default_settings.txt", if exists, is always read and the other
-configuration files given as parameter can define more settings or override
-some (or even all) settings in the previous files. The idea is that
-you can define in the earlier files all the settings that are common for
-all the simulations and run different, specific, simulations using
-different configuration files.
-
-
-Run indexing
-------------
-
-Run indexing is a feature that allows you to run large amounts of
-different configurations using only single configuration file. The idea is
-that you provide an array of settings (using the syntax described above)
-for the variables that should be changed between runs. For example, if you
-want to run the simulation using five different random number generator
-seeds for movement models, you can define in the settings file the
-following:
-
-MovementModel.rngSeed = [1; 2; 3; 4; 5]
-
-Now, if you run the simulation using command:
-
-./one.sh -b 5 my_config.txt
-
-you would run first using seed 1 (run index 0), then another run using
-seed 2, etc. Note that you have to run it using batch mode (-b option) if
-you want to use different values. Without the batch mode flag the first
-parameter (if numeric) is the run index to use when running in GUI mode.
-
-Run indexes wrap around: used value is the value at index (runIndex %
-arrayLength). Because of wrapping, you can easily run large amount of
-permutations easily. For example, if you define two key-value pairs:
-
-key1 = [1; 2]
-key2 = [a; b; c]
-
-and run simulation using run-index count 6, you would get all permutations
-of the two values (1,a; 2,b; 1,c; 2,a; 1,b; 2,c). This naturally works
-with any amount of arrays. Just make sure that the smallest common
-nominator of all array sizes is 1 (e.g., use arrays whose sizes are primes)
--- unless you don't want all permutations but some values should be
-paired.
-
-
-Movement models
----------------
-
-Movement models govern the way nodes move in the simulation. They provide
-coordinates, speeds and pause times for the nodes. The basic installation
-contains, e.g., random waypoint, map based movement, shortest path map based
-movement, map route movement, and external movement. All these models, except
-external movement, have configurable speed and pause time distributions. A
-minimum and maximum values can be given and the movement model draws
-uniformly distributed random values that are within the given range. Same
-applies for pause times. In external movement model the speeds and pause
-times are interpreted from the given data.
-
-When a node uses the random waypoint movement model (RandomWaypoint), it is
-given a random coordinate in the simulation area. Node moves directly to the
-given destination at constant speed, pauses for a while, and then gets a new
-destination. This continues throughout the simulations and nodes move along
-these zig-zag paths.
-
-Map-based movement models constrain the node movement to predefined paths.
-Different types of paths can be defined and one can define valid paths for
-all node groups. This way e.g., cars can be prevented from driving indoors or
-on pedestrian paths.
-
-The basic map-based movement model (MapBasedMovement) initially distributes
-the nodes between any two adjacent (i.e., connected by a path) map nodes and
-then nodes start moving from adjacent map node to another. When node reaches
-the next map node, it randomly selects the next adjacent map node but chooses
-the map node where it came from only if that is the only option (i.e., avoids
-going back to where it came from). Once node has moved trough 10-100 map
-nodes, it pauses for a while and then starts moving again.
-
-The more sophisticated version of the map-based movement model
-(ShortestPathMapBasedMovement) uses Dijkstra's shortest path algorithm to
-find its way trough the map area. Once a node reaches its destination, and
-has waited for the pause time, a new random map node is chosen and node moves
-there using the shortest path that can be taken using only valid map nodes.
-
-For the shortest path based movement models, map data can also contain Points
-Of Interest (POIs). Instead of selecting any random map node for the next
-destination, the movement model can be configured to give a POI belonging to
-a certain POI group with a configurable probability. There can be unlimited
-amount of POI groups and all groups can contain any amount of POIs. All node
-groups can have different probabilities for all POI groups. POIs can be used
-to model e.g., shops, restaurants and tourist attractions.
-
-Route based movement model (MapRouteMovement) can be used to model nodes that
-follow certain routes, e.g. bus or tram lines. Only the stops on the route
-have to be defined and then the nodes using that route move from stop to stop
-using shortest paths and stop on the stops for the configured time.
-
-All movement models can also decide when the node is active (moves and can be
-connected to) and when not. For all models, except for the external movement,
-multiple simulation time intervals can be given and the nodes in that group
-will be active only during those times.
-
-All map-based models get their input data using files formatted with a subset
-of the Well Known Text (WKT) format. LINESTRING and MULTILINESTRING
-directives of WKT files are supported by the parser for map path data. For
-point data (e.g. for POIs), also the POINT directive is supported. Adjacent
-nodes in a (MULTI)LINESTRING are considered to form a path and if some lines
-contain some vertex(es) with exactly the same coordinates, the paths are
-joined from those places (this is how you create intersections). WKT files
-can be edited and generated from real world map data using any suitable
-Geographic Information System (GIS) program. The map data included in the
-simulator distribution was converted and edited using the free, Java based
-OpenJUMP GIS program.
-
-Different map types are defined by storing the paths belonging to different
-types to different files. Points Of Interest are simply defined with WKT
-POINT directive and POI groups are defined by storing all POIs belonging to a
-certain group in the same file. All POIs must also be part of the map data so
-they are accessible using the paths. Stops for the routes are defined with
-LINESTRING and the stops are traversed in the same order they appear in the
-LINESTRING. One WKT file can contain multiple routes and they are given to
-nodes in the same order as they appear in the file.
-
-The experimental movement model that uses external movement data
-(ExternalMovement) reads timestamped node locations from a file and moves the
-nodes in the simulation accordingly. See javadocs of ExternalMovementReader
-class from input package for details of the format. A suitable, experimental
-converter script (transimsParser.pl) for TRANSIMS data is included in the
-toolkit folder.
-
-The movement model to use is defined per node group with the "movementModel"
-setting. Value of the setting must be a valid movement model class name from
-the movement package. Settings that are common for all movement models are
-read in the MovementModel class and movement model specific settings are read
-in the respective classes. See the javadoc documentation and example
-configuration files for details.
-
-Routing modules and message creation
-------------------------------------
-
-Routing modules define how the messages are handled in the simulation. Six
-basic active routing modules (First Contact, Epidemic, Spray and Wait, Direct
-delivery, PRoPHET and MaxProp) and also a passive router for external routing
-simulation are included in the package. The active routing modules are
-implementations of the well known routing algorithms for DTN routing. There
-are also variants of these models and couple of different models included in
-the latest versions. See the classes in the routing package for details.
-
-Passive router is made especially for interacting with other (DTN) routing
-simulators or running simulations that don't need any routing functionality.
-The router doesn't do anything unless commanded by external events. These
-external events are provided to the simulator by a class that implements the
-EventQueue interface.
-
-There are two basic classes that can be used as a source of message events:
-ExternalEventsQueue and MessageEventGenerator. The former can read events
-from a file that can be created by hand, with a suitable script (e.g.,
-createCreates.pl script in the toolkit folder), or by converting e.g.,
-dtnsim2's output to suitable form. See StandardEventsReader class from input
-package for details of the format. MessageEventGenerator is a simple message
-generator class that creates uniformly distributed message creation patterns
-with configurable message creation interval, message size and
-source/destination host ranges. More specific messaging scenarios can be
-created with MessageBurstGenerator, and One{From,To}EachMessageGenerator
-classes. See javadocs for details.
-
-The toolkit folder contains an experimental parser script (dtnsim2parser.pl)
-for dtnsim2's output (there used to be a more capable Java-based parser but
-it was discarded in favor of this more easily extendable script). The script
-requires a few patches to dtnsim2's code and those can be found from the
-toolkit/dtnsim2patches folder.
-
-The routing module to use is defined per node group with the setting
-"router". All routers can't interact properly (e.g., PRoPHET router can only
-work with other PRoPHET routers) so usually it makes sense to use the same
-(or compatible) router for all groups.
-
-Reports
--------
-
-Reports can be used to create summary data of simulation runs, detailed data
-of connections and messages, files suitable for post-processing using e.g.,
-Graphviz (to create graphs) and also to interface with other programs. See
-javadocs of report-package classes for details.
-
-There can be any number of reports for any simulation run and the number of
-reports to load is defined with "Report.nrofReports" setting. Report class
-names are defined with "Report.reportN" setting, where N is an integer value
-starting from 1. The values of the settings must be valid report class names
-from the report package. The output directory of all reports (which can be
-overridden per report class with the "output" setting) must be defined with
-Report.reportDir -setting. If no "output" setting is given for a report
-class, the resulting report file name is "ReportClassName_ScenarioName.txt".
-
-All reports have many configurable settings which can be defined using
-ReportClassName.settingKey -syntax. See javadocs of Report class and specific
-report classes for details (look for "setting id" definitions).
-
-Host groups
------------
-
-A host group is group of hosts (nodes) that shares movement and routing
-module settings. Different groups can have different values for the settings
-and this way they can represent different types of nodes. Base settings can
-be defined in the "Group" namespace and different node groups can override
-these settings or define new settings in their specific namespaces (Group1,
-Group2, etc.).
-
-The settings
-------------
-
-There are plenty of settings to configure; more than is meaningful to
-present here. See javadocs of especially report, routing and movement
-model classes for details. See also included settings files for examples.
-Perhaps the most important settings are the following.
-
-
-Scenario settings:
----
-
-Scenario.name
-Name of the scenario. All report files are by default prefixed with this.
-
-Scenario.simulateConnections
-Should connections be simulated. If you're only interested in movement
-modeling, you can disable this to get faster simulation. Usually you want
-this to be on.
-
-Scenario.updateInterval
-How many seconds are stepped on every update. Increase this to get faster
-simulation, but then you'll lose some precision. Values from 0.1 to 2 are good
-for simulations.
-
-Scenario.endTime
-How many simulated seconds to simulate.
-
-Scenario.nrofHostGroups
-How many hosts group are present in the simulation.
-
-
-Interface settings (used to define the possible interfaces the nodes can have)
----
-
-type
-What class (from the interfaces-directory) is used for this interface
-
-The remaining settings are class-specific. Can be for example:
-
-transmitRange
-Range (meters) of the interface.
-
-transmitSpeed
-Transmit speed of the interface (bytes per second).
-
-
-Host group settings (used in Group or GroupN namespace):
----
-
-groupID
-Group's identifier (a string or a character). Used as the prefix of host
-names that are shown in the GUI and reports. Host's full name is
-groupID+networkAddress.
-
-nrofHosts
-Number of hosts in this group.
-
-nrofInterfaces
-Number of interfaces this the nodes of this group use
-
-interfaceX
-The interface that should be used as the interface number X
-
-movementModel
-The movement model all hosts in the group use. Must be a valid class (one
-that is a subclass of MovementModel class) name from the movement package.
-
-waitTime
-Minimum and maximum (two comma-separated decimal values) of the wait time
-interval (seconds). Defines how long nodes should stay in the same place
-after reaching the destination of the current path. A new random value within
-the interval is used on every stop. Default value is 0,0.
-
-speed
-Minimum and maximum (two comma-separated decimal values) of the speed
-interval (m/s). Defines how fast nodes move. A new random value is used on
-every new path. Default value is 1,1.
-
-bufferSize
-Size of the nodes' message buffer (bytes). When the buffer is full, node can't
-accept any more messages unless it drops some old messages from the buffer.
-
-router
-Router module which is used to route messages. Must be a valid class
-(subclass of MessageRouter class) name from routing package.
-
-activeTimes
-Time intervals (comma-separated simulated time value tuples: start1, end1,
-start2, end2, ...) when the nodes in the group should be active. If no
-intervals are defined, nodes are active all the time.
-
-msgTtl
-Time To Live (simulated minutes) of the messages created by this host group.
-Nodes (with active routing module) check every one minute whether some of
-their messages' TTLs have expired and drop such messages. If no TTL is
-defined, infinite TTL is used.
-
-
-Group and movement model specific settings (only meaningful for certain
-movement models):
-
-pois
-Points Of Interest indexes and probabilities (comma-separated
-index-probability tuples: poiIndex1, poiProb1, poiIndex2, poiProb2, ... ).
-Indexes are integers and probabilities are decimal values in the range of
-0.0-1.0. Setting defines the POI groups where the nodes in this host group
-can choose destinations from and the probabilities for choosing a certain POI
-group. For example, a (random) POI from the group defined in the POI file1
-(defined with PointsOfInterest.poiFile1 setting) is chosen with the
-probability poiProb1. If the sum of all probabilities is less than 1.0, a
-probability of choosing any random map node for the next destination is (1.0
-- theSumOfProbabilities). Setting can be used only with
-ShortestPathMapBasedMovement -based movement models.
-
-okMaps
-Which map node types (refers to map file indexes) are OK for the group
-(comma-separated list of integers). Nodes will not travel trough map nodes
-that are not OK for them. As default, all map nodes are OK. Setting can be
-used with any MapBasedMovent -based movement model.
-
-routeFile
-If MapRouteMovement movement model is used, this setting defines the route
-file (path) where the route is read from. Route file should contain
-LINESTRING WKT directives. Each vertex in a LINESTRING represents one stop
-on the route.
-
-routeType
-If MapRouteMovement movement model is used, this setting defines the routes
-type. Type can be either circular (value 1) or ping-pong (value 2). See
-movement.map.MapRoute class for details.
-
-
-Movement model settings:
----
-
-MovementModel.rngSeed
-The seed for all movement models' random number generator. If the seed and
-all the movement model related settings are kept the same, all nodes should
-move the same way in different simulations (same destinations and speed &
-wait time values are used).
-
-MovementModel.worldSize
-Size of the simulation world in meters (two comma separated values:
-width, height).
-
-PointsOfInterest.poiFileN
-For ShortestPathMapBasedMovement -based movement models, this setting defines
-the WKT files where the POI coordinates are read from. POI coordinates are
-defined using the POINT WKT directive. The "N" in the end of the setting must
-be a positive integer (i.e., poiFile1, poiFile2, ...).
-
-MapBasedMovement.nrofMapFiles
-How many map file settings to look for in the settings file.
-
-MapBasedMovement.mapFileN
-Path to the Nth map file ("N" must be a positive integer). There must be at
-least nrofMapFiles separate files defined in the configuration files(s). All
-map files must be WKT files with LINESTRING and/or MULTILINESTRING WKT
-directives. Map files can contain POINT directives too, but those are
-skipped. This way the same file(s) can be used for both POI and map data. By
-default the map coordinates are translated so that the upper left corner of
-the map is at coordinate point (0,0). Y-coordinates are mirrored before
-translation so that the map's north points up in the playfield view. Also all
-POI and route files are translated to match to the map data transformation.
-
-
-Report settings:
----
-
-Report.nrofReports
-How many report modules to load. Module names are defined with settings
-"Report.report1", "Report.report2", etc. Following report settings can be
-defined for all reports (using Report name space) or just for certain reports
-(using ReportN name spaces).
-
-Report.reportDir
-Where to store the report output files. Can be absolute path or relative to
-the path where the simulation was started. If the directory doesn't exists,
-it is created.
-
-Report.warmup
-Length of the warm up period (simulated seconds from the start). During the
-warm up the report modules should discard the new events. The behavior is
-report module specific so check the (java)documentation of different report
-modules for details.
-
-
-Event generator settings:
----
-
-Events.nrof
-How many event generators are loaded for the simulation. Event generator
-specific settings (see below) are defined in EventsN namespaces (so
-Events1.settingName configures a setting for the 1st event generator etc.).
-
-EventsN.class
-Name of the generator class to load (e.g., ExternalEventsQueue or
-MessageEventGenerator). The class must be found from the input package.
-
-For the ExternalEventsQueue you must at least define the path to the external
-events file (using setting "filePath"). See input.StandardEventsReader class'
-javadocs for information about different external events.
-
-
-Other settings:
----
-
-Optimization.randomizeUpdateOrder
-Should the order in which the nodes' update method is called be randomized.
-Call to update causes the nodes to check their connections and also update
-their routing module. If set to false, node update order is the same as their
-network address order. With randomizing, the order is different on every time
-step.
-
-Optimization.cellSizeMult
-Adjust the trade-off between memory consumption and simulation speed.
-Especially useful for large maps. See ConnectivityOptimizer class for details.
-
-
-GUI
-===
-
-The GUI's main window is divided into three parts. The main part contains
-the playfield view (where node movement is displayed) and simulation and
-GUI control and information. The right part is used to select nodes and
-the lower part is for logging and breakpoints.
-
-The main part's topmost section is for simulation and GUI controls. The
-first field shows the current simulation time. Next field shows the
-simulation speed (simulated seconds per second). The following four
-buttons are used to pause, step, fast forward, and fast forward simulation
-to given time. Pressing step-button multiple times runs simulation
-step-by-step. Fast forward (FFW) can be used to skip uninteresting parts
-of simulation. In FFW, the GUI update speed is set to a large value. Next
-drop-down is used to control GUI update speed. Speed 1 means that GUI is
-updated on every simulated second. Speed 10 means that GUI is updated only
-on every 10th second etc. Negative values slow down the simulation. The
-following drop-down controls the zoom factor. The last button saves the
-current view as a png-image.
-
-Middle section, i.e., the playfield view, shows the node placement, map
-paths, node identifiers, connections among nodes etc. All nodes are
-displayed as small rectangles and their radio range is shown as a green
-circle around the node. Node's group identifier and network address (a
-number) are shown next to each node. If a node is carrying messages, each
-message is represented by a green or blue filled rectangle. If node
-carries more than 10 messages, another column of rectangles is drawn for
-each 10 messages but every other rectangle is now red. You can center the
-view to any place by clicking with mouse button on the play field. Zoom
-factor can also be changed using mouse wheel on top of the playfield view.
-
-The right part of main window is for choosing a node for closer inspection.
-Simply clicking a button shows the node info in main parts lower section.
-From there more information can be displayed by selecting one of the
-messages the node is carrying (if any) from the drop-down menu. Pressing
-the "routing info" button opens a new window where information about the
-routing module is displayed. When a node is chosen, the playfield view is
-also centered on that node and the current path the node is traveling is
-shown in red.
-
-Logging (the lowest part) if divided to two sections, control and log. From
-the control part you can select what kind of messages are shown in the
-log. You can also define if simulation should be paused on certain type of
-event (using the check boxes in the "pause" column). Log part displays time
-stamped events. All nodes and message names in the log messages are
-buttons and you can get more information about them by clicking the
-buttons.
-
-
-DTN2 Reference Implementation Connectivity
-==========================================
-
-DTN2 connectivity allows bundles to be passed between the ONE and any
-number of DTN2 routers. This is done through DTN2's External Convergence
-Layer Interface.
-
-When DTN2 connectivity is enabled ONE will connect to dtnd routers as
-an external convergence layer adapter. ONE will also automatically configure
-dtnd through a console connection with a link and route for bundles to reach
-the simulator.
-
-When a bundle is received from dtnd, ONE attempts to match the destination EID
-against the regular expressions configured in the configuration file (see DTN2
-Connectivity Configuration File below). For each matching node a copy of a
-message is created and routed inside ONE. When the bundle reaches its destination
-inside ONE it is delivered to the dtnd router instance attached to the node.
-Copies of the bundle payload are stored within 'bundles' directory.
-
-To enable this functionality the following steps must be taken:
-
-1) DTN2 must be compiled and configured with ECL support enabled.
-2) DTN2Events event generator must be configured to be loaded into ONE
- as an events class.
-3) DTN2Reporter must be configured and loaded into one as a report class.
-4) DTN2 connectivity configuration file must be configured as DTN2.configFile
-
-To start the simulation:
-1) Start all the dtnd router instances.
-2) Start ONE.
-
-Example Configuration (2-4 above)
----------------------------------
-
-Events.nrof = 1
-Events1.class = DTN2Events
-Report.nrofReports = 1
-Report.report1 = DTN2Reporter
-DTN2.configFile = cla.conf
-
-DTN2 Connectivity Configuration File
-------------------------------------
-
-The DTN2 connectivity configuration file defines which nodes inside ONE
-should connect to which DTN2 router instances. It also defines the EID's
-that the nodes match.
-
-The configuration file is composed of comment lines starting with # and
-configuration lines with the following format:
-
-
-
-The fields have the following meaning:
-
-nodeID: The ID of a node inside ONE (integer >= 0)
-EID regexp: Incoming bundles whose destination EID matches this regexp
- will be forwarded to the node inside ONE.
- (see java.util.regex.Pattern)
-dtnd host: Hostname/IP of the dtnd router to connect to this node.
-ECL port: dtnd router's port listening to ECLAs
-console port: dtnd router's console port
-
-Example:
-#
-1 dtn://local-1.dtn/(.*) localhost 8801 5051
-2 dtn://local-2.dtn/(.*) localhost 8802 5052
-
-Known Issues
-------------
-
-For DTN2 connectivity related issues, you can contact teemuk@netlab.tkk.fi
-
--Quitting dtnd router instances connected to ONE will cause ONE to quit.
-
-
-Toolkit
-=======
-
-The simulation package includes a folder called "toolkit" that contains
-scripts for generating input and processing the output of the simulator. All
-(currently included) scripts are written with Perl (http://www.perl.com/) so
-you need to have it installed before running the scripts. Some post processing
-scripts use gnuplot (http://www.gnuplot.info/) for creating graphics. Both of
-the programs are freely available for most of the Unix/Linux and Windows
-environments. For Windows environment, you may need to change the path to the
-executables for some of the scripts.
-
-getStats.pl
-This script can be used to create bar-plots of various statistics gathered by
-the MessageStatsReport -report module. The only mandatory option is "-stat"
-which is used to define the name of the statistics value that should be parsed
-from the report files (e.g., "delivery_prob" for message delivery
-probabilities). Rest of the parameters should be MessageStatsReport output
-filenames (or paths). Script creates three output files: one with values from
-all the files, one with the gnuplot commands used to create the graphics and
-finally an image file containing the graphics. One bar is created to the plot
-for each input file. The title for each bar is parsed from the report filename
-using the regular expression defined with "-label" option. Run getStats.pl
-with "-help" option for more help.
-
-ccdfPlotter.pl
-Script for creating Complementary(/Inverse) Cumulative Distribution Function
-plots (using gluplot) from reports that contain time-hitcount-tuples. Output
-filename must be defined with the "-out" option and rest of the parameters
-should be (suitable) report filenames. "-label" option can be used for
-defining label extracting regular expression (similar to one for the getStats
-script) for the legend.
-
-createCreates.pl
-Message creation pattern for the simulation can be defined with external events
-file. Such a file can be simply created with any text editor but this script
-makes it easier to create a large amount of messages. Mandatory options are
-the number of messages ("-nrof"), time range ("-time"), host address range
-("-hosts") and message size range ("-sizes"). The number of messages is simply
-an integer but the ranges are given with two integers with a colon (:) between
-them. If hosts should reply to the messages that they receive, size range of
-the reply messages can be defined with "-rsizes" option. If a certain random
-number generator seed should be used, that can be defined with "-seed" option.
-All random values are drawn from a uniform distribution with inclusive minimum
-value and exclusive maximum value. Script outputs commands that are suitable
-for external events file's contents. You probably want to redirect the output
-to some file.
-
-dtnsim2parser.pl and transimsParser.pl
-These two (quite experimental) parsers convert data from other programs to a
-form that is suitable for ONE. Both take two parameters: input and output
-file. If these parameters are omitted, stdin and stdout are used for input and
-output. With "-h" option a short help is printed.
-dtnsim2parser converts dtnsim2's (http://watwire.uwaterloo.ca/DTN/sim/) output
-(with verbose mode 8) to an external events file that can be fed to ONE. The
-main idea of this parser is that you can first create a connectivity pattern
-file using ONE and ConnectivityDtnsim2Report, feed that to dtnsim2 and then
-observe the results visually in ONE (using the output converted with
-dtnsim2parser as the external events file).
-transimsParser can convert TRANSIM's (http://transims-opensource.net/) vehicle
-snapshot files to external movement files that can be used as an input for
-node movement. See ExternalMovement and ExternalMovementReader classes for
-more information.
\ No newline at end of file
+The ONE v1.6.0 - Readme
+=======================
+
+The ONE is a Opportunistic Network Environment simulator which provides a
+powerful tool for generating mobility traces, running DTN messaging
+simulations with different routing protocols, and visualizing both
+simulations interactively in real-time and results after their completion.
+
+
+Quick start
+===========
+
+Compiling
+---------
+
+You can compile ONE from the source code using the included compile.bat
+script. That should work both in Windows and Unix/Linux environment with
+Java 6 JDK or later.
+
+If you want to use Eclipse for compiling the ONE, since version 1.1.0 you need
+to include some jar libraries in the project's build path. The libraries are
+located in the lib folder. To include them in Eclipse, assuming that you have
+an Eclipse Java project whose root folder is the folder where you extracted
+the ONE, do the following:
+
+select from menus: Project -> Properties -> Java Build Path
+Go to "Libraries" tab
+Click "Add JARs..."
+Select "DTNConsoleConnection.jar" under the "lib" folder
+Add the "ECLA.jar" the same way
+Press "OK".
+
+Now Eclipse should be able to compile the ONE without warnings.
+
+
+Running
+-------
+
+ONE can be started using the included one.bat (for Windows) or one.sh (for
+Linux/Unix) script. Following examples assume you're using the Linux/Unix
+script (just replace "./one.sh" with "one.bat" for Windows).
+
+Synopsis:
+./one.sh [-b runcount] [conf-files]
+
+Options:
+ -b Run simulation in batch mode. Doesn't start GUI but prints
+information about the progress to terminal. The option must be followed
+by the number of runs to perform in the batch mode or by a range of runs
+to perform, delimited with a colon (e.g, value 2:4 would perform runs 2,
+3 and 4). See section "Run indexing" for more information.
+
+Parameters:
+ conf-files: The configuration file names where simulation parameters
+are read from. Any number of configuration files can be defined and they are
+read in the order given in the command line. Values in the later config files
+override values in earlier config files.
+
+
+Configuring
+===========
+
+All simulation parameters are given using configuration files. These files
+are normal text files that contain key-value pairs. Syntax for most of the
+variables is:
+Namespace.key = value
+
+I.e., the key is (usually) prefixed by a namespace, followed by a dot, and
+then key name. Key and value are separated by equals-sign. Namespaces
+start with capital letter and both namespace and keys are written in
+CamelCase (and are case sensitive). Namespace defines (loosely) the part
+of the simulation environment where the setting has effect on. Many, but
+not all, namespaces are equal to the class name where they are read.
+Especially movement models, report modules and routing modules follow this
+convention. In some cases the namespace is defined by the user: e.g., with
+network interfaces user can pick up any idenfitier, define interface specific
+settings in that namespace, and give the name of the namespace when
+configuring which interface each group should use.
+
+Numeric values use '.' as the decimal separator and can be suffixed with
+kilo (k) mega (M) or giga (G) suffix. Boolean settings accept "true",
+"false", "0", and "1" as values.
+
+Many settings define paths to external data files. The paths can be relative
+or absolute but the directory separator must be '/' in both Unix and Windows
+environment.
+
+Some variables contain comma-separated values, and for them the syntax is:
+Namespace.key = value1, value2, value3, etc.
+
+For run-indexed values the syntax is:
+Namespace.key = [run1value; run2value; run3value; etc]
+I.e., all values are given in brackets and values for different run are
+separated by semicolon. Each value can also be a comma-separated value.
+For more information about run indexing, go to section "Run indexing".
+
+Setting files can contain comments too. A comment line must start with "#"
+character. Rest of the line is skipped when the settings are read. This can
+be also useful for disabling settings easily.
+
+Some values (scenario and report names at the moment) support "value
+filling". With this feature, you can construct e.g., scenario name
+dynamically from the setting values. This is especially useful when using
+run indexing. Just put setting key names in the value part prefixed and
+suffixed by two percent (%) signs. These placeholders are replaces by the
+current setting value from the configuration file. See the included
+snw_comparison_settings.txt for an example.
+
+File "default_settings.txt", if exists, is always read and the other
+configuration files given as parameter can define more settings or override
+some (or even all) settings in the previous files. The idea is that
+you can define in the earlier files all the settings that are common for
+all the simulations and run different, specific, simulations using
+different configuration files.
+
+
+Run indexing
+------------
+
+Run indexing is a feature that allows you to run large amounts of
+different configurations using only single configuration file. The idea is
+that you provide an array of settings (using the syntax described above)
+for the variables that should be changed between runs. For example, if you
+want to run the simulation using five different random number generator
+seeds for movement models, you can define in the settings file the
+following:
+
+MovementModel.rngSeed = [1; 2; 3; 4; 5]
+
+Now, if you run the simulation using command:
+
+./one.sh -b 5 my_config.txt
+
+you would run first using seed 1 (run index 0), then another run using
+seed 2, etc. Note that you have to run it using batch mode (-b option) if
+you want to use different values. Without the batch mode flag the first
+parameter (if numeric) is the run index to use when running in GUI mode.
+
+Run indexes wrap around: used value is the value at index (runIndex %
+arrayLength). Because of wrapping, you can easily run large amount of
+permutations easily. For example, if you define two key-value pairs:
+
+key1 = [1; 2]
+key2 = [a; b; c]
+
+and run simulation using run-index count 6, you would get all permutations
+of the two values (1,a; 2,b; 1,c; 2,a; 1,b; 2,c). This naturally works
+with any amount of arrays. Just make sure that the smallest common
+nominator of all array sizes is 1 (e.g., use arrays whose sizes are primes)
+-- unless you don't want all permutations but some values should be
+paired.
+
+
+Movement models
+---------------
+
+Movement models govern the way nodes move in the simulation. They provide
+coordinates, speeds and pause times for the nodes. The basic installation
+contains, e.g., random waypoint, map based movement, shortest path map based
+movement, map route movement, and external movement. All these models, except
+external movement, have configurable speed and pause time distributions. A
+minimum and maximum values can be given and the movement model draws
+uniformly distributed random values that are within the given range. Same
+applies for pause times. In external movement model the speeds and pause
+times are interpreted from the given data.
+
+When a node uses the random waypoint movement model (RandomWaypoint), it is
+given a random coordinate in the simulation area. Node moves directly to the
+given destination at constant speed, pauses for a while, and then gets a new
+destination. This continues throughout the simulations and nodes move along
+these zig-zag paths.
+
+Map-based movement models constrain the node movement to predefined paths.
+Different types of paths can be defined and one can define valid paths for
+all node groups. This way e.g., cars can be prevented from driving indoors or
+on pedestrian paths.
+
+The basic map-based movement model (MapBasedMovement) initially distributes
+the nodes between any two adjacent (i.e., connected by a path) map nodes and
+then nodes start moving from adjacent map node to another. When node reaches
+the next map node, it randomly selects the next adjacent map node but chooses
+the map node where it came from only if that is the only option (i.e., avoids
+going back to where it came from). Once node has moved trough 10-100 map
+nodes, it pauses for a while and then starts moving again.
+
+The more sophisticated version of the map-based movement model
+(ShortestPathMapBasedMovement) uses Dijkstra's shortest path algorithm to
+find its way trough the map area. Once a node reaches its destination, and
+has waited for the pause time, a new random map node is chosen and node moves
+there using the shortest path that can be taken using only valid map nodes.
+
+For the shortest path based movement models, map data can also contain Points
+Of Interest (POIs). Instead of selecting any random map node for the next
+destination, the movement model can be configured to give a POI belonging to
+a certain POI group with a configurable probability. There can be unlimited
+amount of POI groups and all groups can contain any amount of POIs. All node
+groups can have different probabilities for all POI groups. POIs can be used
+to model e.g., shops, restaurants and tourist attractions.
+
+Route based movement model (MapRouteMovement) can be used to model nodes that
+follow certain routes, e.g. bus or tram lines. Only the stops on the route
+have to be defined and then the nodes using that route move from stop to stop
+using shortest paths and stop on the stops for the configured time.
+
+All movement models can also decide when the node is active (moves and can be
+connected to) and when not. For all models, except for the external movement,
+multiple simulation time intervals can be given and the nodes in that group
+will be active only during those times.
+
+All map-based models get their input data using files formatted with a subset
+of the Well Known Text (WKT) format. LINESTRING and MULTILINESTRING
+directives of WKT files are supported by the parser for map path data. For
+point data (e.g. for POIs), also the POINT directive is supported. Adjacent
+nodes in a (MULTI)LINESTRING are considered to form a path and if some lines
+contain some vertex(es) with exactly the same coordinates, the paths are
+joined from those places (this is how you create intersections). WKT files
+can be edited and generated from real world map data using any suitable
+Geographic Information System (GIS) program. The map data included in the
+simulator distribution was converted and edited using the free, Java based
+OpenJUMP GIS program.
+
+Different map types are defined by storing the paths belonging to different
+types to different files. Points Of Interest are simply defined with WKT
+POINT directive and POI groups are defined by storing all POIs belonging to a
+certain group in the same file. All POIs must also be part of the map data so
+they are accessible using the paths. Stops for the routes are defined with
+LINESTRING and the stops are traversed in the same order they appear in the
+LINESTRING. One WKT file can contain multiple routes and they are given to
+nodes in the same order as they appear in the file.
+
+The experimental movement model that uses external movement data
+(ExternalMovement) reads timestamped node locations from a file and moves the
+nodes in the simulation accordingly. See javadocs of ExternalMovementReader
+class from input package for details of the format. A suitable, experimental
+converter script (transimsParser.pl) for TRANSIMS data is included in the
+toolkit folder.
+
+The movement model to use is defined per node group with the "movementModel"
+setting. Value of the setting must be a valid movement model class name from
+the movement package. Settings that are common for all movement models are
+read in the MovementModel class and movement model specific settings are read
+in the respective classes. See the javadoc documentation and example
+configuration files for details.
+
+Routing modules and message creation
+------------------------------------
+
+Routing modules define how the messages are handled in the simulation. Six
+basic active routing modules (First Contact, Epidemic, Spray and Wait, Direct
+delivery, PRoPHET and MaxProp) and also a passive router for external routing
+simulation are included in the package. The active routing modules are
+implementations of the well known routing algorithms for DTN routing. There
+are also variants of these models and couple of different models included in
+the latest versions. See the classes in the routing package for details.
+
+Passive router is made especially for interacting with other (DTN) routing
+simulators or running simulations that don't need any routing functionality.
+The router doesn't do anything unless commanded by external events. These
+external events are provided to the simulator by a class that implements the
+EventQueue interface.
+
+There are two basic classes that can be used as a source of message events:
+ExternalEventsQueue and MessageEventGenerator. The former can read events
+from a file that can be created by hand, with a suitable script (e.g.,
+createCreates.pl script in the toolkit folder), or by converting e.g.,
+dtnsim2's output to suitable form. See StandardEventsReader class from input
+package for details of the format. MessageEventGenerator is a simple message
+generator class that creates uniformly distributed message creation patterns
+with configurable message creation interval, message size and
+source/destination host ranges. More specific messaging scenarios can be
+created with MessageBurstGenerator, and One{From,To}EachMessageGenerator
+classes. See javadocs for details.
+
+The toolkit folder contains an experimental parser script (dtnsim2parser.pl)
+for dtnsim2's output (there used to be a more capable Java-based parser but
+it was discarded in favor of this more easily extendable script). The script
+requires a few patches to dtnsim2's code and those can be found from the
+toolkit/dtnsim2patches folder.
+
+The routing module to use is defined per node group with the setting
+"router". All routers can't interact properly (e.g., PRoPHET router can only
+work with other PRoPHET routers) so usually it makes sense to use the same
+(or compatible) router for all groups.
+
+Reports
+-------
+
+Reports can be used to create summary data of simulation runs, detailed data
+of connections and messages, files suitable for post-processing using e.g.,
+Graphviz (to create graphs) and also to interface with other programs. See
+javadocs of report-package classes for details.
+
+There can be any number of reports for any simulation run and the number of
+reports to load is defined with "Report.nrofReports" setting. Report class
+names are defined with "Report.reportN" setting, where N is an integer value
+starting from 1. The values of the settings must be valid report class names
+from the report package. The output directory of all reports (which can be
+overridden per report class with the "output" setting) must be defined with
+Report.reportDir -setting. If no "output" setting is given for a report
+class, the resulting report file name is "ReportClassName_ScenarioName.txt".
+
+All reports have many configurable settings which can be defined using
+ReportClassName.settingKey -syntax. See javadocs of Report class and specific
+report classes for details (look for "setting id" definitions).
+
+Host groups
+-----------
+
+A host group is group of hosts (nodes) that shares movement and routing
+module settings. Different groups can have different values for the settings
+and this way they can represent different types of nodes. Base settings can
+be defined in the "Group" namespace and different node groups can override
+these settings or define new settings in their specific namespaces (Group1,
+Group2, etc.).
+
+The settings
+------------
+
+There are plenty of settings to configure; more than is meaningful to
+present here. See javadocs of especially report, routing and movement
+model classes for details. See also included settings files for examples.
+Perhaps the most important settings are the following.
+
+
+Scenario settings:
+---
+
+Scenario.name
+Name of the scenario. All report files are by default prefixed with this.
+
+Scenario.simulateConnections
+Should connections be simulated. If you're only interested in movement
+modeling, you can disable this to get faster simulation. Usually you want
+this to be on.
+
+Scenario.updateInterval
+How many seconds are stepped on every update. Increase this to get faster
+simulation, but then you'll lose some precision. Values from 0.1 to 2 are good
+for simulations.
+
+Scenario.endTime
+How many simulated seconds to simulate.
+
+Scenario.nrofHostGroups
+How many hosts group are present in the simulation.
+
+
+Interface settings (used to define the possible interfaces the nodes can have)
+---
+
+type
+What class (from the interfaces-directory) is used for this interface
+
+The remaining settings are class-specific. Can be for example:
+
+transmitRange
+Range (meters) of the interface.
+
+transmitSpeed
+Transmit speed of the interface (bytes per second).
+
+
+Host group settings (used in Group or GroupN namespace):
+---
+
+groupID
+Group's identifier (a string or a character). Used as the prefix of host
+names that are shown in the GUI and reports. Host's full name is
+groupID+networkAddress.
+
+nrofHosts
+Number of hosts in this group.
+
+nrofInterfaces
+Number of interfaces this the nodes of this group use
+
+interfaceX
+The interface that should be used as the interface number X
+
+movementModel
+The movement model all hosts in the group use. Must be a valid class (one
+that is a subclass of MovementModel class) name from the movement package.
+
+waitTime
+Minimum and maximum (two comma-separated decimal values) of the wait time
+interval (seconds). Defines how long nodes should stay in the same place
+after reaching the destination of the current path. A new random value within
+the interval is used on every stop. Default value is 0,0.
+
+speed
+Minimum and maximum (two comma-separated decimal values) of the speed
+interval (m/s). Defines how fast nodes move. A new random value is used on
+every new path. Default value is 1,1.
+
+bufferSize
+Size of the nodes' message buffer (bytes). When the buffer is full, node can't
+accept any more messages unless it drops some old messages from the buffer.
+
+router
+Router module which is used to route messages. Must be a valid class
+(subclass of MessageRouter class) name from routing package.
+
+activeTimes
+Time intervals (comma-separated simulated time value tuples: start1, end1,
+start2, end2, ...) when the nodes in the group should be active. If no
+intervals are defined, nodes are active all the time.
+
+msgTtl
+Time To Live (simulated minutes) of the messages created by this host group.
+Nodes (with active routing module) check every one minute whether some of
+their messages' TTLs have expired and drop such messages. If no TTL is
+defined, infinite TTL is used.
+
+
+Group and movement model specific settings (only meaningful for certain
+movement models):
+
+pois
+Points Of Interest indexes and probabilities (comma-separated
+index-probability tuples: poiIndex1, poiProb1, poiIndex2, poiProb2, ... ).
+Indexes are integers and probabilities are decimal values in the range of
+0.0-1.0. Setting defines the POI groups where the nodes in this host group
+can choose destinations from and the probabilities for choosing a certain POI
+group. For example, a (random) POI from the group defined in the POI file1
+(defined with PointsOfInterest.poiFile1 setting) is chosen with the
+probability poiProb1. If the sum of all probabilities is less than 1.0, a
+probability of choosing any random map node for the next destination is (1.0
+- theSumOfProbabilities). Setting can be used only with
+ShortestPathMapBasedMovement -based movement models.
+
+okMaps
+Which map node types (refers to map file indexes) are OK for the group
+(comma-separated list of integers). Nodes will not travel trough map nodes
+that are not OK for them. As default, all map nodes are OK. Setting can be
+used with any MapBasedMovent -based movement model.
+
+routeFile
+If MapRouteMovement movement model is used, this setting defines the route
+file (path) where the route is read from. Route file should contain
+LINESTRING WKT directives. Each vertex in a LINESTRING represents one stop
+on the route.
+
+routeType
+If MapRouteMovement movement model is used, this setting defines the routes
+type. Type can be either circular (value 1) or ping-pong (value 2). See
+movement.map.MapRoute class for details.
+
+
+Movement model settings:
+---
+
+MovementModel.rngSeed
+The seed for all movement models' random number generator. If the seed and
+all the movement model related settings are kept the same, all nodes should
+move the same way in different simulations (same destinations and speed &
+wait time values are used).
+
+MovementModel.worldSize
+Size of the simulation world in meters (two comma separated values:
+width, height).
+
+PointsOfInterest.poiFileN
+For ShortestPathMapBasedMovement -based movement models, this setting defines
+the WKT files where the POI coordinates are read from. POI coordinates are
+defined using the POINT WKT directive. The "N" in the end of the setting must
+be a positive integer (i.e., poiFile1, poiFile2, ...).
+
+MapBasedMovement.nrofMapFiles
+How many map file settings to look for in the settings file.
+
+MapBasedMovement.mapFileN
+Path to the Nth map file ("N" must be a positive integer). There must be at
+least nrofMapFiles separate files defined in the configuration files(s). All
+map files must be WKT files with LINESTRING and/or MULTILINESTRING WKT
+directives. Map files can contain POINT directives too, but those are
+skipped. This way the same file(s) can be used for both POI and map data. By
+default the map coordinates are translated so that the upper left corner of
+the map is at coordinate point (0,0). Y-coordinates are mirrored before
+translation so that the map's north points up in the playfield view. Also all
+POI and route files are translated to match to the map data transformation.
+
+
+Report settings:
+---
+
+Report.nrofReports
+How many report modules to load. Module names are defined with settings
+"Report.report1", "Report.report2", etc. Following report settings can be
+defined for all reports (using Report name space) or just for certain reports
+(using ReportN name spaces).
+
+Report.reportDir
+Where to store the report output files. Can be absolute path or relative to
+the path where the simulation was started. If the directory doesn't exists,
+it is created.
+
+Report.warmup
+Length of the warm up period (simulated seconds from the start). During the
+warm up the report modules should discard the new events. The behavior is
+report module specific so check the (java)documentation of different report
+modules for details.
+
+
+Event generator settings:
+---
+
+Events.nrof
+How many event generators are loaded for the simulation. Event generator
+specific settings (see below) are defined in EventsN namespaces (so
+Events1.settingName configures a setting for the 1st event generator etc.).
+
+EventsN.class
+Name of the generator class to load (e.g., ExternalEventsQueue or
+MessageEventGenerator). The class must be found from the input package.
+
+For the ExternalEventsQueue you must at least define the path to the external
+events file (using setting "filePath"). See input.StandardEventsReader class'
+javadocs for information about different external events.
+
+
+Other settings:
+---
+
+Optimization.randomizeUpdateOrder
+Should the order in which the nodes' update method is called be randomized.
+Call to update causes the nodes to check their connections and also update
+their routing module. If set to false, node update order is the same as their
+network address order. With randomizing, the order is different on every time
+step.
+
+Optimization.cellSizeMult
+Adjust the trade-off between memory consumption and simulation speed.
+Especially useful for large maps. See ConnectivityOptimizer class for details.
+
+
+GUI
+===
+
+The GUI's main window is divided into three parts. The main part contains
+the playfield view (where node movement is displayed) and simulation and
+GUI control and information. The right part is used to select nodes and
+the lower part is for logging and breakpoints.
+
+The main part's topmost section is for simulation and GUI controls. The
+first field shows the current simulation time. Next field shows the
+simulation speed (simulated seconds per second). The following four
+buttons are used to pause, step, fast forward, and fast forward simulation
+to given time. Pressing step-button multiple times runs simulation
+step-by-step. Fast forward (FFW) can be used to skip uninteresting parts
+of simulation. In FFW, the GUI update speed is set to a large value. Next
+drop-down is used to control GUI update speed. Speed 1 means that GUI is
+updated on every simulated second. Speed 10 means that GUI is updated only
+on every 10th second etc. Negative values slow down the simulation. The
+following drop-down controls the zoom factor. The last button saves the
+current view as a png-image.
+
+Middle section, i.e., the playfield view, shows the node placement, map
+paths, node identifiers, connections among nodes etc. All nodes are
+displayed as small rectangles and their radio range is shown as a green
+circle around the node. Node's group identifier and network address (a
+number) are shown next to each node. If a node is carrying messages, each
+message is represented by a green or blue filled rectangle. If node
+carries more than 10 messages, another column of rectangles is drawn for
+each 10 messages but every other rectangle is now red. You can center the
+view to any place by clicking with mouse button on the play field. Zoom
+factor can also be changed using mouse wheel on top of the playfield view.
+
+The right part of main window is for choosing a node for closer inspection.
+Simply clicking a button shows the node info in main parts lower section.
+From there more information can be displayed by selecting one of the
+messages the node is carrying (if any) from the drop-down menu. Pressing
+the "routing info" button opens a new window where information about the
+routing module is displayed. When a node is chosen, the playfield view is
+also centered on that node and the current path the node is traveling is
+shown in red.
+
+Logging (the lowest part) if divided to two sections, control and log. From
+the control part you can select what kind of messages are shown in the
+log. You can also define if simulation should be paused on certain type of
+event (using the check boxes in the "pause" column). Log part displays time
+stamped events. All nodes and message names in the log messages are
+buttons and you can get more information about them by clicking the
+buttons.
+
+
+DTN2 Reference Implementation Connectivity
+==========================================
+
+DTN2 connectivity allows bundles to be passed between the ONE and any
+number of DTN2 routers. This is done through DTN2's External Convergence
+Layer Interface.
+
+When DTN2 connectivity is enabled ONE will connect to dtnd routers as
+an external convergence layer adapter. ONE will also automatically configure
+dtnd through a console connection with a link and route for bundles to reach
+the simulator.
+
+When a bundle is received from dtnd, ONE attempts to match the destination EID
+against the regular expressions configured in the configuration file (see DTN2
+Connectivity Configuration File below). For each matching node a copy of a
+message is created and routed inside ONE. When the bundle reaches its destination
+inside ONE it is delivered to the dtnd router instance attached to the node.
+Copies of the bundle payload are stored within 'bundles' directory.
+
+To enable this functionality the following steps must be taken:
+
+1) DTN2 must be compiled and configured with ECL support enabled.
+2) DTN2Events event generator must be configured to be loaded into ONE
+ as an events class.
+3) DTN2Reporter must be configured and loaded into one as a report class.
+4) DTN2 connectivity configuration file must be configured as DTN2.configFile
+
+To start the simulation:
+1) Start all the dtnd router instances.
+2) Start ONE.
+
+Example Configuration (2-4 above)
+---------------------------------
+
+Events.nrof = 1
+Events1.class = DTN2Events
+Report.nrofReports = 1
+Report.report1 = DTN2Reporter
+DTN2.configFile = cla.conf
+
+DTN2 Connectivity Configuration File
+------------------------------------
+
+The DTN2 connectivity configuration file defines which nodes inside ONE
+should connect to which DTN2 router instances. It also defines the EID's
+that the nodes match.
+
+The configuration file is composed of comment lines starting with # and
+configuration lines with the following format:
+
+
+
+The fields have the following meaning:
+
+nodeID: The ID of a node inside ONE (integer >= 0)
+EID regexp: Incoming bundles whose destination EID matches this regexp
+ will be forwarded to the node inside ONE.
+ (see java.util.regex.Pattern)
+dtnd host: Hostname/IP of the dtnd router to connect to this node.
+ECL port: dtnd router's port listening to ECLAs
+console port: dtnd router's console port
+
+Example:
+#
+1 dtn://local-1.dtn/(.*) localhost 8801 5051
+2 dtn://local-2.dtn/(.*) localhost 8802 5052
+
+Known Issues
+------------
+
+For DTN2 connectivity related issues, you can contact teemuk@netlab.tkk.fi
+
+-Quitting dtnd router instances connected to ONE will cause ONE to quit.
+
+
+Toolkit
+=======
+
+The simulation package includes a folder called "toolkit" that contains
+scripts for generating input and processing the output of the simulator. All
+(currently included) scripts are written with Perl (http://www.perl.com/) so
+you need to have it installed before running the scripts. Some post processing
+scripts use gnuplot (http://www.gnuplot.info/) for creating graphics. Both of
+the programs are freely available for most of the Unix/Linux and Windows
+environments. For Windows environment, you may need to change the path to the
+executables for some of the scripts.
+
+getStats.pl
+This script can be used to create bar-plots of various statistics gathered by
+the MessageStatsReport -report module. The only mandatory option is "-stat"
+which is used to define the name of the statistics value that should be parsed
+from the report files (e.g., "delivery_prob" for message delivery
+probabilities). Rest of the parameters should be MessageStatsReport output
+filenames (or paths). Script creates three output files: one with values from
+all the files, one with the gnuplot commands used to create the graphics and
+finally an image file containing the graphics. One bar is created to the plot
+for each input file. The title for each bar is parsed from the report filename
+using the regular expression defined with "-label" option. Run getStats.pl
+with "-help" option for more help.
+
+ccdfPlotter.pl
+Script for creating Complementary(/Inverse) Cumulative Distribution Function
+plots (using gluplot) from reports that contain time-hitcount-tuples. Output
+filename must be defined with the "-out" option and rest of the parameters
+should be (suitable) report filenames. "-label" option can be used for
+defining label extracting regular expression (similar to one for the getStats
+script) for the legend.
+
+createCreates.pl
+Message creation pattern for the simulation can be defined with external events
+file. Such a file can be simply created with any text editor but this script
+makes it easier to create a large amount of messages. Mandatory options are
+the number of messages ("-nrof"), time range ("-time"), host address range
+("-hosts") and message size range ("-sizes"). The number of messages is simply
+an integer but the ranges are given with two integers with a colon (:) between
+them. If hosts should reply to the messages that they receive, size range of
+the reply messages can be defined with "-rsizes" option. If a certain random
+number generator seed should be used, that can be defined with "-seed" option.
+All random values are drawn from a uniform distribution with inclusive minimum
+value and exclusive maximum value. Script outputs commands that are suitable
+for external events file's contents. You probably want to redirect the output
+to some file.
+
+dtnsim2parser.pl and transimsParser.pl
+These two (quite experimental) parsers convert data from other programs to a
+form that is suitable for ONE. Both take two parameters: input and output
+file. If these parameters are omitted, stdin and stdout are used for input and
+output. With "-h" option a short help is printed.
+dtnsim2parser converts dtnsim2's (http://watwire.uwaterloo.ca/DTN/sim/) output
+(with verbose mode 8) to an external events file that can be fed to ONE. The
+main idea of this parser is that you can first create a connectivity pattern
+file using ONE and ConnectivityDtnsim2Report, feed that to dtnsim2 and then
+observe the results visually in ONE (using the output converted with
+dtnsim2parser as the external events file).
+transimsParser can convert TRANSIM's (http://transims-opensource.net/) vehicle
+snapshot files to external movement files that can be used as an input for
+node movement. See ExternalMovement and ExternalMovementReader classes for
+more information.
diff --git a/applications/PingApplication.java b/applications/PingApplication.java
index b2787db20..9e175b813 100644
--- a/applications/PingApplication.java
+++ b/applications/PingApplication.java
@@ -1,6 +1,6 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
package applications;
@@ -17,14 +17,14 @@
import core.World;
/**
- * Simple ping application to demonstrate the application support. The
+ * Simple ping application to demonstrate the application support. The
* application can be configured to send pings with a fixed interval or to only
* answer to pings it receives. When the application receives a ping it sends
* a pong message in response.
- *
+ *
* The corresponding PingAppReporter
class can be used to record
* information about the application behavior.
- *
+ *
* @see PingAppReporter
* @author teemuk
*/
@@ -43,10 +43,10 @@ public class PingApplication extends Application {
public static final String PING_PING_SIZE = "pingSize";
/** Size of the pong message */
public static final String PING_PONG_SIZE = "pongSize";
-
+
/** Application ID */
public static final String APP_ID = "fi.tkk.netlab.PingApplication";
-
+
// Private vars
private double lastPing = 0;
private double interval = 500;
@@ -57,10 +57,10 @@ public class PingApplication extends Application {
private int pingSize=1;
private int pongSize=1;
private Random rng;
-
- /**
+
+ /**
* Creates a new ping application with the given settings.
- *
+ *
* @param s Settings to use for initializing the application.
*/
public PingApplication(Settings s) {
@@ -87,14 +87,14 @@ public PingApplication(Settings s) {
this.destMin = destination[0];
this.destMax = destination[1];
}
-
+
rng = new Random(this.seed);
super.setAppID(APP_ID);
}
-
- /**
+
+ /**
* Copy-constructor
- *
+ *
* @param a
*/
public PingApplication(PingApplication a) {
@@ -109,11 +109,11 @@ public PingApplication(PingApplication a) {
this.pingSize = a.getPingSize();
this.rng = new Random(this.seed);
}
-
- /**
+
+ /**
* Handles an incoming message. If the message is a ping message replies
* with a pong message. Generates events for ping and pong messages.
- *
+ *
* @param msg message received by the router
* @param host host to which the application instance is attached
*/
@@ -121,33 +121,33 @@ public PingApplication(PingApplication a) {
public Message handle(Message msg, DTNHost host) {
String type = (String)msg.getProperty("type");
if (type==null) return msg; // Not a ping/pong message
-
+
// Respond with pong if we're the recipient
if (msg.getTo()==host && type.equalsIgnoreCase("ping")) {
- String id = "pong" + SimClock.getIntTime() + "-" +
+ String id = "pong" + SimClock.getIntTime() + "-" +
host.getAddress();
Message m = new Message(host, msg.getFrom(), id, getPongSize());
m.addProperty("type", "pong");
m.setAppID(APP_ID);
host.createNewMessage(m);
-
+
// Send event to listeners
super.sendEventToListeners("GotPing", null, host);
super.sendEventToListeners("SentPong", null, host);
}
-
+
// Received a pong reply
if (msg.getTo()==host && type.equalsIgnoreCase("pong")) {
// Send event to listeners
super.sendEventToListeners("GotPong", null, host);
}
-
+
return msg;
}
- /**
+ /**
* Draws a random host from the destination range
- *
+ *
* @return host
*/
private DTNHost randomHost() {
@@ -159,15 +159,15 @@ private DTNHost randomHost() {
World w = SimScenario.getInstance().getWorld();
return w.getNodeByAddress(destaddr);
}
-
+
@Override
public Application replicate() {
return new PingApplication(this);
}
- /**
+ /**
* Sends a ping packet if this is an active application instance.
- *
+ *
* @param host to which the application instance is attached
*/
@Override
@@ -182,10 +182,10 @@ public void update(DTNHost host) {
m.addProperty("type", "ping");
m.setAppID(APP_ID);
host.createNewMessage(m);
-
+
// Call listeners
super.sendEventToListeners("SentPing", null, host);
-
+
this.lastPing = curTime;
}
}
diff --git a/core/Application.java b/core/Application.java
index d2aabaeec..98520c725 100644
--- a/core/Application.java
+++ b/core/Application.java
@@ -1,6 +1,6 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
package core;
@@ -14,12 +14,12 @@
* properties of the message before returning it or return null to signal
* to the router that it wants the message to be dropped.
*
- *
+ *
*
* In addition, the application's update()
method is called every
* simulation cycle.
*
- *
+ *
*
* Configuration of application is done by picking a unique application instance
* name (e.g., mySimpleApp) and setting its type
property to the
@@ -28,37 +28,37 @@
* Group.application
setting: Group1.application =
* mySimpleApp
.
*
- *
+ *
* @author mjpitka
* @author teemuk
*/
public abstract class Application {
private List aListeners = null;
-
+
public String appID = null;
- public Application(){
+ public Application(){
}
-
+
/**
* Copy constructor.
- *
+ *
* @param app
*/
- public Application(Application app){
+ public Application(Application app){
this.aListeners = app.getAppListeners();
this.appID = app.appID;
}
-
+
/**
- * This method handles application functionality related to
- * processing of the bundle. Application handles a messages,
- * which arrives to the node hosting this application. After
- * performing application specific handling, this method returns
- * a list of messages. If node wishes to continue forwarding the
+ * This method handles application functionality related to
+ * processing of the bundle. Application handles a messages,
+ * which arrives to the node hosting this application. After
+ * performing application specific handling, this method returns
+ * a list of messages. If node wishes to continue forwarding the
* incoming
- *
+ *
* @param msg The incoming message.
* @param host The host this application instance is attached to.
* @return the (possibly modified) message to forward or null
@@ -66,52 +66,52 @@ public Application(Application app){
* message.
*/
public abstract Message handle(Message msg, DTNHost host);
-
- /**
+
+ /**
* Called every simulation cycle.
- *
+ *
* @param host The host this application instance is attached to.
*/
public abstract void update(DTNHost host);
-
- /**
+
+ /**
*
* Returns an unique application ID. The application will only receive
* messages with this application ID. If the AppID is set to
* null
the application will receive all messages.
*
- *
+ *
* @return Application ID.
*/
public String getAppID() {
return this.appID;
}
-
- /**
+
+ /**
* Sets the application ID. Should only set once when the application is
* created. Changing the value during simulation runtime is not recommended
* unless you really know what you're doing.
- *
+ *
* @param appID
*/
public void setAppID(String appID) {
this.appID = appID;
}
-
+
public abstract Application replicate();
-
+
public void setAppListeners (List aListeners){
this.aListeners = aListeners;
}
-
+
public List getAppListeners(){
return this.aListeners;
}
-
- /**
+
+ /**
* Sends an event to all listeners.
- *
+ *
* @param event The event to send.
* @param params Any additional parameters to send.
* @param host The host which where the app is running.
diff --git a/core/ApplicationListener.java b/core/ApplicationListener.java
index 2d22c397c..0dc1155de 100644
--- a/core/ApplicationListener.java
+++ b/core/ApplicationListener.java
@@ -1,35 +1,35 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package core;
-
+package core;
+
/**
- *
- * Interface for classes that want to be informed about messages
+ *
+ * Interface for classes that want to be informed about messages
* between hosts.
*
- *
+ *
*
* Report classes wishing to receive application events should implement this
* interface. Note that the application event names are defined by the
* applications so any class wishing to interpret them must know the
* application.
*
- *
+ *
* @author teemuk
- * @author mjpitka
- */
-public interface ApplicationListener {
-
- /**
+ * @author mjpitka
+ */
+public interface ApplicationListener {
+
+ /**
* Application has generated an event.
- *
+ *
* @param event Event name.
* @param params Additional parameters for the event
* @param app Application instance that generated the event.
* @param host The host this application instance is running on.
- */
+ */
public void gotEvent(String event, Object params, Application app,
- DTNHost host);
-}
+ DTNHost host);
+}
diff --git a/core/ArithmeticCondition.java b/core/ArithmeticCondition.java
index 448acf046..20ba948cf 100644
--- a/core/ArithmeticCondition.java
+++ b/core/ArithmeticCondition.java
@@ -1,83 +1,83 @@
-/*
- * Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
- */
-package core;
-
-/**
- * This class presents a simple arithmetic condition: is value smaller than,
- * bigger than, or equal to another value. The condition is given in text
- * form, e.g., "< 42", and then different values can be matched against that
- * condition.
- * @author Ari
- */
-public class ArithmeticCondition {
-
- private static final String VALID_OPERATORS = "><=";
- private char operator;
- private double number;
-
- /**
- * Creates a new condition based on the given string.
- * @param cond The condition string. Must consist of one operator
- * ("<", ">", or "=") and one double-precision floating point number.
- * @throws SettingsError if the given string is not a valid condition
- */
- public ArithmeticCondition(String cond) {
- String value;
- int multiplier = 1;
-
- if (cond.length() < 2) {
- throw new SettingsError("Invalid condition \"" + cond + "\"");
- }
-
- operator = cond.charAt(0);
- value = cond.substring(1);
-
- /* handle kilo and Mega suffixes for the value */
- if (value.endsWith("k")) {
- multiplier = 1000;
- } else if (value.endsWith("M")) {
- multiplier = 1000000;
- }
- if (multiplier > 1) { /* remove suffix */
- value = value.substring(0, value.length() - 1);
- }
-
- if (VALID_OPERATORS.indexOf(operator) == -1) {
- throw new SettingsError("Invalid operator in condition \"" + cond +
- "\" valid operators: " + VALID_OPERATORS);
- }
-
- try {
- number = Double.parseDouble(value);
- } catch (NumberFormatException e) {
- throw new SettingsError("Invalid numeric value in condition \"" +
- cond + "\"");
- }
-
- number *= multiplier;
-
- }
-
- /**
- * Returns true if the given value satisfies "V X N" where V is the given
- * value, X is the operator (from the settings), and N is the numeric value
- * given after the operator in the settings.
- * @param value The value to check
- * @return true if the condition holds for the given value, false otherwise
- */
- public boolean isTrueFor(double value) {
- switch (operator) {
- case '<': return value < this.number;
- case '>': return value > this.number;
- case '=': return value == this.number; // XXX: == for doubles...
- default: throw new SettingsError("Invalid operator");
- }
- }
-
- @Override
- public String toString() {
- return "Condition \"" + operator + " " + number + "\"";
- }
-}
+/*
+ * Copyright 2010 Aalto University, ComNet
+ * Released under GPLv3. See LICENSE.txt for details.
+ */
+package core;
+
+/**
+ * This class presents a simple arithmetic condition: is value smaller than,
+ * bigger than, or equal to another value. The condition is given in text
+ * form, e.g., "< 42", and then different values can be matched against that
+ * condition.
+ * @author Ari
+ */
+public class ArithmeticCondition {
+
+ private static final String VALID_OPERATORS = "><=";
+ private char operator;
+ private double number;
+
+ /**
+ * Creates a new condition based on the given string.
+ * @param cond The condition string. Must consist of one operator
+ * ("<", ">", or "=") and one double-precision floating point number.
+ * @throws SettingsError if the given string is not a valid condition
+ */
+ public ArithmeticCondition(String cond) {
+ String value;
+ int multiplier = 1;
+
+ if (cond.length() < 2) {
+ throw new SettingsError("Invalid condition \"" + cond + "\"");
+ }
+
+ operator = cond.charAt(0);
+ value = cond.substring(1);
+
+ /* handle kilo and Mega suffixes for the value */
+ if (value.endsWith("k")) {
+ multiplier = 1000;
+ } else if (value.endsWith("M")) {
+ multiplier = 1000000;
+ }
+ if (multiplier > 1) { /* remove suffix */
+ value = value.substring(0, value.length() - 1);
+ }
+
+ if (VALID_OPERATORS.indexOf(operator) == -1) {
+ throw new SettingsError("Invalid operator in condition \"" + cond +
+ "\" valid operators: " + VALID_OPERATORS);
+ }
+
+ try {
+ number = Double.parseDouble(value);
+ } catch (NumberFormatException e) {
+ throw new SettingsError("Invalid numeric value in condition \"" +
+ cond + "\"");
+ }
+
+ number *= multiplier;
+
+ }
+
+ /**
+ * Returns true if the given value satisfies "V X N" where V is the given
+ * value, X is the operator (from the settings), and N is the numeric value
+ * given after the operator in the settings.
+ * @param value The value to check
+ * @return true if the condition holds for the given value, false otherwise
+ */
+ public boolean isTrueFor(double value) {
+ switch (operator) {
+ case '<': return value < this.number;
+ case '>': return value > this.number;
+ case '=': return value == this.number; // XXX: == for doubles...
+ default: throw new SettingsError("Invalid operator");
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "Condition \"" + operator + " " + number + "\"";
+ }
+}
diff --git a/core/CBRConnection.java b/core/CBRConnection.java
index 0db8634bd..9768aaa8f 100644
--- a/core/CBRConnection.java
+++ b/core/CBRConnection.java
@@ -1,124 +1,124 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
- */
-package core;
-
-import routing.MessageRouter;
-
-/**
- * A constant bit-rate connection between two DTN nodes.
- */
-public class CBRConnection extends Connection {
- private int speed;
- private double transferDoneTime;
-
- /**
- * Creates a new connection between nodes and sets the connection
- * state to "up".
- * @param fromNode The node that initiated the connection
- * @param fromInterface The interface that initiated the connection
- * @param toNode The node in the other side of the connection
- * @param toInterface The interface in the other side of the connection
- * @param connectionSpeed Transfer speed of the connection (Bps) when
- * the connection is initiated
- */
- public CBRConnection(DTNHost fromNode, NetworkInterface fromInterface,
- DTNHost toNode, NetworkInterface toInterface, int connectionSpeed) {
- super(fromNode, fromInterface, toNode, toInterface);
- this.speed = connectionSpeed;
- this.transferDoneTime = 0;
-
- }
-
- /**
- * Sets a message that this connection is currently transferring. If message
- * passing is controlled by external events, this method is not needed
- * (but then e.g. {@link #finalizeTransfer()} and
- * {@link #isMessageTransferred()} will not work either). Only a one message
- * at a time can be transferred using one connection.
- * @param from The host sending the message
- * @param m The message
- * @return The value returned by
- * {@link MessageRouter#receiveMessage(Message, DTNHost)}
- */
- public int startTransfer(DTNHost from, Message m) {
- assert this.msgOnFly == null : "Already transferring " +
- this.msgOnFly + " from " + this.msgFromNode + " to " +
- this.getOtherNode(this.msgFromNode) + ". Can't " +
- "start transfer of " + m + " from " + from;
-
- this.msgFromNode = from;
- Message newMessage = m.replicate();
- int retVal = getOtherNode(from).receiveMessage(newMessage, from);
-
- if (retVal == MessageRouter.RCV_OK) {
- this.msgOnFly = newMessage;
- this.transferDoneTime = SimClock.getTime() +
- (1.0*m.getSize()) / this.speed;
- }
-
- return retVal;
- }
-
- /**
- * Aborts the transfer of the currently transferred message.
- */
- public void abortTransfer() {
- assert msgOnFly != null : "No message to abort at " + msgFromNode;
- getOtherNode(msgFromNode).messageAborted(this.msgOnFly.getId(),
- msgFromNode,getRemainingByteCount());
- clearMsgOnFly();
- this.transferDoneTime = 0;
- }
-
- /**
- * Gets the transferdonetime
- */
- public double getTransferDoneTime() {
- return transferDoneTime;
- }
-
- /**
- * Returns true if the current message transfer is done.
- * @return True if the transfer is done, false if not
- */
- public boolean isMessageTransferred() {
- return getRemainingByteCount() == 0;
- }
-
- /**
- * returns the current speed of the connection
- */
- public double getSpeed() {
- return this.speed;
- }
-
- /**
- * Returns the amount of bytes to be transferred before ongoing transfer
- * is ready or 0 if there's no ongoing transfer or it has finished
- * already
- * @return the amount of bytes to be transferred
- */
- public int getRemainingByteCount() {
- int remaining;
-
- if (msgOnFly == null) {
- return 0;
- }
-
- remaining = (int)((this.transferDoneTime - SimClock.getTime())
- * this.speed);
-
- return (remaining > 0 ? remaining : 0);
- }
-
- /**
- * Returns a String presentation of the connection.
- */
- public String toString() {
- return super.toString() + (isTransferring() ?
- " until " + String.format("%.2f", this.transferDoneTime) : "");
- }
-
-}
+ * Released under GPLv3. See LICENSE.txt for details.
+ */
+package core;
+
+import routing.MessageRouter;
+
+/**
+ * A constant bit-rate connection between two DTN nodes.
+ */
+public class CBRConnection extends Connection {
+ private int speed;
+ private double transferDoneTime;
+
+ /**
+ * Creates a new connection between nodes and sets the connection
+ * state to "up".
+ * @param fromNode The node that initiated the connection
+ * @param fromInterface The interface that initiated the connection
+ * @param toNode The node in the other side of the connection
+ * @param toInterface The interface in the other side of the connection
+ * @param connectionSpeed Transfer speed of the connection (Bps) when
+ * the connection is initiated
+ */
+ public CBRConnection(DTNHost fromNode, NetworkInterface fromInterface,
+ DTNHost toNode, NetworkInterface toInterface, int connectionSpeed) {
+ super(fromNode, fromInterface, toNode, toInterface);
+ this.speed = connectionSpeed;
+ this.transferDoneTime = 0;
+
+ }
+
+ /**
+ * Sets a message that this connection is currently transferring. If message
+ * passing is controlled by external events, this method is not needed
+ * (but then e.g. {@link #finalizeTransfer()} and
+ * {@link #isMessageTransferred()} will not work either). Only a one message
+ * at a time can be transferred using one connection.
+ * @param from The host sending the message
+ * @param m The message
+ * @return The value returned by
+ * {@link MessageRouter#receiveMessage(Message, DTNHost)}
+ */
+ public int startTransfer(DTNHost from, Message m) {
+ assert this.msgOnFly == null : "Already transferring " +
+ this.msgOnFly + " from " + this.msgFromNode + " to " +
+ this.getOtherNode(this.msgFromNode) + ". Can't " +
+ "start transfer of " + m + " from " + from;
+
+ this.msgFromNode = from;
+ Message newMessage = m.replicate();
+ int retVal = getOtherNode(from).receiveMessage(newMessage, from);
+
+ if (retVal == MessageRouter.RCV_OK) {
+ this.msgOnFly = newMessage;
+ this.transferDoneTime = SimClock.getTime() +
+ (1.0*m.getSize()) / this.speed;
+ }
+
+ return retVal;
+ }
+
+ /**
+ * Aborts the transfer of the currently transferred message.
+ */
+ public void abortTransfer() {
+ assert msgOnFly != null : "No message to abort at " + msgFromNode;
+ getOtherNode(msgFromNode).messageAborted(this.msgOnFly.getId(),
+ msgFromNode,getRemainingByteCount());
+ clearMsgOnFly();
+ this.transferDoneTime = 0;
+ }
+
+ /**
+ * Gets the transferdonetime
+ */
+ public double getTransferDoneTime() {
+ return transferDoneTime;
+ }
+
+ /**
+ * Returns true if the current message transfer is done.
+ * @return True if the transfer is done, false if not
+ */
+ public boolean isMessageTransferred() {
+ return getRemainingByteCount() == 0;
+ }
+
+ /**
+ * returns the current speed of the connection
+ */
+ public double getSpeed() {
+ return this.speed;
+ }
+
+ /**
+ * Returns the amount of bytes to be transferred before ongoing transfer
+ * is ready or 0 if there's no ongoing transfer or it has finished
+ * already
+ * @return the amount of bytes to be transferred
+ */
+ public int getRemainingByteCount() {
+ int remaining;
+
+ if (msgOnFly == null) {
+ return 0;
+ }
+
+ remaining = (int)((this.transferDoneTime - SimClock.getTime())
+ * this.speed);
+
+ return (remaining > 0 ? remaining : 0);
+ }
+
+ /**
+ * Returns a String presentation of the connection.
+ */
+ public String toString() {
+ return super.toString() + (isTransferring() ?
+ " until " + String.format("%.2f", this.transferDoneTime) : "");
+ }
+
+}
diff --git a/core/Connection.java b/core/Connection.java
index d6e24d43f..a5092b312 100644
--- a/core/Connection.java
+++ b/core/Connection.java
@@ -1,6 +1,6 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
package core;
@@ -29,7 +29,7 @@ public abstract class Connection {
* @param toNode The node in the other side of the connection
* @param toInterface The interface in the other side of the connection
*/
- public Connection(DTNHost fromNode, NetworkInterface fromInterface,
+ public Connection(DTNHost fromNode, NetworkInterface fromInterface,
DTNHost toNode, NetworkInterface toInterface) {
this.fromNode = fromNode;
this.fromInterface = fromInterface;
@@ -48,7 +48,7 @@ public boolean isUp() {
return this.isUp;
}
- /**
+ /**
* Returns true if the connections is transferring a message
* @return true if the connections is transferring a message
*/
@@ -56,7 +56,7 @@ public boolean isTransferring() {
return this.msgOnFly != null;
}
-
+
/**
* Returns true if the given node is the initiator of the connection, false
* otherwise
@@ -66,7 +66,7 @@ public boolean isTransferring() {
public boolean isInitiator(DTNHost node) {
return node == this.fromNode;
}
-
+
/**
* Sets the state of the connection.
* @param state True if the connection is up, false if not
@@ -78,11 +78,11 @@ public void setUpState(boolean state) {
/**
* Sets a message that this connection is currently transferring. If message
* passing is controlled by external events, this method is not needed
- * (but then e.g. {@link #finalizeTransfer()} and
+ * (but then e.g. {@link #finalizeTransfer()} and
* {@link #isMessageTransferred()} will not work either). Only a one message
* at a time can be transferred using one connection.
* @param m The message
- * @return The value returned by
+ * @return The value returned by
* {@link MessageRouter#receiveMessage(Message, DTNHost)}
*/
public abstract int startTransfer(DTNHost from, Message m);
@@ -97,7 +97,7 @@ public void setUpState(boolean state) {
* Aborts the transfer of the currently transferred message.
*/
public void abortTransfer() {
- assert msgOnFly != null : "No message to abort at " + msgFromNode;
+ assert msgOnFly != null : "No message to abort at " + msgFromNode;
int bytesRemaining = getRemainingByteCount();
this.bytesTransferred += msgOnFly.getSize() - bytesRemaining;
@@ -105,7 +105,7 @@ public void abortTransfer() {
getOtherNode(msgFromNode).messageAborted(this.msgOnFly.getId(),
msgFromNode, bytesRemaining);
clearMsgOnFly();
- }
+ }
/**
* Returns the amount of bytes to be transferred before ongoing transfer
@@ -121,7 +121,7 @@ public void abortTransfer() {
*/
protected void clearMsgOnFly() {
this.msgOnFly = null;
- this.msgFromNode = null;
+ this.msgFromNode = null;
}
/**
@@ -133,7 +133,7 @@ protected void clearMsgOnFly() {
public void finalizeTransfer() {
assert this.msgOnFly != null : "Nothing to finalize in " + this;
assert msgFromNode != null : "msgFromNode is not set";
-
+
this.bytesTransferred += msgOnFly.getSize();
getOtherNode(msgFromNode).messageTransferred(this.msgOnFly.getId(),
@@ -142,7 +142,7 @@ public void finalizeTransfer() {
}
/**
- * Returns true if the current message transfer is done
+ * Returns true if the current message transfer is done
* @return True if the transfer is done, false if not
*/
public abstract boolean isMessageTransferred();
@@ -153,21 +153,21 @@ public void finalizeTransfer() {
* @return true if the connection is ready to transfer a message
*/
public boolean isReadyForTransfer() {
- return this.isUp && this.msgOnFly == null;
+ return this.isUp && this.msgOnFly == null;
}
/**
* Gets the message that this connection is currently transferring.
* @return The message or null if no message is being transferred
- */
+ */
public Message getMessage() {
return this.msgOnFly;
}
- /**
+ /**
* Gets the current connection speed
*/
- public abstract double getSpeed();
+ public abstract double getSpeed();
/**
* Returns the total amount of bytes this connection has transferred so far
@@ -182,7 +182,7 @@ public int getTotalBytesTransferred() {
return this.bytesTransferred + this.msgOnFly.getSize();
}
else {
- return this.bytesTransferred +
+ return this.bytesTransferred +
(msgOnFly.getSize() - getRemainingByteCount());
}
}
@@ -221,8 +221,8 @@ public NetworkInterface getOtherInterface(NetworkInterface i) {
*/
public String toString() {
return fromNode + "<->" + toNode + " (" + getSpeed()/1000 + " kBps) is " +
- (isUp() ? "up":"down") +
- (isTransferring() ? " transferring " + this.msgOnFly +
+ (isUp() ? "up":"down") +
+ (isTransferring() ? " transferring " + this.msgOnFly +
" from " + this.msgFromNode : "");
}
diff --git a/core/ConnectionListener.java b/core/ConnectionListener.java
index 210978f2e..752fedf17 100644
--- a/core/ConnectionListener.java
+++ b/core/ConnectionListener.java
@@ -1,27 +1,27 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package core;
-
-/**
- * Interface for classes that want to be informed about connections
- * between hosts.
- */
-public interface ConnectionListener {
-
- /**
- * Method is called when two hosts are connected.
- * @param host1 Host that initiated the connection
- * @param host2 Host that was connected to
- */
- public void hostsConnected(DTNHost host1, DTNHost host2);
-
- /**
- * Method is called when connection between hosts is disconnected.
- * @param host1 Host that initiated the disconnection
- * @param host2 Host at the other end of the connection
- */
- public void hostsDisconnected(DTNHost host1, DTNHost host2);
-
-}
+package core;
+
+/**
+ * Interface for classes that want to be informed about connections
+ * between hosts.
+ */
+public interface ConnectionListener {
+
+ /**
+ * Method is called when two hosts are connected.
+ * @param host1 Host that initiated the connection
+ * @param host2 Host that was connected to
+ */
+ public void hostsConnected(DTNHost host1, DTNHost host2);
+
+ /**
+ * Method is called when connection between hosts is disconnected.
+ * @param host1 Host that initiated the disconnection
+ * @param host2 Host at the other end of the connection
+ */
+ public void hostsDisconnected(DTNHost host1, DTNHost host2);
+
+}
diff --git a/core/Coord.java b/core/Coord.java
index 002801c57..45b22835e 100644
--- a/core/Coord.java
+++ b/core/Coord.java
@@ -1,156 +1,156 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package core;
-
-/**
- * Class to hold 2D coordinates and perform simple arithmetics and
- * transformations
- */
-public class Coord implements Cloneable, Comparable {
- private double x;
- private double y;
-
- /**
- * Constructor.
- * @param x Initial X-coordinate
- * @param y Initial Y-coordinate
- */
- public Coord(double x, double y) {
- setLocation(x,y);
- }
-
- /**
- * Sets the location of this coordinate object
- * @param x The x coordinate to set
- * @param y The y coordinate to set
- */
- public void setLocation(double x, double y) {
- this.x = x;
- this.y = y;
- }
-
- /**
- * Sets this coordinate's location to be equal to other
- * coordinates location
- * @param c The other coordinate
- */
- public void setLocation(Coord c) {
- this.x = c.x;
- this.y = c.y;
- }
-
- /**
- * Moves the point by dx and dy
- * @param dx How much to move the point in X-direction
- * @param dy How much to move the point in Y-direction
- */
- public void translate(double dx, double dy) {
- this.x += dx;
- this.y += dy;
- }
-
- /**
- * Returns the distance to another coordinate
- * @param other The other coordinate
- * @return The distance between this and another coordinate
- */
- public double distance(Coord other) {
- double dx = this.x - other.x;
- double dy = this.y - other.y;
-
- return Math.sqrt(dx*dx + dy*dy);
- }
-
- /**
- * Returns the x coordinate
- * @return x coordinate
- */
- public double getX() {
- return this.x;
- }
-
- /**
- * Returns the y coordinate
- * @return y coordinate
- */
- public double getY() {
- return this.y;
- }
-
- /**
- * Returns a text representation of the coordinate (rounded to 2 decimals)
- * @return a text representation of the coordinate
- */
- public String toString() {
- return String.format("(%.2f,%.2f)",x,y);
- }
-
- /**
- * Returns a clone of this coordinate
- */
- public Coord clone() {
- Coord clone = null;
- try {
- clone = (Coord) super.clone();
- } catch (CloneNotSupportedException e) {
- e.printStackTrace();
- System.exit(-1);
- }
- return clone;
- }
-
- /**
- * Checks if this coordinate's location is equal to other coordinate's
- * @param c The other coordinate
- * @return True if locations are the same
- */
- public boolean equals(Coord c) {
- if (c == this) {
- return true;
- }
- else {
- return (x == c.x && y == c.y); // XXX: == for doubles...
- }
- }
-
- @Override
+package core;
+
+/**
+ * Class to hold 2D coordinates and perform simple arithmetics and
+ * transformations
+ */
+public class Coord implements Cloneable, Comparable {
+ private double x;
+ private double y;
+
+ /**
+ * Constructor.
+ * @param x Initial X-coordinate
+ * @param y Initial Y-coordinate
+ */
+ public Coord(double x, double y) {
+ setLocation(x,y);
+ }
+
+ /**
+ * Sets the location of this coordinate object
+ * @param x The x coordinate to set
+ * @param y The y coordinate to set
+ */
+ public void setLocation(double x, double y) {
+ this.x = x;
+ this.y = y;
+ }
+
+ /**
+ * Sets this coordinate's location to be equal to other
+ * coordinates location
+ * @param c The other coordinate
+ */
+ public void setLocation(Coord c) {
+ this.x = c.x;
+ this.y = c.y;
+ }
+
+ /**
+ * Moves the point by dx and dy
+ * @param dx How much to move the point in X-direction
+ * @param dy How much to move the point in Y-direction
+ */
+ public void translate(double dx, double dy) {
+ this.x += dx;
+ this.y += dy;
+ }
+
+ /**
+ * Returns the distance to another coordinate
+ * @param other The other coordinate
+ * @return The distance between this and another coordinate
+ */
+ public double distance(Coord other) {
+ double dx = this.x - other.x;
+ double dy = this.y - other.y;
+
+ return Math.sqrt(dx*dx + dy*dy);
+ }
+
+ /**
+ * Returns the x coordinate
+ * @return x coordinate
+ */
+ public double getX() {
+ return this.x;
+ }
+
+ /**
+ * Returns the y coordinate
+ * @return y coordinate
+ */
+ public double getY() {
+ return this.y;
+ }
+
+ /**
+ * Returns a text representation of the coordinate (rounded to 2 decimals)
+ * @return a text representation of the coordinate
+ */
+ public String toString() {
+ return String.format("(%.2f,%.2f)",x,y);
+ }
+
+ /**
+ * Returns a clone of this coordinate
+ */
+ public Coord clone() {
+ Coord clone = null;
+ try {
+ clone = (Coord) super.clone();
+ } catch (CloneNotSupportedException e) {
+ e.printStackTrace();
+ System.exit(-1);
+ }
+ return clone;
+ }
+
+ /**
+ * Checks if this coordinate's location is equal to other coordinate's
+ * @param c The other coordinate
+ * @return True if locations are the same
+ */
+ public boolean equals(Coord c) {
+ if (c == this) {
+ return true;
+ }
+ else {
+ return (x == c.x && y == c.y); // XXX: == for doubles...
+ }
+ }
+
+ @Override
public boolean equals(Object o) {
- if (o == null) return false;
- return equals((Coord) o);
- }
-
- /**
- * Returns a hash code for this coordinate
- * (actually a hash of the String made of the coordinates)
- */
- public int hashCode() {
- return (x+","+y).hashCode();
- }
-
- /**
- * Compares this coordinate to other coordinate. Coordinate whose y
- * value is smaller comes first and if y values are equal, the one with
- * smaller x value comes first.
- * @return -1, 0 or 1 if this node is before, in the same place or
- * after the other coordinate
- */
- public int compareTo(Coord other) {
- if (this.y < other.y) {
- return -1;
- }
- else if (this.y > other.y) {
- return 1;
- }
- else if (this.x < other.x) {
- return -1;
- }
- else if (this.x > other.x) {
- return 1;
- }
- else {
- return 0;
- }
- }
-}
+ if (o == null) return false;
+ return equals((Coord) o);
+ }
+
+ /**
+ * Returns a hash code for this coordinate
+ * (actually a hash of the String made of the coordinates)
+ */
+ public int hashCode() {
+ return (x+","+y).hashCode();
+ }
+
+ /**
+ * Compares this coordinate to other coordinate. Coordinate whose y
+ * value is smaller comes first and if y values are equal, the one with
+ * smaller x value comes first.
+ * @return -1, 0 or 1 if this node is before, in the same place or
+ * after the other coordinate
+ */
+ public int compareTo(Coord other) {
+ if (this.y < other.y) {
+ return -1;
+ }
+ else if (this.y > other.y) {
+ return 1;
+ }
+ else if (this.x < other.x) {
+ return -1;
+ }
+ else if (this.x > other.x) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
+ }
+}
diff --git a/core/DTN2Manager.java b/core/DTN2Manager.java
index 9e1592ecd..80c6d607d 100644
--- a/core/DTN2Manager.java
+++ b/core/DTN2Manager.java
@@ -1,6 +1,6 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
package core;
@@ -20,7 +20,7 @@
import fi.tkk.netlab.dtn.ecla.Bundle;
import fi.tkk.netlab.dtn.ecla.CLAParser;
-/**
+/**
* Manages the external convergence layer connections to dtnd.
* Parses the configuration file and sets up the CLAParsers
* and EID->host mappings.
@@ -29,14 +29,14 @@
public class DTN2Manager {
private static Map CLAs = null;
/** Mapping from EID to DTNHost */
- private static Collection EID_to_host = null;
+ private static Collection EID_to_host = null;
/** Set of all bundles in the simulator */
private static Map bundles = null;
/** Reporter object that passes messages from ONE to dtnd */
private static DTN2Reporter reporter = null;
/** Events object that passes messages from dtnd to ONE */
private static DTN2Events events = null;
-
+
/**
* EID to DTNHost mapping elements.
*/
@@ -50,7 +50,7 @@ public EIDHost(String eid, int host_id, DTNHost host) {
this.host_id = host_id;
}
}
-
+
/**
* Sets up the dtnd connections by parsing the configuration file
* defined in the DTN2.configFile
setting.
@@ -65,16 +65,16 @@ public static void setup(World world) {
String[] attrs;
int nodeID, dtnd_port, console_port;
String nodeEID, dtnd_host;
-
+
DTN2Manager.CLAs = new HashMap();
DTN2Manager.EID_to_host = new LinkedList();
DTN2Manager.bundles = new HashMap();
-
+
// Check if DTN2Reporter and DTN2Events have been loaded.
// If not, we do nothing here.
if (DTN2Manager.reporter==null || DTN2Manager.events==null)
return;
-
+
// Get input stream from the settings file.
Settings conf = new Settings("DTN2");
String fname;
@@ -94,12 +94,12 @@ public static void setup(World world) {
+fname+"'");
return;
}
-
+
// Create a directory to hold copies of the bundles
f = new File("bundles");
if (!f.exists())
f.mkdir();
-
+
// Parse config file
try {
s = in.readLine();
@@ -114,21 +114,21 @@ public static void setup(World world) {
dtnd_host = attrs[2];
dtnd_port = Integer.parseInt(attrs[3]);
console_port = Integer.parseInt(attrs[4]);
-
+
// Find the host
DTNHost h = world.getNodeByAddress(nodeID);
// Add to the EID -> Host mapping
- DTN2Manager.EIDHost e = new DTN2Manager.EIDHost(nodeEID,
+ DTN2Manager.EIDHost e = new DTN2Manager.EIDHost(nodeEID,
nodeID, h);
DTN2Manager.EID_to_host.add(e);
-
+
// Configure and start the CLA
CLAParser p;
p = new CLAParser(dtnd_host, dtnd_port, "ONE");
- DTN2Events.ParserHandler ph =
+ DTN2Events.ParserHandler ph =
DTN2Manager.events.getParserHandler(nodeID, dtnd_host,
- console_port);
+ console_port);
p.setListener(ph);
Thread t = new Thread(p);
t.start();
@@ -142,8 +142,8 @@ public static void setup(World world) {
}
}
}
-
-
+
+
/**
* Sets the DTN2Reporter
object used to pass messages from ONE
* to dtnd.
@@ -154,15 +154,15 @@ public static void setup(World world) {
public static void setReporter(DTN2Reporter reporter) {
DTN2Manager.reporter = reporter;
}
-
+
/**
* Returns reference to the DTN2Reporter
object.
* @return reference to the active DTN2Reporter object
- */
+ */
public static DTN2Reporter getReporter() {
return DTN2Manager.reporter;
}
-
+
/**
* Sets the DTN2Events object.
* @param events the active events object to use
@@ -170,15 +170,15 @@ public static DTN2Reporter getReporter() {
public static void setEvents(DTN2Events events) {
DTN2Manager.events = events;
}
-
- /**
+
+ /**
* Returns the DTN2Events object.
* @return the currently active events object.
*/
public static DTN2Events getEvents() {
return DTN2Manager.events;
}
-
+
/**
* Returns the ECL parser associated with the host.
* @param host the host who's parser to return
@@ -187,8 +187,8 @@ public static DTN2Events getEvents() {
public static CLAParser getParser(DTNHost host) {
return DTN2Manager.CLAs.get(host);
}
-
- /**
+
+ /**
* Returns a Collection
of DTNHost
* objects corresponding to the given EID.
* @param EID EID of the host
@@ -201,7 +201,7 @@ public static Collection getHosts(String EID) {
}
return c;
}
-
+
/**
* Stores a reference to a bundle corresponding to the given message.
* @param id the id of the message
@@ -210,8 +210,8 @@ public static Collection getHosts(String EID) {
public static void addBundle(String id, Bundle bundle) {
DTN2Manager.bundles.put(id, bundle);
}
-
- /**
+
+ /**
* Returns the bundle associated with the given message id.
* @param id the message id
* @return the bundle associated with the message
diff --git a/core/DTNHost.java b/core/DTNHost.java
index 6a8c6c934..a230f22fd 100644
--- a/core/DTNHost.java
+++ b/core/DTNHost.java
@@ -1,9 +1,9 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package core;
-
+package core;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -12,46 +12,46 @@
import movement.Path;
import routing.MessageRouter;
import routing.util.RoutingInfo;
-
-/**
- * A DTN capable host.
- */
-public class DTNHost implements Comparable {
+
+/**
+ * A DTN capable host.
+ */
+public class DTNHost implements Comparable {
private static int nextAddress = 0;
private int address;
- private Coord location; // where is the host
- private Coord destination; // where is it going
-
- private MessageRouter router;
- private MovementModel movement;
- private Path path;
- private double speed;
- private double nextTimeToMove;
- private String name;
- private List msgListeners;
- private List movListeners;
+ private Coord location; // where is the host
+ private Coord destination; // where is it going
+
+ private MessageRouter router;
+ private MovementModel movement;
+ private Path path;
+ private double speed;
+ private double nextTimeToMove;
+ private String name;
+ private List msgListeners;
+ private List movListeners;
private List net;
- private ModuleCommunicationBus comBus;
+ private ModuleCommunicationBus comBus;
static {
DTNSim.registerForReset(DTNHost.class.getCanonicalName());
reset();
- }
- /**
- * Creates a new DTNHost.
+ }
+ /**
+ * Creates a new DTNHost.
* @param msgLs Message listeners
- * @param movLs Movement listeners
- * @param groupId GroupID of this host
+ * @param movLs Movement listeners
+ * @param groupId GroupID of this host
* @param interf List of NetworkInterfaces for the class
* @param comBus Module communication bus object
- * @param mmProto Prototype of the movement model of this host
- * @param mRouterProto Prototype of the message router of this host
- */
+ * @param mmProto Prototype of the movement model of this host
+ * @param mRouterProto Prototype of the message router of this host
+ */
public DTNHost(List msgLs,
List movLs,
String groupId, List interf,
- ModuleCommunicationBus comBus,
+ ModuleCommunicationBus comBus,
MovementModel mmProto, MessageRouter mRouterProto) {
this.comBus = comBus;
this.location = new Coord(0,0);
@@ -63,39 +63,39 @@ public DTNHost(List msgLs,
NetworkInterface ni = i.replicate();
ni.setHost(this);
net.add(ni);
- }
+ }
// TODO - think about the names of the interfaces and the nodes
//this.name = groupId + ((NetworkInterface)net.get(1)).getAddress();
- this.msgListeners = msgLs;
- this.movListeners = movLs;
-
- // create instances by replicating the prototypes
+ this.msgListeners = msgLs;
+ this.movListeners = movLs;
+
+ // create instances by replicating the prototypes
this.movement = mmProto.replicate();
this.movement.setComBus(comBus);
- this.movement.setHost(this);
- setRouter(mRouterProto.replicate());
-
- this.location = movement.getInitialLocation();
-
- this.nextTimeToMove = movement.nextPathAvailable();
- this.path = null;
-
- if (movLs != null) { // inform movement listeners about the location
- for (MovementListener l : movLs) {
- l.initialLocation(this, this.location);
- }
- }
- }
-
+ this.movement.setHost(this);
+ setRouter(mRouterProto.replicate());
+
+ this.location = movement.getInitialLocation();
+
+ this.nextTimeToMove = movement.nextPathAvailable();
+ this.path = null;
+
+ if (movLs != null) { // inform movement listeners about the location
+ for (MovementListener l : movLs) {
+ l.initialLocation(this, this.location);
+ }
+ }
+ }
+
/**
* Returns a new network interface address and increments the address for
* subsequent calls.
* @return The next address.
*/
private synchronized static int getNextAddress() {
- return nextAddress++;
+ return nextAddress++;
}
/**
@@ -103,16 +103,16 @@ private synchronized static int getNextAddress() {
*/
public static void reset() {
nextAddress = 0;
- }
-
- /**
- * Returns true if this node is actively moving (false if not)
- * @return true if this node is actively moving (false if not)
- */
- public boolean isMovementActive() {
- return this.movement.isActive();
- }
-
+ }
+
+ /**
+ * Returns true if this node is actively moving (false if not)
+ * @return true if this node is actively moving (false if not)
+ */
+ public boolean isMovementActive() {
+ return this.movement.isActive();
+ }
+
/**
* Returns true if this node's radio is active (false if not)
* @return true if this node's radio is active (false if not)
@@ -120,32 +120,32 @@ public boolean isMovementActive() {
public boolean isRadioActive() {
/* TODO: make this work for multiple interfaces */
return this.getInterface(1).isActive();
- }
-
- /**
- * Set a router for this host
- * @param router The router to set
- */
- private void setRouter(MessageRouter router) {
- router.init(this, msgListeners);
- this.router = router;
- }
-
- /**
- * Returns the router of this host
- * @return the router of this host
- */
- public MessageRouter getRouter() {
- return this.router;
- }
-
- /**
- * Returns the network-layer address of this host.
- */
- public int getAddress() {
- return this.address;
- }
-
+ }
+
+ /**
+ * Set a router for this host
+ * @param router The router to set
+ */
+ private void setRouter(MessageRouter router) {
+ router.init(this, msgListeners);
+ this.router = router;
+ }
+
+ /**
+ * Returns the router of this host
+ * @return the router of this host
+ */
+ public MessageRouter getRouter() {
+ return this.router;
+ }
+
+ /**
+ * Returns the network-layer address of this host.
+ */
+ public int getAddress() {
+ return this.address;
+ }
+
/**
* Returns this hosts's ModuleCommunicationBus
* @return this hosts's ModuleCommunicationBus
@@ -153,7 +153,7 @@ public int getAddress() {
public ModuleCommunicationBus getComBus() {
return this.comBus;
}
-
+
/**
* Informs the router of this host about state change in a connection
* object.
@@ -166,90 +166,90 @@ public void connectionUp(Connection con) {
public void connectionDown(Connection con) {
this.router.changedConnection(con);
}
-
- /**
- * Returns a copy of the list of connections this host has with other hosts
- * @return a copy of the list of connections this host has with other hosts
- */
- public List getConnections() {
+
+ /**
+ * Returns a copy of the list of connections this host has with other hosts
+ * @return a copy of the list of connections this host has with other hosts
+ */
+ public List getConnections() {
List lc = new ArrayList();
for (NetworkInterface i : net) {
lc.addAll(i.getConnections());
}
- return lc;
- }
-
- /**
- * Returns the current location of this host.
- * @return The location
- */
- public Coord getLocation() {
- return this.location;
- }
-
- /**
- * Returns the Path this node is currently traveling or null if no
- * path is in use at the moment.
- * @return The path this node is traveling
- */
- public Path getPath() {
- return this.path;
- }
-
-
- /**
- * Sets the Node's location overriding any location set by movement model
- * @param location The location to set
- */
- public void setLocation(Coord location) {
- this.location = location.clone();
- }
-
- /**
- * Sets the Node's name overriding the default name (groupId + netAddress)
- * @param name The name to set
- */
- public void setName(String name) {
- this.name = name;
- }
-
- /**
- * Returns the messages in a collection.
- * @return Messages in a collection
- */
- public Collection getMessageCollection() {
- return this.router.getMessageCollection();
- }
-
- /**
- * Returns the number of messages this node is carrying.
- * @return How many messages the node is carrying currently.
- */
- public int getNrofMessages() {
- return this.router.getNrofMessages();
- }
-
- /**
- * Returns the buffer occupancy percentage. Occupancy is 0 for empty
- * buffer but can be over 100 if a created message is bigger than buffer
- * space that could be freed.
- * @return Buffer occupancy percentage
- */
- public double getBufferOccupancy() {
- double bSize = router.getBufferSize();
- double freeBuffer = router.getFreeBufferSize();
- return 100*((bSize-freeBuffer)/bSize);
- }
-
- /**
- * Returns routing info of this host's router.
- * @return The routing info.
- */
- public RoutingInfo getRoutingInfo() {
- return this.router.getRoutingInfo();
- }
+ return lc;
+ }
+
+ /**
+ * Returns the current location of this host.
+ * @return The location
+ */
+ public Coord getLocation() {
+ return this.location;
+ }
+
+ /**
+ * Returns the Path this node is currently traveling or null if no
+ * path is in use at the moment.
+ * @return The path this node is traveling
+ */
+ public Path getPath() {
+ return this.path;
+ }
+
+
+ /**
+ * Sets the Node's location overriding any location set by movement model
+ * @param location The location to set
+ */
+ public void setLocation(Coord location) {
+ this.location = location.clone();
+ }
+
+ /**
+ * Sets the Node's name overriding the default name (groupId + netAddress)
+ * @param name The name to set
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Returns the messages in a collection.
+ * @return Messages in a collection
+ */
+ public Collection getMessageCollection() {
+ return this.router.getMessageCollection();
+ }
+
+ /**
+ * Returns the number of messages this node is carrying.
+ * @return How many messages the node is carrying currently.
+ */
+ public int getNrofMessages() {
+ return this.router.getNrofMessages();
+ }
+
+ /**
+ * Returns the buffer occupancy percentage. Occupancy is 0 for empty
+ * buffer but can be over 100 if a created message is bigger than buffer
+ * space that could be freed.
+ * @return Buffer occupancy percentage
+ */
+ public double getBufferOccupancy() {
+ double bSize = router.getBufferSize();
+ double freeBuffer = router.getFreeBufferSize();
+ return 100*((bSize-freeBuffer)/bSize);
+ }
+
+ /**
+ * Returns routing info of this host's router.
+ * @return The routing info.
+ */
+ public RoutingInfo getRoutingInfo() {
+ return this.router.getRoutingInfo();
+ }
/**
* Returns the interface objects of the node
@@ -266,7 +266,7 @@ public NetworkInterface getInterface(int interfaceNo) {
try {
ni = net.get(interfaceNo-1);
} catch (IndexOutOfBoundsException ex) {
- throw new SimError("No such interface: "+interfaceNo +
+ throw new SimError("No such interface: "+interfaceNo +
" at " + this);
}
return ni;
@@ -281,13 +281,13 @@ protected NetworkInterface getInterface(String interfacetype) {
return ni;
}
}
- return null;
+ return null;
}
/**
* Force a connection event
*/
- public void forceConnection(DTNHost anotherHost, String interfaceId,
+ public void forceConnection(DTNHost anotherHost, String interfaceId,
boolean up) {
NetworkInterface ni;
NetworkInterface no;
@@ -301,11 +301,11 @@ public void forceConnection(DTNHost anotherHost, String interfaceId,
} else {
ni = getInterface(1);
no = anotherHost.getInterface(1);
-
- assert (ni.getInterfaceType().equals(no.getInterfaceType())) :
+
+ assert (ni.getInterfaceType().equals(no.getInterfaceType())) :
"Interface types do not match. Please specify interface type explicitly";
}
-
+
if (up) {
ni.createConnection(no);
} else {
@@ -323,25 +323,25 @@ public void connect(DTNHost h) {
}
/**
- * Updates node's network layer and router.
+ * Updates node's network layer and router.
* @param simulateConnections Should network layer be updated too
- */
+ */
public void update(boolean simulateConnections) {
if (!isRadioActive()) {
// Make sure inactive nodes don't have connections
tearDownAllConnections();
return;
}
-
+
if (simulateConnections) {
for (NetworkInterface i : net) {
i.update();
}
}
- this.router.update();
+ this.router.update();
}
-
- /**
+
+ /**
* Tears down all connections for this host.
*/
private void tearDownAllConnections() {
@@ -349,7 +349,7 @@ private void tearDownAllConnections() {
// Get all connections for the interface
List conns = i.getConnections();
if (conns.size() == 0) continue;
-
+
// Destroy all connections
List removeList =
new ArrayList(conns.size());
@@ -360,177 +360,177 @@ private void tearDownAllConnections() {
i.destroyConnection(inf);
}
}
- }
-
- /**
- * Moves the node towards the next waypoint or waits if it is
- * not time to move yet
- * @param timeIncrement How long time the node moves
- */
- public void move(double timeIncrement) {
+ }
+
+ /**
+ * Moves the node towards the next waypoint or waits if it is
+ * not time to move yet
+ * @param timeIncrement How long time the node moves
+ */
+ public void move(double timeIncrement) {
double possibleMovement;
double distance;
double dx, dy;
- if (!isMovementActive() || SimClock.getTime() < this.nextTimeToMove) {
- return;
- }
- if (this.destination == null) {
- if (!setNextWaypoint()) {
- return;
- }
- }
-
- possibleMovement = timeIncrement * speed;
- distance = this.location.distance(this.destination);
-
- while (possibleMovement >= distance) {
- // node can move past its next destination
- this.location.setLocation(this.destination); // snap to destination
- possibleMovement -= distance;
- if (!setNextWaypoint()) { // get a new waypoint
- return; // no more waypoints left
- }
- distance = this.location.distance(this.destination);
- }
-
- // move towards the point for possibleMovement amount
- dx = (possibleMovement/distance) * (this.destination.getX() -
- this.location.getX());
- dy = (possibleMovement/distance) * (this.destination.getY() -
- this.location.getY());
- this.location.translate(dx, dy);
- }
-
- /**
- * Sets the next destination and speed to correspond the next waypoint
- * on the path.
- * @return True if there was a next waypoint to set, false if node still
- * should wait
- */
- private boolean setNextWaypoint() {
- if (path == null) {
- path = movement.getPath();
- }
-
- if (path == null || !path.hasNext()) {
- this.nextTimeToMove = movement.nextPathAvailable();
- this.path = null;
- return false;
- }
-
- this.destination = path.getNextWaypoint();
- this.speed = path.getSpeed();
-
- if (this.movListeners != null) {
- for (MovementListener l : this.movListeners) {
- l.newDestination(this, this.destination, this.speed);
- }
- }
-
- return true;
- }
-
- /**
- * Sends a message from this host to another host
- * @param id Identifier of the message
- * @param to Host the message should be sent to
- */
- public void sendMessage(String id, DTNHost to) {
- this.router.sendMessage(id, to);
- }
-
- /**
- * Start receiving a message from another host
- * @param m The message
- * @param from Who the message is from
- * @return The value returned by
- * {@link MessageRouter#receiveMessage(Message, DTNHost)}
- */
- public int receiveMessage(Message m, DTNHost from) {
- int retVal = this.router.receiveMessage(m, from);
+ if (!isMovementActive() || SimClock.getTime() < this.nextTimeToMove) {
+ return;
+ }
+ if (this.destination == null) {
+ if (!setNextWaypoint()) {
+ return;
+ }
+ }
+
+ possibleMovement = timeIncrement * speed;
+ distance = this.location.distance(this.destination);
+
+ while (possibleMovement >= distance) {
+ // node can move past its next destination
+ this.location.setLocation(this.destination); // snap to destination
+ possibleMovement -= distance;
+ if (!setNextWaypoint()) { // get a new waypoint
+ return; // no more waypoints left
+ }
+ distance = this.location.distance(this.destination);
+ }
+
+ // move towards the point for possibleMovement amount
+ dx = (possibleMovement/distance) * (this.destination.getX() -
+ this.location.getX());
+ dy = (possibleMovement/distance) * (this.destination.getY() -
+ this.location.getY());
+ this.location.translate(dx, dy);
+ }
+
+ /**
+ * Sets the next destination and speed to correspond the next waypoint
+ * on the path.
+ * @return True if there was a next waypoint to set, false if node still
+ * should wait
+ */
+ private boolean setNextWaypoint() {
+ if (path == null) {
+ path = movement.getPath();
+ }
+
+ if (path == null || !path.hasNext()) {
+ this.nextTimeToMove = movement.nextPathAvailable();
+ this.path = null;
+ return false;
+ }
+
+ this.destination = path.getNextWaypoint();
+ this.speed = path.getSpeed();
+
+ if (this.movListeners != null) {
+ for (MovementListener l : this.movListeners) {
+ l.newDestination(this, this.destination, this.speed);
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Sends a message from this host to another host
+ * @param id Identifier of the message
+ * @param to Host the message should be sent to
+ */
+ public void sendMessage(String id, DTNHost to) {
+ this.router.sendMessage(id, to);
+ }
+
+ /**
+ * Start receiving a message from another host
+ * @param m The message
+ * @param from Who the message is from
+ * @return The value returned by
+ * {@link MessageRouter#receiveMessage(Message, DTNHost)}
+ */
+ public int receiveMessage(Message m, DTNHost from) {
+ int retVal = this.router.receiveMessage(m, from);
if (retVal == MessageRouter.RCV_OK) {
m.addNodeOnPath(this); // add this node on the messages path
}
- return retVal;
- }
-
- /**
- * Requests for deliverable message from this host to be sent trough a
- * connection.
- * @param con The connection to send the messages trough
- * @return True if this host started a transfer, false if not
- */
- public boolean requestDeliverableMessages(Connection con) {
- return this.router.requestDeliverableMessages(con);
- }
-
- /**
- * Informs the host that a message was successfully transferred.
- * @param id Identifier of the message
- * @param from From who the message was from
- */
- public void messageTransferred(String id, DTNHost from) {
- this.router.messageTransferred(id, from);
- }
-
- /**
- * Informs the host that a message transfer was aborted.
- * @param id Identifier of the message
+ return retVal;
+ }
+
+ /**
+ * Requests for deliverable message from this host to be sent trough a
+ * connection.
+ * @param con The connection to send the messages trough
+ * @return True if this host started a transfer, false if not
+ */
+ public boolean requestDeliverableMessages(Connection con) {
+ return this.router.requestDeliverableMessages(con);
+ }
+
+ /**
+ * Informs the host that a message was successfully transferred.
+ * @param id Identifier of the message
+ * @param from From who the message was from
+ */
+ public void messageTransferred(String id, DTNHost from) {
+ this.router.messageTransferred(id, from);
+ }
+
+ /**
+ * Informs the host that a message transfer was aborted.
+ * @param id Identifier of the message
* @param from From who the message was from
* @param bytesRemaining Nrof bytes that were left before the transfer
- * would have been ready; or -1 if the number of bytes is not known
- */
- public void messageAborted(String id, DTNHost from, int bytesRemaining) {
- this.router.messageAborted(id, from, bytesRemaining);
- }
-
- /**
+ * would have been ready; or -1 if the number of bytes is not known
+ */
+ public void messageAborted(String id, DTNHost from, int bytesRemaining) {
+ this.router.messageAborted(id, from, bytesRemaining);
+ }
+
+ /**
* Creates a new message to this host's router
- * @param m The message to create
- */
+ * @param m The message to create
+ */
public void createNewMessage(Message m) {
- this.router.createNewMessage(m);
- }
-
- /**
- * Deletes a message from this host
- * @param id Identifier of the message
- * @param drop True if the message is deleted because of "dropping"
- * (e.g. buffer is full) or false if it was deleted for some other reason
- * (e.g. the message got delivered to final destination). This effects the
- * way the removing is reported to the message listeners.
- */
- public void deleteMessage(String id, boolean drop) {
- this.router.deleteMessage(id, drop);
- }
-
- /**
- * Returns a string presentation of the host.
- * @return Host's name
- */
- public String toString() {
- return name;
- }
-
- /**
+ this.router.createNewMessage(m);
+ }
+
+ /**
+ * Deletes a message from this host
+ * @param id Identifier of the message
+ * @param drop True if the message is deleted because of "dropping"
+ * (e.g. buffer is full) or false if it was deleted for some other reason
+ * (e.g. the message got delivered to final destination). This effects the
+ * way the removing is reported to the message listeners.
+ */
+ public void deleteMessage(String id, boolean drop) {
+ this.router.deleteMessage(id, drop);
+ }
+
+ /**
+ * Returns a string presentation of the host.
+ * @return Host's name
+ */
+ public String toString() {
+ return name;
+ }
+
+ /**
* Checks if a host is the same as this host by comparing the object
- * reference
- * @param otherHost The other host
- * @return True if the hosts objects are the same object
- */
- public boolean equals(DTNHost otherHost) {
- return this == otherHost;
- }
-
- /**
- * Compares two DTNHosts by their addresses.
- * @see Comparable#compareTo(Object)
- */
- public int compareTo(DTNHost h) {
- return this.getAddress() - h.getAddress();
- }
-
-}
+ * reference
+ * @param otherHost The other host
+ * @return True if the hosts objects are the same object
+ */
+ public boolean equals(DTNHost otherHost) {
+ return this == otherHost;
+ }
+
+ /**
+ * Compares two DTNHosts by their addresses.
+ * @see Comparable#compareTo(Object)
+ */
+ public int compareTo(DTNHost h) {
+ return this.getAddress() - h.getAddress();
+ }
+
+}
diff --git a/core/DTNSim.java b/core/DTNSim.java
index bfa3307e7..cd91a6477 100644
--- a/core/DTNSim.java
+++ b/core/DTNSim.java
@@ -1,6 +1,6 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
package core;
import gui.DTNSimGUI;
@@ -10,32 +10,32 @@
import java.util.List;
import ui.DTNSimTextUI;
-
-/**
- * Simulator's main class
- */
-public class DTNSim {
- /** If this option ({@value}) is given to program, batch mode and
- * Text UI are used*/
+
+/**
+ * Simulator's main class
+ */
+public class DTNSim {
+ /** If this option ({@value}) is given to program, batch mode and
+ * Text UI are used*/
public static final String BATCH_MODE_FLAG = "-b";
/** Delimiter for batch mode index range values (colon) */
public static final String RANGE_DELIMETER = ":";
-
+
/** Name of the static method that all resettable classes must have
* @see #registerForReset(String) */
public static final String RESET_METHOD_NAME = "reset";
/** List of class names that should be reset between batch runs */
private static List> resetList = new ArrayList>();
-
+
/**
* Starts the user interface with given arguments.
* If first argument is {@link #BATCH_MODE_FLAG}, the batch mode and text UI
* is started. The batch mode option must be followed by the number of runs,
- * or a with a combination of starting run and the number of runs,
+ * or a with a combination of starting run and the number of runs,
* delimited with a {@value #RANGE_DELIMETER}. Different settings from run
- * arrays are used for different runs (see
- * {@link Settings#setRunIndex(int)}). Following arguments are the settings
- * files for the simulation run (if any). For GUI mode, the number before
+ * arrays are used for different runs (see
+ * {@link Settings#setRunIndex(int)}). Following arguments are the settings
+ * files for the simulation run (if any). For GUI mode, the number before
* settings files (if given) is the run index to use for that run.
* @param args Command line arguments
*/
@@ -48,7 +48,7 @@ public static void main(String[] args) {
/* set US locale to parse decimals in consistent way */
java.util.Locale.setDefault(java.util.Locale.US);
-
+
if (args.length > 0) {
if (args[0].equals(BATCH_MODE_FLAG)) {
batchMode = true;
@@ -60,7 +60,7 @@ public static void main(String[] args) {
firstConfIndex = 2;
}
}
- else { /* GUI mode */
+ else { /* GUI mode */
try { /* is there a run index for the GUI mode ? */
guiIndex = Integer.parseInt(args[0]);
firstConfIndex = 1;
@@ -73,9 +73,9 @@ public static void main(String[] args) {
else {
confFiles = new String[] {null};
}
-
+
initSettings(confFiles, firstConfIndex);
-
+
if (batchMode) {
long startTime = System.currentTimeMillis();
for (int i=nrofRuns[0]; icore.SimClock
+ * @param className Full name (i.e., containing the packet path)
+ * of the class to register. For example: core.SimClock
*/
public static void registerForReset(String className) {
Class> c = null;
@@ -146,19 +146,19 @@ public static void registerForReset(String className) {
c = Class.forName(className);
c.getMethod(RESET_METHOD_NAME);
} catch (ClassNotFoundException e) {
- System.err.println("Can't register class " + className +
+ System.err.println("Can't register class " + className +
" for resetting; class not found");
System.exit(-1);
-
+
}
catch (NoSuchMethodException e) {
- System.err.println("Can't register class " + className +
+ System.err.println("Can't register class " + className +
" for resetting; class doesn't contain resetting method");
System.exit(-1);
}
resetList.add(c);
}
-
+
/**
* Resets all registered classes.
*/
@@ -174,18 +174,18 @@ private static void resetForNextRun() {
}
}
}
-
+
/**
- * Parses the number of runs, and an optional starting run index, from a
+ * Parses the number of runs, and an optional starting run index, from a
* command line argument
* @param arg The argument to parse
* @return The first and (last_run_index - 1) in an array
*/
private static int[] parseNrofRuns(String arg) {
- int val[] = {0,1};
+ int val[] = {0,1};
try {
if (arg.contains(RANGE_DELIMETER)) {
- val[0] = Integer.parseInt(arg.substring(0,
+ val[0] = Integer.parseInt(arg.substring(0,
arg.indexOf(RANGE_DELIMETER))) - 1;
val[1] = Integer.parseInt(arg.substring(arg.
indexOf(RANGE_DELIMETER) + 1, arg.length()));
@@ -193,29 +193,29 @@ private static int[] parseNrofRuns(String arg) {
else {
val[0] = 0;
val[1] = Integer.parseInt(arg);
- }
+ }
} catch (NumberFormatException e) {
System.err.println("Invalid argument '" + arg + "' for" +
" number of runs");
- System.err.println("The argument must be either a single value, " +
- "or a range of values (e.g., '2:5'). Note that this " +
+ System.err.println("The argument must be either a single value, " +
+ "or a range of values (e.g., '2:5'). Note that this " +
"option has changed in version 1.3.");
System.exit(-1);
}
-
+
if (val[0] < 0) {
System.err.println("Starting run value can't be smaller than 1");
System.exit(-1);
}
if (val[0] >= val[1]) {
- System.err.println("Starting run value can't be bigger than the " +
+ System.err.println("Starting run value can't be bigger than the " +
"last run value");
- System.exit(-1);
+ System.exit(-1);
}
-
+
return val;
}
-
+
/**
* Prints text to stdout
* @param txt Text to print
diff --git a/core/Debug.java b/core/Debug.java
index 722b79fde..b0546a1f9 100644
--- a/core/Debug.java
+++ b/core/Debug.java
@@ -1,115 +1,115 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package core;
-
+package core;
+
import java.io.PrintStream;
-
-/**
- * Debugging info printer with time stamping. This class is not to be actively
- * used but convenient for temporary debugging.
- */
-public class Debug {
- private static PrintStream out = System.out;
- private static int debugLevel = 0;
- private static long timingStart = -1;
- private static String timingCause;
-
- /**
- * Sets the current debug level (smaller level -> more messages)
- * @param level The level to set
- */
- public void setDebugLevel(int level) {
- debugLevel = level;
- }
-
- /**
- * Sets print stream of debug output.
- * @param outStrm The stream
- */
- public void setPrintStream(PrintStream outStrm) {
- out = outStrm;
- }
-
- /**
- * Prints text to output with level 0
- * @param txt text to print
- */
- public static void p(String txt) {
- p(txt, 0, false);
- }
-
- /**
- * Prints text to output given with level
- * @param level The debug level
- * @param txt text to print
- */
- public static void p(String txt, int level) {
- p(txt,level, false);
- }
-
-
- /**
- * Debug print with a timestamp
- * @param txt Text to print
- * @param level Debug level
- */
- public static void pt(String txt, int level) {
- p(txt,level,true);
- }
-
- /**
- * Debug print with a timestamp and 0 level
- * @param txt Text to print
- */
- public static void pt(String txt) {
- p(txt,0,true);
- }
-
- /**
- * Print text to debug output.
- * @param txt The text to print
- * @param level The debug level (only messages with level >= debugLevel
- * are printed)
- * @param timestamp If true, text is (sim)timestamped
- */
- public static void p(String txt, int level, boolean timestamp) {
- String time = "";
- int simTime = SimClock.getIntTime();
- if (level < debugLevel) {
- return;
- }
-
- if (timestamp) {
- time = "[@"+simTime+"]";
- }
- out.println("D" + time + ": " + txt);
- }
-
- /**
- * Start timing an action.
- * @see #doneTiming()
- */
- public static void startTiming(String cause) {
- if (timingStart != -1) {
- doneTiming();
- }
- timingCause = cause;
- timingStart = System.currentTimeMillis();
- }
-
- /**
- * End timing an action. Information how long the action took is
- * printed to debug stream.
- * @see #startTiming(String)
- */
- public static void doneTiming() {
- long end = System.currentTimeMillis();
- long diff = end-timingStart;
- if (end-timingStart > 0)
- pt(timingCause + " took "+ diff/1000.0 + "s" );
-
- timingStart = -1;
- }
-}
+
+/**
+ * Debugging info printer with time stamping. This class is not to be actively
+ * used but convenient for temporary debugging.
+ */
+public class Debug {
+ private static PrintStream out = System.out;
+ private static int debugLevel = 0;
+ private static long timingStart = -1;
+ private static String timingCause;
+
+ /**
+ * Sets the current debug level (smaller level -> more messages)
+ * @param level The level to set
+ */
+ public void setDebugLevel(int level) {
+ debugLevel = level;
+ }
+
+ /**
+ * Sets print stream of debug output.
+ * @param outStrm The stream
+ */
+ public void setPrintStream(PrintStream outStrm) {
+ out = outStrm;
+ }
+
+ /**
+ * Prints text to output with level 0
+ * @param txt text to print
+ */
+ public static void p(String txt) {
+ p(txt, 0, false);
+ }
+
+ /**
+ * Prints text to output given with level
+ * @param level The debug level
+ * @param txt text to print
+ */
+ public static void p(String txt, int level) {
+ p(txt,level, false);
+ }
+
+
+ /**
+ * Debug print with a timestamp
+ * @param txt Text to print
+ * @param level Debug level
+ */
+ public static void pt(String txt, int level) {
+ p(txt,level,true);
+ }
+
+ /**
+ * Debug print with a timestamp and 0 level
+ * @param txt Text to print
+ */
+ public static void pt(String txt) {
+ p(txt,0,true);
+ }
+
+ /**
+ * Print text to debug output.
+ * @param txt The text to print
+ * @param level The debug level (only messages with level >= debugLevel
+ * are printed)
+ * @param timestamp If true, text is (sim)timestamped
+ */
+ public static void p(String txt, int level, boolean timestamp) {
+ String time = "";
+ int simTime = SimClock.getIntTime();
+ if (level < debugLevel) {
+ return;
+ }
+
+ if (timestamp) {
+ time = "[@"+simTime+"]";
+ }
+ out.println("D" + time + ": " + txt);
+ }
+
+ /**
+ * Start timing an action.
+ * @see #doneTiming()
+ */
+ public static void startTiming(String cause) {
+ if (timingStart != -1) {
+ doneTiming();
+ }
+ timingCause = cause;
+ timingStart = System.currentTimeMillis();
+ }
+
+ /**
+ * End timing an action. Information how long the action took is
+ * printed to debug stream.
+ * @see #startTiming(String)
+ */
+ public static void doneTiming() {
+ long end = System.currentTimeMillis();
+ long diff = end-timingStart;
+ if (end-timingStart > 0)
+ pt(timingCause + " took "+ diff/1000.0 + "s" );
+
+ timingStart = -1;
+ }
+}
diff --git a/core/Message.java b/core/Message.java
index 60b48b75e..d037b890b 100644
--- a/core/Message.java
+++ b/core/Message.java
@@ -1,268 +1,268 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package core;
-
+package core;
+
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
-
-/**
- * A message that is created at a node or passed between nodes.
- */
-public class Message implements Comparable {
- /** Value for infinite TTL of message */
- public static final int INFINITE_TTL = -1;
- private DTNHost from;
- private DTNHost to;
- /** Identifier of the message */
- private String id;
- /** Size of the message (bytes) */
- private int size;
- /** List of nodes this message has passed */
- private List path;
- /** Next unique identifier to be given */
- private static int nextUniqueId;
- /** Unique ID of this message */
- private int uniqueId;
- /** The time this message was received */
- private double timeReceived;
- /** The time when this message was created */
- private double timeCreated;
- /** Initial TTL of the message */
- private int initTtl;
-
- /** if a response to this message is required, this is the size of the
- * response message (or 0 if no response is requested) */
- private int responseSize;
- /** if this message is a response message, this is set to the request msg*/
+
+/**
+ * A message that is created at a node or passed between nodes.
+ */
+public class Message implements Comparable {
+ /** Value for infinite TTL of message */
+ public static final int INFINITE_TTL = -1;
+ private DTNHost from;
+ private DTNHost to;
+ /** Identifier of the message */
+ private String id;
+ /** Size of the message (bytes) */
+ private int size;
+ /** List of nodes this message has passed */
+ private List path;
+ /** Next unique identifier to be given */
+ private static int nextUniqueId;
+ /** Unique ID of this message */
+ private int uniqueId;
+ /** The time this message was received */
+ private double timeReceived;
+ /** The time when this message was created */
+ private double timeCreated;
+ /** Initial TTL of the message */
+ private int initTtl;
+
+ /** if a response to this message is required, this is the size of the
+ * response message (or 0 if no response is requested) */
+ private int responseSize;
+ /** if this message is a response message, this is set to the request msg*/
private Message requestMsg;
-
+
/** Container for generic message properties. Note that all values
* stored in the properties should be immutable because only a shallow
* copy of the properties is made when replicating messages */
- private Map properties;
-
+ private Map properties;
+
/** Application ID of the application that created the message */
private String appID;
-
- static {
+
+ static {
reset();
- DTNSim.registerForReset(Message.class.getCanonicalName());
- }
-
- /**
- * Creates a new Message.
- * @param from Who the message is (originally) from
- * @param to Who the message is (originally) to
- * @param id Message identifier (must be unique for message but
- * will be the same for all replicates of the message)
- * @param size Size of the message (in bytes)
- */
- public Message(DTNHost from, DTNHost to, String id, int size) {
- this.from = from;
- this.to = to;
- this.id = id;
- this.size = size;
- this.path = new ArrayList();
- this.uniqueId = nextUniqueId;
-
- this.timeCreated = SimClock.getTime();
- this.timeReceived = this.timeCreated;
- this.initTtl = INFINITE_TTL;
- this.responseSize = 0;
- this.requestMsg = null;
+ DTNSim.registerForReset(Message.class.getCanonicalName());
+ }
+
+ /**
+ * Creates a new Message.
+ * @param from Who the message is (originally) from
+ * @param to Who the message is (originally) to
+ * @param id Message identifier (must be unique for message but
+ * will be the same for all replicates of the message)
+ * @param size Size of the message (in bytes)
+ */
+ public Message(DTNHost from, DTNHost to, String id, int size) {
+ this.from = from;
+ this.to = to;
+ this.id = id;
+ this.size = size;
+ this.path = new ArrayList();
+ this.uniqueId = nextUniqueId;
+
+ this.timeCreated = SimClock.getTime();
+ this.timeReceived = this.timeCreated;
+ this.initTtl = INFINITE_TTL;
+ this.responseSize = 0;
+ this.requestMsg = null;
this.properties = null;
this.appID = null;
-
- Message.nextUniqueId++;
- addNodeOnPath(from);
- }
-
- /**
- * Returns the node this message is originally from
- * @return the node this message is originally from
- */
- public DTNHost getFrom() {
- return this.from;
- }
-
- /**
- * Returns the node this message is originally to
- * @return the node this message is originally to
- */
- public DTNHost getTo() {
- return this.to;
- }
-
- /**
- * Returns the ID of the message
- * @return The message id
- */
- public String getId() {
- return this.id;
- }
-
- /**
- * Returns an ID that is unique per message instance
- * (different for replicates too)
- * @return The unique id
- */
- public int getUniqueId() {
- return this.uniqueId;
- }
-
- /**
- * Returns the size of the message (in bytes)
- * @return the size of the message
- */
- public int getSize() {
- return this.size;
- }
-
- /**
- * Adds a new node on the list of nodes this message has passed
- * @param node The node to add
- */
- public void addNodeOnPath(DTNHost node) {
- this.path.add(node);
- }
-
- /**
- * Returns a list of nodes this message has passed so far
- * @return The list as vector
- */
- public List getHops() {
- return this.path;
- }
-
- /**
- * Returns the amount of hops this message has passed
- * @return the amount of hops this message has passed
- */
- public int getHopCount() {
- return this.path.size() -1;
- }
-
- /**
- * Returns the time to live (minutes) of the message or Integer.MAX_VALUE
- * if the TTL is infinite. Returned value can be negative if the TTL has
- * passed already.
- * @return The TTL (minutes)
- */
- public int getTtl() {
- if (this.initTtl == INFINITE_TTL) {
- return Integer.MAX_VALUE;
- }
- else {
- return (int)( ((this.initTtl * 60) -
- (SimClock.getTime()-this.timeCreated)) /60.0 );
- }
- }
-
-
+
+ Message.nextUniqueId++;
+ addNodeOnPath(from);
+ }
+
+ /**
+ * Returns the node this message is originally from
+ * @return the node this message is originally from
+ */
+ public DTNHost getFrom() {
+ return this.from;
+ }
+
+ /**
+ * Returns the node this message is originally to
+ * @return the node this message is originally to
+ */
+ public DTNHost getTo() {
+ return this.to;
+ }
+
+ /**
+ * Returns the ID of the message
+ * @return The message id
+ */
+ public String getId() {
+ return this.id;
+ }
+
+ /**
+ * Returns an ID that is unique per message instance
+ * (different for replicates too)
+ * @return The unique id
+ */
+ public int getUniqueId() {
+ return this.uniqueId;
+ }
+
+ /**
+ * Returns the size of the message (in bytes)
+ * @return the size of the message
+ */
+ public int getSize() {
+ return this.size;
+ }
+
+ /**
+ * Adds a new node on the list of nodes this message has passed
+ * @param node The node to add
+ */
+ public void addNodeOnPath(DTNHost node) {
+ this.path.add(node);
+ }
+
+ /**
+ * Returns a list of nodes this message has passed so far
+ * @return The list as vector
+ */
+ public List getHops() {
+ return this.path;
+ }
+
+ /**
+ * Returns the amount of hops this message has passed
+ * @return the amount of hops this message has passed
+ */
+ public int getHopCount() {
+ return this.path.size() -1;
+ }
+
+ /**
+ * Returns the time to live (minutes) of the message or Integer.MAX_VALUE
+ * if the TTL is infinite. Returned value can be negative if the TTL has
+ * passed already.
+ * @return The TTL (minutes)
+ */
+ public int getTtl() {
+ if (this.initTtl == INFINITE_TTL) {
+ return Integer.MAX_VALUE;
+ }
+ else {
+ return (int)( ((this.initTtl * 60) -
+ (SimClock.getTime()-this.timeCreated)) /60.0 );
+ }
+ }
+
+
/**
* Sets the initial TTL (time-to-live) for this message. The initial
* TTL is the TTL when the original message was created. The current TTL
- * is calculated based on the time of
+ * is calculated based on the time of
* @param ttl The time-to-live to set
*/
public void setTtl(int ttl) {
this.initTtl = ttl;
}
-
- /**
- * Sets the time when this message was received.
- * @param time The time to set
- */
- public void setReceiveTime(double time) {
- this.timeReceived = time;
- }
-
- /**
- * Returns the time when this message was received
- * @return The time
- */
- public double getReceiveTime() {
- return this.timeReceived;
- }
-
- /**
- * Returns the time when this message was created
- * @return the time when this message was created
- */
- public double getCreationTime() {
- return this.timeCreated;
- }
-
- /**
- * If this message is a response to a request, sets the request message
- * @param request The request message
- */
- public void setRequest(Message request) {
- this.requestMsg = request;
- }
-
- /**
- * Returns the message this message is response to or null if this is not
- * a response message
- * @return the message this message is response to
- */
- public Message getRequest() {
- return this.requestMsg;
- }
-
- /**
- * Returns true if this message is a response message
- * @return true if this message is a response message
- */
- public boolean isResponse() {
- return this.requestMsg != null;
- }
-
- /**
- * Sets the requested response message's size. If size == 0, no response
- * is requested (default)
- * @param size Size of the response message
- */
- public void setResponseSize(int size) {
- this.responseSize = size;
- }
-
- /**
- * Returns the size of the requested response message or 0 if no response
- * is requested.
- * @return the size of the requested response message
- */
- public int getResponseSize() {
- return responseSize;
- }
-
- /**
- * Returns a string representation of the message
- * @return a string representation of the message
- */
- public String toString () {
- return id;
- }
-
- /**
- * Deep copies message data from other message. If new fields are
- * introduced to this class, most likely they should be copied here too
- * (unless done in constructor).
- * @param m The message where the data is copied
- */
- protected void copyFrom(Message m) {
- this.path = new ArrayList(m.path);
- this.timeCreated = m.timeCreated;
- this.responseSize = m.responseSize;
+
+ /**
+ * Sets the time when this message was received.
+ * @param time The time to set
+ */
+ public void setReceiveTime(double time) {
+ this.timeReceived = time;
+ }
+
+ /**
+ * Returns the time when this message was received
+ * @return The time
+ */
+ public double getReceiveTime() {
+ return this.timeReceived;
+ }
+
+ /**
+ * Returns the time when this message was created
+ * @return the time when this message was created
+ */
+ public double getCreationTime() {
+ return this.timeCreated;
+ }
+
+ /**
+ * If this message is a response to a request, sets the request message
+ * @param request The request message
+ */
+ public void setRequest(Message request) {
+ this.requestMsg = request;
+ }
+
+ /**
+ * Returns the message this message is response to or null if this is not
+ * a response message
+ * @return the message this message is response to
+ */
+ public Message getRequest() {
+ return this.requestMsg;
+ }
+
+ /**
+ * Returns true if this message is a response message
+ * @return true if this message is a response message
+ */
+ public boolean isResponse() {
+ return this.requestMsg != null;
+ }
+
+ /**
+ * Sets the requested response message's size. If size == 0, no response
+ * is requested (default)
+ * @param size Size of the response message
+ */
+ public void setResponseSize(int size) {
+ this.responseSize = size;
+ }
+
+ /**
+ * Returns the size of the requested response message or 0 if no response
+ * is requested.
+ * @return the size of the requested response message
+ */
+ public int getResponseSize() {
+ return responseSize;
+ }
+
+ /**
+ * Returns a string representation of the message
+ * @return a string representation of the message
+ */
+ public String toString () {
+ return id;
+ }
+
+ /**
+ * Deep copies message data from other message. If new fields are
+ * introduced to this class, most likely they should be copied here too
+ * (unless done in constructor).
+ * @param m The message where the data is copied
+ */
+ protected void copyFrom(Message m) {
+ this.path = new ArrayList(m.path);
+ this.timeCreated = m.timeCreated;
+ this.responseSize = m.responseSize;
this.requestMsg = m.requestMsg;
this.initTtl = m.initTtl;
this.appID = m.appID;
-
+
if (m.properties != null) {
Set keys = m.properties.keySet();
for (String key : keys) {
@@ -270,13 +270,13 @@ protected void copyFrom(Message m) {
}
}
}
-
+
/**
- * Adds a generic property for this message. The key can be any string but
+ * Adds a generic property for this message. The key can be any string but
* it should be such that no other class accidently uses the same value.
* The value can be any object but it's good idea to store only immutable
* objects because when message is replicated, only a shallow copy of the
- * properties is made.
+ * properties is made.
* @param key The key which is used to lookup the value
* @param value The value to store
* @throws SimError if the message already has a value for the given key
@@ -284,13 +284,13 @@ protected void copyFrom(Message m) {
public void addProperty(String key, Object value) throws SimError {
if (this.properties != null && this.properties.containsKey(key)) {
/* check to prevent accidental name space collisions */
- throw new SimError("Message " + this + " already contains value " +
+ throw new SimError("Message " + this + " already contains value " +
"for a key " + key);
}
-
+
this.updateProperty(key, value);
}
-
+
/**
* Returns an object that was stored to this message using the given
* key. If such object is not found, null is returned.
@@ -303,9 +303,9 @@ public Object getProperty(String key) {
}
return this.properties.get(key);
}
-
+
/**
- * Updates a value for an existing property. For storing the value first
+ * Updates a value for an existing property. For storing the value first
* time, {@link #addProperty(String, Object)} should be used which
* checks for name space clashes.
* @param key The key which is used to lookup the value
@@ -316,34 +316,34 @@ public void updateProperty(String key, Object value) throws SimError {
/* lazy creation to prevent performance overhead for classes
that don't use the property feature */
this.properties = new HashMap();
- }
+ }
this.properties.put(key, value);
- }
-
- /**
- * Returns a replicate of this message (identical except for the unique id)
- * @return A replicate of the message
- */
- public Message replicate() {
- Message m = new Message(from, to, id, size);
- m.copyFrom(this);
- return m;
- }
-
- /**
- * Compares two messages by their ID (alphabetically).
- * @see String#compareTo(String)
- */
- public int compareTo(Message m) {
- return toString().compareTo(m.toString());
- }
-
- /**
- * Resets all static fields to default values
- */
- public static void reset() {
- nextUniqueId = 0;
+ }
+
+ /**
+ * Returns a replicate of this message (identical except for the unique id)
+ * @return A replicate of the message
+ */
+ public Message replicate() {
+ Message m = new Message(from, to, id, size);
+ m.copyFrom(this);
+ return m;
+ }
+
+ /**
+ * Compares two messages by their ID (alphabetically).
+ * @see String#compareTo(String)
+ */
+ public int compareTo(Message m) {
+ return toString().compareTo(m.toString());
+ }
+
+ /**
+ * Resets all static fields to default values
+ */
+ public static void reset() {
+ nextUniqueId = 0;
}
/**
@@ -358,6 +358,6 @@ public String getAppID() {
*/
public void setAppID(String appID) {
this.appID = appID;
- }
-
-}
+ }
+
+}
diff --git a/core/MessageListener.java b/core/MessageListener.java
index f4ee2048d..43e651d1b 100644
--- a/core/MessageListener.java
+++ b/core/MessageListener.java
@@ -1,56 +1,56 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package core;
-
-/**
- * Interface for classes that want to be informed about messages
- * between hosts
- *
- */
-public interface MessageListener {
-
- /**
- * Method is called when a new message is created
- * @param m Message that was created
- */
- public void newMessage(Message m);
-
- /**
- * Method is called when a message's transfer is started
- * @param m The message that is going to be transferred
- * @param from Node where the message is transferred from
- * @param to Node where the message is transferred to
- */
- public void messageTransferStarted(Message m, DTNHost from, DTNHost to);
-
- /**
- * Method is called when a message is deleted
- * @param m The message that was deleted
- * @param where The host where the message was deleted
- * @param dropped True if the message was dropped, false if removed
- */
- public void messageDeleted(Message m, DTNHost where, boolean dropped);
-
- /**
- * Method is called when a message's transfer was aborted before
- * it finished
- * @param m The message that was being transferred
- * @param from Node where the message was being transferred from
- * @param to Node where the message was being transferred to
- */
- public void messageTransferAborted(Message m, DTNHost from, DTNHost to);
-
- /**
- * Method is called when a message is successfully transferred from
- * a node to another.
- * @param m The message that was transferred
- * @param from Node where the message was transferred from
- * @param to Node where the message was transferred to
- * @param firstDelivery Was the target node final destination of the message
- * and received this message for the first time.
- */
- public void messageTransferred(Message m, DTNHost from, DTNHost to,
- boolean firstDelivery);
-}
+package core;
+
+/**
+ * Interface for classes that want to be informed about messages
+ * between hosts
+ *
+ */
+public interface MessageListener {
+
+ /**
+ * Method is called when a new message is created
+ * @param m Message that was created
+ */
+ public void newMessage(Message m);
+
+ /**
+ * Method is called when a message's transfer is started
+ * @param m The message that is going to be transferred
+ * @param from Node where the message is transferred from
+ * @param to Node where the message is transferred to
+ */
+ public void messageTransferStarted(Message m, DTNHost from, DTNHost to);
+
+ /**
+ * Method is called when a message is deleted
+ * @param m The message that was deleted
+ * @param where The host where the message was deleted
+ * @param dropped True if the message was dropped, false if removed
+ */
+ public void messageDeleted(Message m, DTNHost where, boolean dropped);
+
+ /**
+ * Method is called when a message's transfer was aborted before
+ * it finished
+ * @param m The message that was being transferred
+ * @param from Node where the message was being transferred from
+ * @param to Node where the message was being transferred to
+ */
+ public void messageTransferAborted(Message m, DTNHost from, DTNHost to);
+
+ /**
+ * Method is called when a message is successfully transferred from
+ * a node to another.
+ * @param m The message that was transferred
+ * @param from Node where the message was transferred from
+ * @param to Node where the message was transferred to
+ * @param firstDelivery Was the target node final destination of the message
+ * and received this message for the first time.
+ */
+ public void messageTransferred(Message m, DTNHost from, DTNHost to,
+ boolean firstDelivery);
+}
diff --git a/core/ModuleCommunicationBus.java b/core/ModuleCommunicationBus.java
index d15177e17..bb2f02759 100644
--- a/core/ModuleCommunicationBus.java
+++ b/core/ModuleCommunicationBus.java
@@ -1,19 +1,19 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package core;
+package core;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
-
-/**
+
+/**
* Intermodule communication bus. Works as a blackboard where modules can
* post data, subscribe to data changes and also poll for data values.
* This is fairly similar to Message class' property interface, but these
- * values are shared for a node instead of message.
- */
+ * values are shared for a node instead of message.
+ */
public class ModuleCommunicationBus {
/** Initial capacity for the listener lists (instead of 10) */
private static int INIT_CAPACITY = 3;
@@ -21,7 +21,7 @@ public class ModuleCommunicationBus {
private HashMap values;
/** Subscribed listeners (or null if none)*/
private HashMap> listeners;
-
+
/**
* Constructor.
*/
@@ -29,12 +29,12 @@ public ModuleCommunicationBus() {
this.values = null; /* use lazy creation */
this.listeners = null;
}
-
+
/**
- * Adds a new property for this node. The key can be any string but
+ * Adds a new property for this node. The key can be any string but
* it should be such that no other class accidently uses the same value.
* Note that, unless the value is immutable, it can be changed by any
- * object that can call {@link #getProperty}.
+ * object that can call {@link #getProperty}.
* @param key The key which is used to lookup the value
* @param value The value to store
* @throws SimError if there is already a value for the given key
@@ -42,15 +42,15 @@ public ModuleCommunicationBus() {
public void addProperty(String key, Object value) throws SimError {
if (this.values != null && this.values.containsKey(key)) {
/* check to prevent accidental name space collisions */
- throw new SimError("A value for the key " + key +
+ throw new SimError("A value for the key " + key +
" already exists");
}
-
+
this.updateProperty(key, value);
}
-
+
/**
- * Returns an object that was stored using the given key. If such object
+ * Returns an object that was stored using the given key. If such object
* is not found, null is returned.
* @param key The key used to lookup the object
* @return The stored object or null if it isn't found
@@ -61,7 +61,7 @@ public Object getProperty(String key) {
}
return this.values.get(key);
}
-
+
/**
* Returns true if the bus contains a value for the given key
* @param key The key for which a value's existence is checked
@@ -73,9 +73,9 @@ public boolean containsProperty(String key) {
}
return this.values.containsKey(key);
}
-
+
/**
- * Updates a value for an existing property. For storing the value first
+ * Updates a value for an existing property. For storing the value first
* time, {@link #addProperty(String, Object)} should be used which
* checks for name space clashes.
* @param key The key which is used to lookup the value
@@ -86,14 +86,14 @@ public void updateProperty(String key, Object value) throws SimError {
/* lazy creation to prevent performance overhead for classes
that don't use the property feature */
this.values = new HashMap();
- }
+ }
this.values.put(key, value);
notifyListeners(key, value);
}
/**
- * Changes the Double value with given key with the value delta
+ * Changes the Double value with given key with the value delta
* @param key The key of variable to update
* @param delta Value added to the old value
* @return The new value
@@ -114,7 +114,7 @@ public double updateDouble(String key, double delta) throws SimError {
return current + delta;
}
-
+
/**
* Returns a double value from the communication bus.
* @param key The key of the variable
@@ -134,7 +134,7 @@ public double getDouble(String key, double naValue) throws SimError {
throw new SimError("No Double value for key " + key);
}
}
-
+
/**
* Returns an integer value from the communication bus.
* @param key The key of the variable
@@ -154,7 +154,7 @@ public int getInt(String key, int naValue) throws SimError {
throw new SimError("No Integer value for key " + key);
}
}
-
+
/**
* Subscribes a module to changes of a certain value.
* @param key The key of the value whose changes the module is interested of
@@ -163,20 +163,20 @@ public int getInt(String key, int naValue) throws SimError {
public void subscribe(String key, ModuleCommunicationListener module) {
if (this.listeners == null) {
/* first listener for the whole node */
- this.listeners =
+ this.listeners =
new HashMap>();
}
-
+
List list = this.listeners.get(key);
if (list == null) {
/* first listener for this key */
list = new ArrayList(INIT_CAPACITY);
this.listeners.put(key, list);
}
-
+
list.add(module);
}
-
+
/**
* Removes a notification subscription
* @param key The key for which the subscription should be removed
@@ -184,46 +184,46 @@ public void subscribe(String key, ModuleCommunicationListener module) {
*/
public void unsubscribe(String key, ModuleCommunicationListener module) {
List list;
-
+
if (this.listeners == null) {
return; /* no subscriptions */
}
-
+
list = this.listeners.get(key);
if (list == null) {
return; /* no subscriptions for the key */
}
-
+
list.remove(module);
}
-
-
+
+
/**
- * Notifies all listeners that have subscribed to the given key
+ * Notifies all listeners that have subscribed to the given key
* @param key The key which got new value
* @param newValue The new value for the key
*/
private void notifyListeners(String key, Object newValue) {
List list;
-
+
if (this.listeners == null) {
return;
}
list = this.listeners.get(key);
-
+
if (list == null) {
return;
}
-
+
for (ModuleCommunicationListener mcl : list) {
mcl.moduleValueChanged(key, newValue);
}
}
-
-
+
+
@Override
public String toString() {
- return "ComBus with mapping: " + (this.values != null ?
+ return "ComBus with mapping: " + (this.values != null ?
this.values.toString() : "n/a");
}
-}
+}
diff --git a/core/ModuleCommunicationListener.java b/core/ModuleCommunicationListener.java
index 2df2c14b9..019d0f3cc 100644
--- a/core/ModuleCommunicationListener.java
+++ b/core/ModuleCommunicationListener.java
@@ -1,21 +1,21 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
- */
-package core;
-
-/**
- * This interface should be implemented by classes that want to be notified
- * of variable value changes in ModuleCommunicationBuses.
- */
-public interface ModuleCommunicationListener {
-
- /**
- * This method is called whenever a variable, whose changes the module has
- * registered to, changes.
- * @param key The name of the variable
- * @param newValue New value for the variable
- */
- public void moduleValueChanged(String key, Object newValue);
-
-}
+ * Released under GPLv3. See LICENSE.txt for details.
+ */
+package core;
+
+/**
+ * This interface should be implemented by classes that want to be notified
+ * of variable value changes in ModuleCommunicationBuses.
+ */
+public interface ModuleCommunicationListener {
+
+ /**
+ * This method is called whenever a variable, whose changes the module has
+ * registered to, changes.
+ * @param key The name of the variable
+ * @param newValue New value for the variable
+ */
+ public void moduleValueChanged(String key, Object newValue);
+
+}
diff --git a/core/MovementListener.java b/core/MovementListener.java
index 8b1bbd45c..6b2073779 100644
--- a/core/MovementListener.java
+++ b/core/MovementListener.java
@@ -1,29 +1,29 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package core;
-
-/**
- * Interface for classes that want to be informed about node movement.
- */
-public interface MovementListener {
-
- /**
- * Method is called every time a host receives a new destination from its
- * movement model.
- * @param host The host that got a new destination
- * @param destination Coordinates of the destination
- * @param speed Speed towards that destination
- */
- public void newDestination(DTNHost host, Coord destination, double speed);
-
- /**
- * Method is called when a host receives its initial location from
- * movement model.
- * @param host The host that got the location
- * @param location Coordinates of the location
- */
- public void initialLocation(DTNHost host, Coord location);
-
-}
+package core;
+
+/**
+ * Interface for classes that want to be informed about node movement.
+ */
+public interface MovementListener {
+
+ /**
+ * Method is called every time a host receives a new destination from its
+ * movement model.
+ * @param host The host that got a new destination
+ * @param destination Coordinates of the destination
+ * @param speed Speed towards that destination
+ */
+ public void newDestination(DTNHost host, Coord destination, double speed);
+
+ /**
+ * Method is called when a host receives its initial location from
+ * movement model.
+ * @param host The host that got the location
+ * @param location Coordinates of the location
+ */
+ public void initialLocation(DTNHost host, Coord location);
+
+}
diff --git a/core/NetworkInterface.java b/core/NetworkInterface.java
index 24433d7e9..6d1581739 100644
--- a/core/NetworkInterface.java
+++ b/core/NetworkInterface.java
@@ -1,517 +1,517 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
- */
-package core;
-
-import interfaces.ConnectivityGrid;
-import interfaces.ConnectivityOptimizer;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-
-import routing.util.EnergyModel;
-
-import util.ActivenessHandler;
-
-/**
- * Network interface of a DTNHost. Takes care of connectivity among hosts.
- */
-abstract public class NetworkInterface implements ModuleCommunicationListener {
- /** transmit range -setting id ({@value})*/
- public static final String TRANSMIT_RANGE_S = "transmitRange";
- /** transmit speed -setting id ({@value})*/
- public static final String TRANSMIT_SPEED_S = "transmitSpeed";
- /** scanning interval -setting id ({@value})*/
- public static final String SCAN_INTERVAL_S = "scanInterval";
-
- /**
- * Sub-namespace for the network related settings in the Group namespace
- * ({@value})
- */
- public static final String NET_SUB_NS = "net";
-
- /** Activeness offset jitter -setting id ({@value})
- * The maximum amount of random offset for the offset */
- public static final String ACT_JITTER_S = "activenessOffsetJitter";
-
- /** {@link ModuleCommunicationBus} identifier for the "scanning interval"
- variable. */
- public static final String SCAN_INTERVAL_ID = "Network.scanInterval";
- /** {@link ModuleCommunicationBus} identifier for the "radio range"
- variable. Value type: double */
- public static final String RANGE_ID = "Network.radioRange";
- /** {@link ModuleCommunicationBus} identifier for the "transmission speed"
- variable. Value type: integer */
- public static final String SPEED_ID = "Network.speed";
-
- private static final int CON_UP = 1;
- private static final int CON_DOWN = 2;
-
- private static Random rng;
- protected DTNHost host = null;
-
- protected String interfacetype;
- protected List connections; // connected hosts
- private List cListeners = null; // list of listeners
- private int address; // network interface address
- protected double transmitRange;
- protected double oldTransmitRange;
- protected int transmitSpeed;
- protected ConnectivityOptimizer optimizer = null;
- /** scanning interval, or 0.0 if n/a */
- private double scanInterval;
- private double lastScanTime;
-
- /** activeness handler for the node group */
- private ActivenessHandler ah;
- /** maximum activeness jitter value for the node group */
- private int activenessJitterMax;
- /** this interface's activeness jitter value */
- private int activenessJitterValue;
-
- static {
- DTNSim.registerForReset(NetworkInterface.class.getCanonicalName());
- reset();
- }
-
- /**
- * Resets the static fields of the class
- */
- public static void reset() {
- rng = new Random(0);
- }
-
- /**
- * For creating an empty class of a specific type
- */
- public NetworkInterface(Settings s) {
- this.interfacetype = s.getNameSpace();
- this.connections = new ArrayList();
-
- this.transmitRange = s.getDouble(TRANSMIT_RANGE_S);
- this.transmitSpeed = s.getInt(TRANSMIT_SPEED_S);
- ensurePositiveValue(transmitRange, TRANSMIT_RANGE_S);
- ensurePositiveValue(transmitSpeed, TRANSMIT_SPEED_S);
- }
-
- /**
- * For creating an empty class of a specific type
- */
- public NetworkInterface() {
- this.interfacetype = "Default";
- this.connections = new ArrayList();
- }
-
- /**
- * copy constructor
- */
- public NetworkInterface(NetworkInterface ni) {
- this.connections = new ArrayList();
- this.host = ni.host;
- this.cListeners = ni.cListeners;
- this.interfacetype = ni.interfacetype;
- this.transmitRange = ni.transmitRange;
- this.transmitSpeed = ni.transmitSpeed;
- this.scanInterval = ni.scanInterval;
- this.ah = ni.ah;
-
- if (ni.activenessJitterMax > 0) {
- this.activenessJitterValue = rng.nextInt(ni.activenessJitterMax);
- } else {
- this.activenessJitterValue = 0;
- }
-
- this.scanInterval = ni.scanInterval;
- /* draw lastScanTime of [0 -- scanInterval] */
- this.lastScanTime = rng.nextDouble() * this.scanInterval;
- }
-
- /**
- * Replication function
- */
- abstract public NetworkInterface replicate();
-
- /**
- * For setting the host - needed when a prototype is copied for several
- * hosts
- * @param host The host where the network interface is
- */
- public void setHost(DTNHost host) {
- this.host = host;
- ModuleCommunicationBus comBus = host.getComBus();
-
- if (!comBus.containsProperty(SCAN_INTERVAL_ID) &&
- !comBus.containsProperty(RANGE_ID)) {
- /* add properties and subscriptions only for the 1st interface */
- /* TODO: support for multiple interfaces */
- comBus.addProperty(SCAN_INTERVAL_ID, this.scanInterval);
- comBus.addProperty(RANGE_ID, this.transmitRange);
- comBus.addProperty(SPEED_ID, this.transmitSpeed);
- comBus.subscribe(SCAN_INTERVAL_ID, this);
- comBus.subscribe(RANGE_ID, this);
- comBus.subscribe(SPEED_ID, this);
- }
-
- if (transmitRange > 0) {
- optimizer = ConnectivityGrid.ConnectivityGridFactory(
- this.interfacetype.hashCode(), transmitRange);
- optimizer.addInterface(this);
- } else {
- optimizer = null;
- }
- }
-
- /**
- * Sets group-based settings for the network interface
- * @param s The settings object using the right group namespace
- */
- public void setGroupSettings(Settings s) {
- s.setSubNameSpace(NET_SUB_NS);
- ah = new ActivenessHandler(s);
-
- if (s.contains(SCAN_INTERVAL_S)) {
- this.scanInterval = s.getDouble(SCAN_INTERVAL_S);
- } else {
- this.scanInterval = 0;
- }
- if (s.contains(ACT_JITTER_S)) {
- this.activenessJitterMax = s.getInt(ACT_JITTER_S);
- }
-
- s.restoreSubNameSpace();
- }
-
- /**
- * For checking what interface type this interface is
- */
- public String getInterfaceType() {
- return interfacetype;
- }
-
- /**
- * For setting the connectionListeners
- * @param cListeners List of connection listeners
- */
- public void setClisteners(List cListeners) {
- this.cListeners = cListeners;
- }
-
- /**
- * Returns the transmit range of this network layer
- * @return the transmit range
- */
- public double getTransmitRange() {
- return this.transmitRange;
- }
-
- /**
- * Returns the transmit speed of this network layer with respect to the
- * another network interface
- * @param ni The other network interface
- * @return the transmit speed
- */
- public int getTransmitSpeed(NetworkInterface ni) {
- return this.transmitSpeed;
- }
-
- /**
- * Returns a list of currently connected connections
- * @return a list of currently connected connections
- */
- public List getConnections() {
- return this.connections;
- }
-
- /**
- * Returns true if the interface is on at the moment (false if not)
- * @return true if the interface is on at the moment (false if not)
- */
- public boolean isActive() {
- boolean active;
-
- if (ah == null) {
- return true; /* no handler: always active */
- }
-
- active = ah.isActive(this.activenessJitterValue);
-
- if (active && host.getComBus().getDouble(EnergyModel.ENERGY_VALUE_ID,
- 1) <= 0) {
- /* TODO: better way to check battery level */
- /* no battery -> inactive */
- active = false;
- }
-
- if (active == false && this.transmitRange > 0) {
- /* not active -> make range 0 */
- this.oldTransmitRange = this.transmitRange;
- host.getComBus().updateProperty(RANGE_ID, 0.0);
- } else if (active == true && this.transmitRange == 0.0) {
- /* active, but range == 0 -> restore range */
- host.getComBus().updateProperty(RANGE_ID,
- this.oldTransmitRange);
- }
- return active;
- }
-
- /**
- * Checks if this interface is currently in the scanning mode
- * @return True if the interface is scanning; false if not
- */
- public boolean isScanning() {
- double simTime = SimClock.getTime();
-
- if (!isActive()) {
- return false;
- }
-
- if (scanInterval > 0.0) {
- if (simTime < lastScanTime) {
- return false; /* not time for the first scan */
- }
- else if (simTime > lastScanTime + scanInterval) {
- lastScanTime = simTime; /* time to start the next scan round */
- return true;
- }
- else if (simTime != lastScanTime ){
- return false; /* not in the scan round */
- }
- }
- /* interval == 0 or still in the same scan round as when
- last time asked */
- return true;
- }
-
- /**
- * Returns true if one of the connections of this interface is transferring
- * data
- * @return true if the interface transferring
- */
- public boolean isTransferring() {
- for (Connection c : this.connections) {
- if (c.isTransferring()) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Connects the interface to another interface.
- *
- * Overload this in a derived class. Check the requirements for
- * the connection to work in the derived class, then call
- * connect(Connection, NetworkInterface) for the actual connection.
- * @param anotherInterface The interface to connect to
- */
- public abstract void connect(NetworkInterface anotherInterface);
-
- /**
- * Connects this host to another host. The derived class should check
- * that all pre-requisites for making a connection are satisfied before
- * actually connecting.
- * @param con The new connection object
- * @param anotherInterface The interface to connect to
- */
- protected void connect(Connection con, NetworkInterface anotherInterface) {
- this.connections.add(con);
- notifyConnectionListeners(CON_UP, anotherInterface.getHost());
-
- // set up bidirectional connection
- anotherInterface.getConnections().add(con);
-
- // inform routers about the connection
- this.host.connectionUp(con);
- anotherInterface.getHost().connectionUp(con);
- }
-
- /**
- * Disconnects this host from another host. The derived class should
- * make the decision whether to disconnect or not
- * @param con The connection to tear down
- */
- protected void disconnect(Connection con,
- NetworkInterface anotherInterface) {
- con.setUpState(false);
- notifyConnectionListeners(CON_DOWN, anotherInterface.getHost());
-
- // tear down bidirectional connection
- if (!anotherInterface.getConnections().remove(con)) {
- throw new SimError("No connection " + con + " found in " +
- anotherInterface);
- }
-
- this.host.connectionDown(con);
- anotherInterface.getHost().connectionDown(con);
- }
-
- /**
- * Returns true if another interface is within radio range of this interface
- * and this interface is also within radio range of the another interface.
- * @param anotherInterface The another interface
- * @return True if the interface is within range, false if not
- */
- protected boolean isWithinRange(NetworkInterface anotherInterface) {
- double smallerRange = anotherInterface.getTransmitRange();
- double myRange = getTransmitRange();
- if (myRange < smallerRange) {
- smallerRange = myRange;
- }
-
- return this.host.getLocation().distance(
- anotherInterface.getHost().getLocation()) <= smallerRange;
- }
-
- /**
- * Returns true if the given NetworkInterface is connected to this host.
- * @param netinterface The other NetworkInterface to check
- * @return True if the two hosts are connected
- */
- protected boolean isConnected(NetworkInterface netinterface) {
- for (int i = 0; i < this.connections.size(); i++) {
- if (this.connections.get(i).getOtherInterface(this) ==
- netinterface) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Makes sure that a value is positive
- * @param value Value to check
- * @param settingName Name of the setting (for error's message)
- * @throws SettingsError if the value was not positive
- */
- protected void ensurePositiveValue(double value, String settingName) {
- if (value < 0) {
- throw new SettingsError("Negative value (" + value +
- ") not accepted for setting " + settingName);
- }
- }
-
- /**
- * Updates the state of current connections (ie tears down connections
- * that are out of range, recalculates transmission speeds etc.).
- */
- abstract public void update();
-
- /**
- * Notifies all the connection listeners about a change in connections.
- * @param type Type of the change (e.g. {@link #CON_DOWN} )
- * @param otherHost The other host on the other end of the connection.
- */
- private void notifyConnectionListeners(int type, DTNHost otherHost) {
- if (this.cListeners == null) {
- return;
- }
- for (ConnectionListener cl : this.cListeners) {
- switch (type) {
- case CON_UP:
- cl.hostsConnected(this.host, otherHost);
- break;
- case CON_DOWN:
- cl.hostsDisconnected(this.host, otherHost);
- break;
- default:
- assert false : type; // invalid type code
- }
- }
- }
-
- /**
- * This method is called by the {@link ModuleCommunicationBus} when/if
- * someone changes the scanning interval, transmit speed, or range
- * @param key Identifier of the changed value
- * @param newValue New value for the variable
- */
- public void moduleValueChanged(String key, Object newValue) {
- if (key.equals(SCAN_INTERVAL_ID)) {
- this.scanInterval = (Double)newValue;
- }
- else if (key.equals(SPEED_ID)) {
- this.transmitSpeed = (Integer)newValue;
- }
- else if (key.equals(RANGE_ID)) {
- this.transmitRange = (Double)newValue;
- }
- else {
- throw new SimError("Unexpected combus ID " + key);
- }
- }
-
- /**
- * Creates a connection to another host. This method does not do any checks
- * on whether the other node is in range or active
- * (cf. {@link #connect(NetworkInterface)}).
- * @param anotherInterface The interface to create the connection to
- */
- public abstract void createConnection(NetworkInterface anotherInterface);
-
- /**
- * Disconnect a connection between this and another host.
- * @param anotherInterface The other host's network interface to disconnect
- * from this host
- */
- public void destroyConnection(NetworkInterface anotherInterface) {
- DTNHost anotherHost = anotherInterface.getHost();
- for (int i=0; i < this.connections.size(); i++) {
- if (this.connections.get(i).getOtherNode(this.host) == anotherHost){
- removeConnectionByIndex(i, anotherInterface);
- }
- }
- // the connection didn't exist, do nothing
- }
-
- /**
- * Removes a connection by its position (index) in the connections array
- * of the interface
- * @param index The array index of the connection to be removed
- * @param anotherInterface The interface of the other host
- */
- private void removeConnectionByIndex(int index,
- NetworkInterface anotherInterface) {
- Connection con = this.connections.get(index);
- DTNHost anotherNode = anotherInterface.getHost();
- con.setUpState(false);
- notifyConnectionListeners(CON_DOWN, anotherNode);
-
- // tear down bidirectional connection
- if (!anotherInterface.getConnections().remove(con)) {
- throw new SimError("No connection " + con + " found in " +
- anotherNode);
- }
-
- this.host.connectionDown(con);
- anotherNode.connectionDown(con);
-
- connections.remove(index);
- }
-
- /**
- * Returns the DTNHost of this interface
- */
- public DTNHost getHost() {
- return host;
- }
-
- /**
- * Returns the current location of the host of this interface.
- * @return The location
- */
- public Coord getLocation() {
- return host.getLocation();
- }
-
- /**
- * Returns a string representation of the object.
- * @return a string representation of the object.
- */
- public String toString() {
- return this.address + " of " + this.host +
- ". Connections: " + this.connections;
- }
-
-}
+ * Released under GPLv3. See LICENSE.txt for details.
+ */
+package core;
+
+import interfaces.ConnectivityGrid;
+import interfaces.ConnectivityOptimizer;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import routing.util.EnergyModel;
+
+import util.ActivenessHandler;
+
+/**
+ * Network interface of a DTNHost. Takes care of connectivity among hosts.
+ */
+abstract public class NetworkInterface implements ModuleCommunicationListener {
+ /** transmit range -setting id ({@value})*/
+ public static final String TRANSMIT_RANGE_S = "transmitRange";
+ /** transmit speed -setting id ({@value})*/
+ public static final String TRANSMIT_SPEED_S = "transmitSpeed";
+ /** scanning interval -setting id ({@value})*/
+ public static final String SCAN_INTERVAL_S = "scanInterval";
+
+ /**
+ * Sub-namespace for the network related settings in the Group namespace
+ * ({@value})
+ */
+ public static final String NET_SUB_NS = "net";
+
+ /** Activeness offset jitter -setting id ({@value})
+ * The maximum amount of random offset for the offset */
+ public static final String ACT_JITTER_S = "activenessOffsetJitter";
+
+ /** {@link ModuleCommunicationBus} identifier for the "scanning interval"
+ variable. */
+ public static final String SCAN_INTERVAL_ID = "Network.scanInterval";
+ /** {@link ModuleCommunicationBus} identifier for the "radio range"
+ variable. Value type: double */
+ public static final String RANGE_ID = "Network.radioRange";
+ /** {@link ModuleCommunicationBus} identifier for the "transmission speed"
+ variable. Value type: integer */
+ public static final String SPEED_ID = "Network.speed";
+
+ private static final int CON_UP = 1;
+ private static final int CON_DOWN = 2;
+
+ private static Random rng;
+ protected DTNHost host = null;
+
+ protected String interfacetype;
+ protected List connections; // connected hosts
+ private List cListeners = null; // list of listeners
+ private int address; // network interface address
+ protected double transmitRange;
+ protected double oldTransmitRange;
+ protected int transmitSpeed;
+ protected ConnectivityOptimizer optimizer = null;
+ /** scanning interval, or 0.0 if n/a */
+ private double scanInterval;
+ private double lastScanTime;
+
+ /** activeness handler for the node group */
+ private ActivenessHandler ah;
+ /** maximum activeness jitter value for the node group */
+ private int activenessJitterMax;
+ /** this interface's activeness jitter value */
+ private int activenessJitterValue;
+
+ static {
+ DTNSim.registerForReset(NetworkInterface.class.getCanonicalName());
+ reset();
+ }
+
+ /**
+ * Resets the static fields of the class
+ */
+ public static void reset() {
+ rng = new Random(0);
+ }
+
+ /**
+ * For creating an empty class of a specific type
+ */
+ public NetworkInterface(Settings s) {
+ this.interfacetype = s.getNameSpace();
+ this.connections = new ArrayList();
+
+ this.transmitRange = s.getDouble(TRANSMIT_RANGE_S);
+ this.transmitSpeed = s.getInt(TRANSMIT_SPEED_S);
+ ensurePositiveValue(transmitRange, TRANSMIT_RANGE_S);
+ ensurePositiveValue(transmitSpeed, TRANSMIT_SPEED_S);
+ }
+
+ /**
+ * For creating an empty class of a specific type
+ */
+ public NetworkInterface() {
+ this.interfacetype = "Default";
+ this.connections = new ArrayList();
+ }
+
+ /**
+ * copy constructor
+ */
+ public NetworkInterface(NetworkInterface ni) {
+ this.connections = new ArrayList();
+ this.host = ni.host;
+ this.cListeners = ni.cListeners;
+ this.interfacetype = ni.interfacetype;
+ this.transmitRange = ni.transmitRange;
+ this.transmitSpeed = ni.transmitSpeed;
+ this.scanInterval = ni.scanInterval;
+ this.ah = ni.ah;
+
+ if (ni.activenessJitterMax > 0) {
+ this.activenessJitterValue = rng.nextInt(ni.activenessJitterMax);
+ } else {
+ this.activenessJitterValue = 0;
+ }
+
+ this.scanInterval = ni.scanInterval;
+ /* draw lastScanTime of [0 -- scanInterval] */
+ this.lastScanTime = rng.nextDouble() * this.scanInterval;
+ }
+
+ /**
+ * Replication function
+ */
+ abstract public NetworkInterface replicate();
+
+ /**
+ * For setting the host - needed when a prototype is copied for several
+ * hosts
+ * @param host The host where the network interface is
+ */
+ public void setHost(DTNHost host) {
+ this.host = host;
+ ModuleCommunicationBus comBus = host.getComBus();
+
+ if (!comBus.containsProperty(SCAN_INTERVAL_ID) &&
+ !comBus.containsProperty(RANGE_ID)) {
+ /* add properties and subscriptions only for the 1st interface */
+ /* TODO: support for multiple interfaces */
+ comBus.addProperty(SCAN_INTERVAL_ID, this.scanInterval);
+ comBus.addProperty(RANGE_ID, this.transmitRange);
+ comBus.addProperty(SPEED_ID, this.transmitSpeed);
+ comBus.subscribe(SCAN_INTERVAL_ID, this);
+ comBus.subscribe(RANGE_ID, this);
+ comBus.subscribe(SPEED_ID, this);
+ }
+
+ if (transmitRange > 0) {
+ optimizer = ConnectivityGrid.ConnectivityGridFactory(
+ this.interfacetype.hashCode(), transmitRange);
+ optimizer.addInterface(this);
+ } else {
+ optimizer = null;
+ }
+ }
+
+ /**
+ * Sets group-based settings for the network interface
+ * @param s The settings object using the right group namespace
+ */
+ public void setGroupSettings(Settings s) {
+ s.setSubNameSpace(NET_SUB_NS);
+ ah = new ActivenessHandler(s);
+
+ if (s.contains(SCAN_INTERVAL_S)) {
+ this.scanInterval = s.getDouble(SCAN_INTERVAL_S);
+ } else {
+ this.scanInterval = 0;
+ }
+ if (s.contains(ACT_JITTER_S)) {
+ this.activenessJitterMax = s.getInt(ACT_JITTER_S);
+ }
+
+ s.restoreSubNameSpace();
+ }
+
+ /**
+ * For checking what interface type this interface is
+ */
+ public String getInterfaceType() {
+ return interfacetype;
+ }
+
+ /**
+ * For setting the connectionListeners
+ * @param cListeners List of connection listeners
+ */
+ public void setClisteners(List cListeners) {
+ this.cListeners = cListeners;
+ }
+
+ /**
+ * Returns the transmit range of this network layer
+ * @return the transmit range
+ */
+ public double getTransmitRange() {
+ return this.transmitRange;
+ }
+
+ /**
+ * Returns the transmit speed of this network layer with respect to the
+ * another network interface
+ * @param ni The other network interface
+ * @return the transmit speed
+ */
+ public int getTransmitSpeed(NetworkInterface ni) {
+ return this.transmitSpeed;
+ }
+
+ /**
+ * Returns a list of currently connected connections
+ * @return a list of currently connected connections
+ */
+ public List getConnections() {
+ return this.connections;
+ }
+
+ /**
+ * Returns true if the interface is on at the moment (false if not)
+ * @return true if the interface is on at the moment (false if not)
+ */
+ public boolean isActive() {
+ boolean active;
+
+ if (ah == null) {
+ return true; /* no handler: always active */
+ }
+
+ active = ah.isActive(this.activenessJitterValue);
+
+ if (active && host.getComBus().getDouble(EnergyModel.ENERGY_VALUE_ID,
+ 1) <= 0) {
+ /* TODO: better way to check battery level */
+ /* no battery -> inactive */
+ active = false;
+ }
+
+ if (active == false && this.transmitRange > 0) {
+ /* not active -> make range 0 */
+ this.oldTransmitRange = this.transmitRange;
+ host.getComBus().updateProperty(RANGE_ID, 0.0);
+ } else if (active == true && this.transmitRange == 0.0) {
+ /* active, but range == 0 -> restore range */
+ host.getComBus().updateProperty(RANGE_ID,
+ this.oldTransmitRange);
+ }
+ return active;
+ }
+
+ /**
+ * Checks if this interface is currently in the scanning mode
+ * @return True if the interface is scanning; false if not
+ */
+ public boolean isScanning() {
+ double simTime = SimClock.getTime();
+
+ if (!isActive()) {
+ return false;
+ }
+
+ if (scanInterval > 0.0) {
+ if (simTime < lastScanTime) {
+ return false; /* not time for the first scan */
+ }
+ else if (simTime > lastScanTime + scanInterval) {
+ lastScanTime = simTime; /* time to start the next scan round */
+ return true;
+ }
+ else if (simTime != lastScanTime ){
+ return false; /* not in the scan round */
+ }
+ }
+ /* interval == 0 or still in the same scan round as when
+ last time asked */
+ return true;
+ }
+
+ /**
+ * Returns true if one of the connections of this interface is transferring
+ * data
+ * @return true if the interface transferring
+ */
+ public boolean isTransferring() {
+ for (Connection c : this.connections) {
+ if (c.isTransferring()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Connects the interface to another interface.
+ *
+ * Overload this in a derived class. Check the requirements for
+ * the connection to work in the derived class, then call
+ * connect(Connection, NetworkInterface) for the actual connection.
+ * @param anotherInterface The interface to connect to
+ */
+ public abstract void connect(NetworkInterface anotherInterface);
+
+ /**
+ * Connects this host to another host. The derived class should check
+ * that all pre-requisites for making a connection are satisfied before
+ * actually connecting.
+ * @param con The new connection object
+ * @param anotherInterface The interface to connect to
+ */
+ protected void connect(Connection con, NetworkInterface anotherInterface) {
+ this.connections.add(con);
+ notifyConnectionListeners(CON_UP, anotherInterface.getHost());
+
+ // set up bidirectional connection
+ anotherInterface.getConnections().add(con);
+
+ // inform routers about the connection
+ this.host.connectionUp(con);
+ anotherInterface.getHost().connectionUp(con);
+ }
+
+ /**
+ * Disconnects this host from another host. The derived class should
+ * make the decision whether to disconnect or not
+ * @param con The connection to tear down
+ */
+ protected void disconnect(Connection con,
+ NetworkInterface anotherInterface) {
+ con.setUpState(false);
+ notifyConnectionListeners(CON_DOWN, anotherInterface.getHost());
+
+ // tear down bidirectional connection
+ if (!anotherInterface.getConnections().remove(con)) {
+ throw new SimError("No connection " + con + " found in " +
+ anotherInterface);
+ }
+
+ this.host.connectionDown(con);
+ anotherInterface.getHost().connectionDown(con);
+ }
+
+ /**
+ * Returns true if another interface is within radio range of this interface
+ * and this interface is also within radio range of the another interface.
+ * @param anotherInterface The another interface
+ * @return True if the interface is within range, false if not
+ */
+ protected boolean isWithinRange(NetworkInterface anotherInterface) {
+ double smallerRange = anotherInterface.getTransmitRange();
+ double myRange = getTransmitRange();
+ if (myRange < smallerRange) {
+ smallerRange = myRange;
+ }
+
+ return this.host.getLocation().distance(
+ anotherInterface.getHost().getLocation()) <= smallerRange;
+ }
+
+ /**
+ * Returns true if the given NetworkInterface is connected to this host.
+ * @param netinterface The other NetworkInterface to check
+ * @return True if the two hosts are connected
+ */
+ protected boolean isConnected(NetworkInterface netinterface) {
+ for (int i = 0; i < this.connections.size(); i++) {
+ if (this.connections.get(i).getOtherInterface(this) ==
+ netinterface) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Makes sure that a value is positive
+ * @param value Value to check
+ * @param settingName Name of the setting (for error's message)
+ * @throws SettingsError if the value was not positive
+ */
+ protected void ensurePositiveValue(double value, String settingName) {
+ if (value < 0) {
+ throw new SettingsError("Negative value (" + value +
+ ") not accepted for setting " + settingName);
+ }
+ }
+
+ /**
+ * Updates the state of current connections (ie tears down connections
+ * that are out of range, recalculates transmission speeds etc.).
+ */
+ abstract public void update();
+
+ /**
+ * Notifies all the connection listeners about a change in connections.
+ * @param type Type of the change (e.g. {@link #CON_DOWN} )
+ * @param otherHost The other host on the other end of the connection.
+ */
+ private void notifyConnectionListeners(int type, DTNHost otherHost) {
+ if (this.cListeners == null) {
+ return;
+ }
+ for (ConnectionListener cl : this.cListeners) {
+ switch (type) {
+ case CON_UP:
+ cl.hostsConnected(this.host, otherHost);
+ break;
+ case CON_DOWN:
+ cl.hostsDisconnected(this.host, otherHost);
+ break;
+ default:
+ assert false : type; // invalid type code
+ }
+ }
+ }
+
+ /**
+ * This method is called by the {@link ModuleCommunicationBus} when/if
+ * someone changes the scanning interval, transmit speed, or range
+ * @param key Identifier of the changed value
+ * @param newValue New value for the variable
+ */
+ public void moduleValueChanged(String key, Object newValue) {
+ if (key.equals(SCAN_INTERVAL_ID)) {
+ this.scanInterval = (Double)newValue;
+ }
+ else if (key.equals(SPEED_ID)) {
+ this.transmitSpeed = (Integer)newValue;
+ }
+ else if (key.equals(RANGE_ID)) {
+ this.transmitRange = (Double)newValue;
+ }
+ else {
+ throw new SimError("Unexpected combus ID " + key);
+ }
+ }
+
+ /**
+ * Creates a connection to another host. This method does not do any checks
+ * on whether the other node is in range or active
+ * (cf. {@link #connect(NetworkInterface)}).
+ * @param anotherInterface The interface to create the connection to
+ */
+ public abstract void createConnection(NetworkInterface anotherInterface);
+
+ /**
+ * Disconnect a connection between this and another host.
+ * @param anotherInterface The other host's network interface to disconnect
+ * from this host
+ */
+ public void destroyConnection(NetworkInterface anotherInterface) {
+ DTNHost anotherHost = anotherInterface.getHost();
+ for (int i=0; i < this.connections.size(); i++) {
+ if (this.connections.get(i).getOtherNode(this.host) == anotherHost){
+ removeConnectionByIndex(i, anotherInterface);
+ }
+ }
+ // the connection didn't exist, do nothing
+ }
+
+ /**
+ * Removes a connection by its position (index) in the connections array
+ * of the interface
+ * @param index The array index of the connection to be removed
+ * @param anotherInterface The interface of the other host
+ */
+ private void removeConnectionByIndex(int index,
+ NetworkInterface anotherInterface) {
+ Connection con = this.connections.get(index);
+ DTNHost anotherNode = anotherInterface.getHost();
+ con.setUpState(false);
+ notifyConnectionListeners(CON_DOWN, anotherNode);
+
+ // tear down bidirectional connection
+ if (!anotherInterface.getConnections().remove(con)) {
+ throw new SimError("No connection " + con + " found in " +
+ anotherNode);
+ }
+
+ this.host.connectionDown(con);
+ anotherNode.connectionDown(con);
+
+ connections.remove(index);
+ }
+
+ /**
+ * Returns the DTNHost of this interface
+ */
+ public DTNHost getHost() {
+ return host;
+ }
+
+ /**
+ * Returns the current location of the host of this interface.
+ * @return The location
+ */
+ public Coord getLocation() {
+ return host.getLocation();
+ }
+
+ /**
+ * Returns a string representation of the object.
+ * @return a string representation of the object.
+ */
+ public String toString() {
+ return this.address + " of " + this.host +
+ ". Connections: " + this.connections;
+ }
+
+}
diff --git a/core/Settings.java b/core/Settings.java
index f39794f52..302642fad 100644
--- a/core/Settings.java
+++ b/core/Settings.java
@@ -1,9 +1,9 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package core;
-
+package core;
+
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -19,112 +19,112 @@
import java.util.Stack;
import util.Range;
-
-/**
- * Interface for simulation settings stored in setting file(s). Settings
- * class should be initialized before using (with {@link #init(String)}). If
- * Settings isn't initialized, only settings in {@link #DEF_SETTINGS_FILE}
- * are read. Normally, after initialization, settings in the given file can
- * override any settings defined in the default settings file and/or define
- * new settings.
- * All settings are key-value pairs. For parsing details see
- * {@link java.util.Properties#getProperty(String)}. Value can be a single
- * value or comma separated list of values. With CSV values, CSV methods
- * must be used (e.g. {@link #getCsvInts(String, int)}). Setting value should
- * not start and end with a bracket since those are reserved for run-specific
- * values (see {@link #setRunIndex(int)}). In file paths directory separator
- * should always be forward slash ("/").
- *
- */
-public class Settings {
- /** properties object where the setting files are read into */
- protected static Properties props;
- /** file name of the default settings file ({@value}) */
+
+/**
+ * Interface for simulation settings stored in setting file(s). Settings
+ * class should be initialized before using (with {@link #init(String)}). If
+ * Settings isn't initialized, only settings in {@link #DEF_SETTINGS_FILE}
+ * are read. Normally, after initialization, settings in the given file can
+ * override any settings defined in the default settings file and/or define
+ * new settings.
+ * All settings are key-value pairs. For parsing details see
+ * {@link java.util.Properties#getProperty(String)}. Value can be a single
+ * value or comma separated list of values. With CSV values, CSV methods
+ * must be used (e.g. {@link #getCsvInts(String, int)}). Setting value should
+ * not start and end with a bracket since those are reserved for run-specific
+ * values (see {@link #setRunIndex(int)}). In file paths directory separator
+ * should always be forward slash ("/").
+ *
+ */
+public class Settings {
+ /** properties object where the setting files are read into */
+ protected static Properties props;
+ /** file name of the default settings file ({@value}) */
public static final String DEF_SETTINGS_FILE ="default_settings.txt";
-
- /**
+
+ /**
* Setting to define the file name where all read settings are written
- * ({@value}. If set to an empty string, standard output is used.
- * By default setting are not written anywhere.
+ * ({@value}. If set to an empty string, standard output is used.
+ * By default setting are not written anywhere.
*/
- public static final String SETTING_OUTPUT_S = "Settings.output";
-
- /** delimiter for requested values in strings ({@value})
- * @see #valueFillString(String) */
+ public static final String SETTING_OUTPUT_S = "Settings.output";
+
+ /** delimiter for requested values in strings ({@value})
+ * @see #valueFillString(String) */
public static final String FILL_DELIMITER = "%%";
-
+
/** Stream where all read settings are written to */
private static PrintStream out = null;
- private static Set writtenSettings = new HashSet();
-
- /** run index for run-specific settings */
- private static int runIndex = 0;
- private String namespace = null; // namespace to look the settings from
- private String secondaryNamespace = null;
- private Stack oldNamespaces;
- private Stack secondaryNamespaces;
-
- /**
- * Creates a setting object with a namespace. Namespace is the prefix
- * of the all subsequent setting requests.
- * @param namespace Namespace to use
- */
- public Settings(String namespace) {
- this.oldNamespaces = new Stack();
- this.secondaryNamespaces = new Stack();
- setNameSpace(namespace);
- }
-
- /**
- * Create a setting object without namespace. All setting requests must
- * be prefixed with a valid namespace (e.g. "Report.nrofReports").
- */
- public Settings() {
- this(null);
- }
-
- /**
- * Sets the run index for the settings (only has effect on settings with
- * run array). A run array can be defined with syntax
- * [settingFor1stRun ; settingFor2ndRun ; SettingFor3rdRun]
- *
I.e. settings are put in brackets and delimited with semicolon.
- * First run's setting is returned when index is 0, second when index is
- * 1 etc. If run index is bigger than run array's length, indexing wraps
- * around in run array (i.e. return value is the value at index
- * runIndex % arrayLength
).
- * To disable whole run-index-thing, set index to value smaller than
- * zero (e.g. -1). When disabled, run-arrays are returned as normal values,
- * including the brackets.
- * @param index The run index to use for subsequent settings calls, or
- * -1 to disable run indexing
- */
- public static void setRunIndex(int index) {
+ private static Set writtenSettings = new HashSet();
+
+ /** run index for run-specific settings */
+ private static int runIndex = 0;
+ private String namespace = null; // namespace to look the settings from
+ private String secondaryNamespace = null;
+ private Stack oldNamespaces;
+ private Stack secondaryNamespaces;
+
+ /**
+ * Creates a setting object with a namespace. Namespace is the prefix
+ * of the all subsequent setting requests.
+ * @param namespace Namespace to use
+ */
+ public Settings(String namespace) {
+ this.oldNamespaces = new Stack();
+ this.secondaryNamespaces = new Stack();
+ setNameSpace(namespace);
+ }
+
+ /**
+ * Create a setting object without namespace. All setting requests must
+ * be prefixed with a valid namespace (e.g. "Report.nrofReports").
+ */
+ public Settings() {
+ this(null);
+ }
+
+ /**
+ * Sets the run index for the settings (only has effect on settings with
+ * run array). A run array can be defined with syntax
+ * [settingFor1stRun ; settingFor2ndRun ; SettingFor3rdRun]
+ *
I.e. settings are put in brackets and delimited with semicolon.
+ * First run's setting is returned when index is 0, second when index is
+ * 1 etc. If run index is bigger than run array's length, indexing wraps
+ * around in run array (i.e. return value is the value at index
+ * runIndex % arrayLength
).
+ * To disable whole run-index-thing, set index to value smaller than
+ * zero (e.g. -1). When disabled, run-arrays are returned as normal values,
+ * including the brackets.
+ * @param index The run index to use for subsequent settings calls, or
+ * -1 to disable run indexing
+ */
+ public static void setRunIndex(int index) {
runIndex = index;
- writtenSettings.clear();
+ writtenSettings.clear();
}
-
+
/**
- * Checks that the given integer array contains a valid range. I.e.,
- * the length of the array must be two and
+ * Checks that the given integer array contains a valid range. I.e.,
+ * the length of the array must be two and
* first_value <= second_value
.
* @param range The range array
* @param sname Name of the setting (for error messages)
* @throws SettingsError If the given array didn't qualify as a range
*/
- public void assertValidRange(int range[], String sname)
+ public void assertValidRange(int range[], String sname)
throws SettingsError {
if (range.length != 2) {
- throw new SettingsError("Range setting " +
- getFullPropertyName(sname) +
+ throw new SettingsError("Range setting " +
+ getFullPropertyName(sname) +
" should contain only two comma separated integer values");
}
if (range[0] > range[1]) {
- throw new SettingsError("Range setting's " +
- getFullPropertyName(sname) +
+ throw new SettingsError("Range setting's " +
+ getFullPropertyName(sname) +
" first value should be smaller or equal to second value");
}
- }
-
+ }
+
/**
* Makes sure that the given settings value is positive
* @param value Value to check
@@ -133,21 +133,21 @@ public void assertValidRange(int range[], String sname)
*/
public void ensurePositiveValue(double value, String settingName) {
if (value < 0) {
- throw new SettingsError("Negative value (" + value +
+ throw new SettingsError("Negative value (" + value +
") not accepted for setting " + settingName);
}
}
-
- /**
- * Sets the namespace to something else than the current namespace.
- * This change can be reverted using {@link #restoreNameSpace()}
- * @param namespace The new namespace
- */
- public void setNameSpace(String namespace) {
- this.oldNamespaces.push(this.namespace);
- this.namespace = namespace;
+
+ /**
+ * Sets the namespace to something else than the current namespace.
+ * This change can be reverted using {@link #restoreNameSpace()}
+ * @param namespace The new namespace
+ */
+ public void setNameSpace(String namespace) {
+ this.oldNamespaces.push(this.namespace);
+ this.namespace = namespace;
}
-
+
/**
* Appends the given namespace to the the current namespace,
* for both the primary and secondary namespace .
@@ -161,108 +161,108 @@ public void setSubNameSpace(String namespace) {
this.secondaryNamespaces.push(this.secondaryNamespace);
this.secondaryNamespace = this.secondaryNamespace + "." + namespace;
}
-
- /**
- * Returns full (namespace prefixed) property name for a setting.
- * @param setting The name of the setting
- * @return The setting name prefixed with fully qualified name of the
- * namespace where the requested setting would be retrieved from or null
- * if that setting is not found from any of the current namespace(s)
- */
- public String getFullPropertyName(String setting) {
- if (!contains(setting)) {
- return null;
- }
-
- if (props.getProperty(getFullPropertyName(setting, false)) != null) {
- return getFullPropertyName(setting, false);
- }
-
- // not found from primary, but Settings contains -> must be from 2ndary
- else return getFullPropertyName(setting, true);
- }
-
- /**
+
+ /**
+ * Returns full (namespace prefixed) property name for a setting.
+ * @param setting The name of the setting
+ * @return The setting name prefixed with fully qualified name of the
+ * namespace where the requested setting would be retrieved from or null
+ * if that setting is not found from any of the current namespace(s)
+ */
+ public String getFullPropertyName(String setting) {
+ if (!contains(setting)) {
+ return null;
+ }
+
+ if (props.getProperty(getFullPropertyName(setting, false)) != null) {
+ return getFullPropertyName(setting, false);
+ }
+
+ // not found from primary, but Settings contains -> must be from 2ndary
+ else return getFullPropertyName(setting, true);
+ }
+
+ /**
* Returns the namespace of the settings object
* @return the namespace of the settings object
*/
public String getNameSpace() {
return this.namespace;
}
-
- /**
+
+ /**
* Returns the secondary namespace of the settings object
* @return the secondary namespace of the settings object
*/
public String getSecondaryNameSpace() {
return this.secondaryNamespace;
}
-
- /**
- * Sets a secondary namespace where a setting is searched from if it
- * isn't found from the primary namespace. Secondary namespace can
- * be used e.g. as a "default" space where the settings are looked from
- * if no specific setting is set.
- * This change can be reverted using {@link #restoreSecondaryNamespace()}
- * @param namespace The new secondary namespace or null if secondary
- * namespace is not used (default behavior)
- */
- public void setSecondaryNamespace(String namespace) {
- this.secondaryNamespaces.push(this.secondaryNamespace);
- this.secondaryNamespace = namespace;
- }
-
- /**
- * Restores the namespace that was in use before a call to setNameSpace
- * @see #setNameSpace(String)
- */
- public void restoreNameSpace() {
- this.namespace = this.oldNamespaces.pop();
- }
-
- /**
- * Restores the secondary namespace that was in use before a call to
- * setSecondaryNameSpace
- * @see #setSecondaryNamespace(String)
- */
- public void restoreSecondaryNamespace() {
- this.secondaryNamespace = this.secondaryNamespaces.pop();
- }
-
- /**
- * Reverts the change made with {@link #setSubNameSpace(String)}, i.e.,
+
+ /**
+ * Sets a secondary namespace where a setting is searched from if it
+ * isn't found from the primary namespace. Secondary namespace can
+ * be used e.g. as a "default" space where the settings are looked from
+ * if no specific setting is set.
+ * This change can be reverted using {@link #restoreSecondaryNamespace()}
+ * @param namespace The new secondary namespace or null if secondary
+ * namespace is not used (default behavior)
+ */
+ public void setSecondaryNamespace(String namespace) {
+ this.secondaryNamespaces.push(this.secondaryNamespace);
+ this.secondaryNamespace = namespace;
+ }
+
+ /**
+ * Restores the namespace that was in use before a call to setNameSpace
+ * @see #setNameSpace(String)
+ */
+ public void restoreNameSpace() {
+ this.namespace = this.oldNamespaces.pop();
+ }
+
+ /**
+ * Restores the secondary namespace that was in use before a call to
+ * setSecondaryNameSpace
+ * @see #setSecondaryNamespace(String)
+ */
+ public void restoreSecondaryNamespace() {
+ this.secondaryNamespace = this.secondaryNamespaces.pop();
+ }
+
+ /**
+ * Reverts the change made with {@link #setSubNameSpace(String)}, i.e.,
* restores both the primary and secondary namespace.
*/
public void restoreSubNameSpace() {
restoreNameSpace();
restoreSecondaryNamespace();
- }
-
- /**
- * Initializes the settings all Settings objects will use. This should be
- * called before any setting requests. Subsequent calls replace all
- * old settings and then Settings contains only the new settings.
- * The file {@link #DEF_SETTINGS_FILE}, if exists, is always read.
- * @param propFile Path to the property file where additional settings
- * are read from or null if no additional settings files are needed.
- * @throws SettingsError If loading the settings file(s) didn't succeed
- */
- public static void init(String propFile) throws SettingsError {
+ }
+
+ /**
+ * Initializes the settings all Settings objects will use. This should be
+ * called before any setting requests. Subsequent calls replace all
+ * old settings and then Settings contains only the new settings.
+ * The file {@link #DEF_SETTINGS_FILE}, if exists, is always read.
+ * @param propFile Path to the property file where additional settings
+ * are read from or null if no additional settings files are needed.
+ * @throws SettingsError If loading the settings file(s) didn't succeed
+ */
+ public static void init(String propFile) throws SettingsError {
String outFile;
- try {
+ try {
if (new File(DEF_SETTINGS_FILE).exists()) {
- Properties defProperties = new Properties();
- defProperties.load(new FileInputStream(DEF_SETTINGS_FILE));
+ Properties defProperties = new Properties();
+ defProperties.load(new FileInputStream(DEF_SETTINGS_FILE));
props = new Properties(defProperties);
}
else {
props = new Properties();
- }
- if (propFile != null) {
- props.load(new FileInputStream(propFile));
- }
- } catch (IOException e) {
- throw new SettingsError(e);
+ }
+ if (propFile != null) {
+ props.load(new FileInputStream(propFile));
+ }
+ } catch (IOException e) {
+ throw new SettingsError(e);
}
outFile = props.getProperty(SETTING_OUTPUT_S);
@@ -278,8 +278,8 @@ public static void init(String propFile) throws SettingsError {
}
}
}
- }
-
+ }
+
/**
* Reads another settings file and adds the key-value pairs to the current
* settings overriding any values that already existed with the same keys.
@@ -294,7 +294,7 @@ public static void addSettings(String propFile) throws SettingsError {
throw new SettingsError(e);
}
}
-
+
/**
* Writes the given setting string to the settings output (if any)
* @param setting The string to write
@@ -308,87 +308,87 @@ private static void outputSetting(String setting) {
writtenSettings.add(setting);
}
}
-
- /**
- * Returns true if a setting with defined name (in the current namespace
- * or secondary namespace if such is set) exists and has some value
- * (not just white space)
- * @param name Name of the setting to check
- * @return True if the setting exists, false if not
- */
- public boolean contains(String name) {
- try {
- String value = getSetting(name);
- if (value == null) {
- return false;
- }
-
- else return value.trim().length() > 0;
- }
- catch (SettingsError e) {
- return false; // didn't find the setting
- }
- }
-
- /**
- * Returns full (namespace prefixed) property name for setting.
- * @param name Name of the settings
- * @param secondary If true, the secondary namespace is used.
- * @return full (prefixed with current namespace) property name for setting
- */
- private String getFullPropertyName(String name, boolean secondary) {
- String usedNamespace = (secondary ? secondaryNamespace : namespace);
-
- if (usedNamespace != null) {
- return usedNamespace + "." + name;
- }
- else {
- return name;
- }
- }
-
- /**
- * Returns a String-valued setting. Setting is first looked from the
- * namespace that is set (if any) and then from the secondary namespace
- * (if any). All other getters use this method as their first step too
- * (so all getters may throw SettingsError and look from both namespaces).
- * @param name Name of the setting to get
- * @return The contents of the setting in a String
- * @throws SettingsError if the setting is not found from either one of
- * the namespaces
- */
+
+ /**
+ * Returns true if a setting with defined name (in the current namespace
+ * or secondary namespace if such is set) exists and has some value
+ * (not just white space)
+ * @param name Name of the setting to check
+ * @return True if the setting exists, false if not
+ */
+ public boolean contains(String name) {
+ try {
+ String value = getSetting(name);
+ if (value == null) {
+ return false;
+ }
+
+ else return value.trim().length() > 0;
+ }
+ catch (SettingsError e) {
+ return false; // didn't find the setting
+ }
+ }
+
+ /**
+ * Returns full (namespace prefixed) property name for setting.
+ * @param name Name of the settings
+ * @param secondary If true, the secondary namespace is used.
+ * @return full (prefixed with current namespace) property name for setting
+ */
+ private String getFullPropertyName(String name, boolean secondary) {
+ String usedNamespace = (secondary ? secondaryNamespace : namespace);
+
+ if (usedNamespace != null) {
+ return usedNamespace + "." + name;
+ }
+ else {
+ return name;
+ }
+ }
+
+ /**
+ * Returns a String-valued setting. Setting is first looked from the
+ * namespace that is set (if any) and then from the secondary namespace
+ * (if any). All other getters use this method as their first step too
+ * (so all getters may throw SettingsError and look from both namespaces).
+ * @param name Name of the setting to get
+ * @return The contents of the setting in a String
+ * @throws SettingsError if the setting is not found from either one of
+ * the namespaces
+ */
public String getSetting(String name) {
- String fullPropName;
- if (props == null) {
- init(null);
- }
- fullPropName = getFullPropertyName(name, false);
- String value = props.getProperty(fullPropName);
-
- if (value != null) { // found value, check if run setting can be parsed
- value = parseRunSetting(value.trim());
- }
-
- if ((value == null || value.length() == 0) &&
- this.secondaryNamespace != null) {
+ String fullPropName;
+ if (props == null) {
+ init(null);
+ }
+ fullPropName = getFullPropertyName(name, false);
+ String value = props.getProperty(fullPropName);
+
+ if (value != null) { // found value, check if run setting can be parsed
+ value = parseRunSetting(value.trim());
+ }
+
+ if ((value == null || value.length() == 0) &&
+ this.secondaryNamespace != null) {
// try secondary namespace if the value wasn't found from primary
- fullPropName = getFullPropertyName(name, true);
- value = props.getProperty(fullPropName);
-
- if (value != null) {
- value = parseRunSetting(value.trim());
- }
- }
-
+ fullPropName = getFullPropertyName(name, true);
+ value = props.getProperty(fullPropName);
+
+ if (value != null) {
+ value = parseRunSetting(value.trim());
+ }
+ }
+
if (value == null || value.length() == 0) {
- throw new SettingsError("Can't find setting " +
+ throw new SettingsError("Can't find setting " +
getPropertyNamesString(name));
- }
-
- outputSetting(fullPropName + " = " + value);
- return value;
- }
-
+ }
+
+ outputSetting(fullPropName + " = " + value);
+ return value;
+ }
+
/**
* Returns the given setting if it exists, or defaultValue if the setting
* does not exist
@@ -404,61 +404,61 @@ public String getSetting(String name, String defaultValue) {
return getSetting(name);
}
}
-
- /**
- * Parses run-specific settings from a String value
- * @param value The String to parse
- * @return The runIndex % arrayLength'th value of the run array
- */
- private static String parseRunSetting(String value) {
- final String RUN_ARRAY_START = "[";
- final String RUN_ARRAY_END = "]";
- final String RUN_ARRAY_DELIM = ";";
- final int MIN_LENGTH = 3; // minimum run is one value. e.g. "[v]"
-
- if (!value.startsWith(RUN_ARRAY_START) ||
- !value.endsWith(RUN_ARRAY_END) ||
- runIndex < 0 ||
- value.length() < MIN_LENGTH) {
- return value; // standard format setting -> return
- }
-
- value = value.substring(1,value.length()-1); // remove brackets
- String[] valueArr = value.split(RUN_ARRAY_DELIM);
- int arrIndex = runIndex % valueArr.length;
- value = valueArr[arrIndex].trim();
-
- return value;
- }
-
- /**
- * Returns the setting name appended to namespace name(s) on a String
- * (for error messages)
- * @param name Name of the setting
- * @return the setting name appended to namespace name(s) on a String
- */
- private String getPropertyNamesString(String name) {
- if (this.secondaryNamespace != null) {
- return "'"+ this.secondaryNamespace + "." + name + "' nor '" +
- this.namespace + "." + name + "'";
- }
- else if (this.namespace != null){
- return "'" + this.namespace + "." + name + "'";
- }
- else {
- return "'" + name + "'";
- }
- }
-
- /**
- * Returns a double-valued setting
- * @param name Name of the setting to get
- * @return Value of the setting as a double
- */
- public double getDouble(String name) {
- return parseDouble(getSetting(name), name);
- }
-
+
+ /**
+ * Parses run-specific settings from a String value
+ * @param value The String to parse
+ * @return The runIndex % arrayLength'th value of the run array
+ */
+ private static String parseRunSetting(String value) {
+ final String RUN_ARRAY_START = "[";
+ final String RUN_ARRAY_END = "]";
+ final String RUN_ARRAY_DELIM = ";";
+ final int MIN_LENGTH = 3; // minimum run is one value. e.g. "[v]"
+
+ if (!value.startsWith(RUN_ARRAY_START) ||
+ !value.endsWith(RUN_ARRAY_END) ||
+ runIndex < 0 ||
+ value.length() < MIN_LENGTH) {
+ return value; // standard format setting -> return
+ }
+
+ value = value.substring(1,value.length()-1); // remove brackets
+ String[] valueArr = value.split(RUN_ARRAY_DELIM);
+ int arrIndex = runIndex % valueArr.length;
+ value = valueArr[arrIndex].trim();
+
+ return value;
+ }
+
+ /**
+ * Returns the setting name appended to namespace name(s) on a String
+ * (for error messages)
+ * @param name Name of the setting
+ * @return the setting name appended to namespace name(s) on a String
+ */
+ private String getPropertyNamesString(String name) {
+ if (this.secondaryNamespace != null) {
+ return "'"+ this.secondaryNamespace + "." + name + "' nor '" +
+ this.namespace + "." + name + "'";
+ }
+ else if (this.namespace != null){
+ return "'" + this.namespace + "." + name + "'";
+ }
+ else {
+ return "'" + name + "'";
+ }
+ }
+
+ /**
+ * Returns a double-valued setting
+ * @param name Name of the setting to get
+ * @return Value of the setting as a double
+ */
+ public double getDouble(String name) {
+ return parseDouble(getSetting(name), name);
+ }
+
/**
* Returns a double-valued setting, or the default value if the given
* setting does not exist
@@ -469,142 +469,142 @@ public double getDouble(String name) {
public double getDouble(String name, double defaultValue) {
return parseDouble(getSetting(name, ""+defaultValue), name);
}
-
- /**
- * Parses a double value from a String valued setting. Supports
- * kilo (k), mega (M) and giga (G) suffixes.
- * @param value String value to parse
- * @param setting The setting where this value was from (for error msgs)
- * @return The value as a double
- * @throws SettingsError if the value wasn't a numeric value
- * (or the suffix wasn't recognized)
- */
- private double parseDouble(String value, String setting) {
- double number;
- int multiplier = 1;
-
- if (value.endsWith("k")) {
- multiplier = 1000;
- }
- else if (value.endsWith("M")) {
- multiplier = 1000000;
- }
- else if (value.endsWith("G")) {
- multiplier = 1000000000;
- }
-
- if (multiplier > 1) { // take the suffix away before parsing
- value = value.substring(0,value.length()-1);
- }
-
- try {
- number = Double.parseDouble(value) * multiplier;
- } catch (NumberFormatException e) {
- throw new SettingsError("Invalid numeric setting '" + value +
- "' for '" + setting +"'\n" + e.getMessage());
- }
- return number;
- }
-
- /**
- * Returns a CSV setting. Value part of the setting must be a list of
- * comma separated values. Whitespace between values is trimmed away.
- * @param name Name of the setting
- * @return Array of values that were comma-separated
- * @throws SettingsError if something went wrong with reading
- */
- public String[] getCsvSetting(String name) {
- ArrayList values = new ArrayList();
- String csv = getSetting(name);
- Scanner s = new Scanner(csv);
- s.useDelimiter(",");
-
- while (s.hasNext()) {
- values.add(s.next().trim());
- }
-
- return values.toArray(new String[0]);
- }
-
- /**
- * Returns a CSV setting containing expected amount of values.
- * Value part of the setting must be a list of
- * comma separated values. Whitespace between values is trimmed away.
- * @param name Name of the setting
- * @param expectedCount how many values are expected
- * @return Array of values that were comma-separated
- * @throws SettingsError if something went wrong with reading or didn't
- * read the expected amount of values.
- */
- public String[] getCsvSetting(String name, int expectedCount) {
- String[] values = getCsvSetting(name);
-
- if (values.length != expectedCount) {
- throw new SettingsError("Read unexpected amount (" + values.length +
- ") of comma separated values for setting '"
- + name + "' (expected " + expectedCount + ")");
- }
-
- return values;
- }
-
- /**
- * Returns an array of CSV setting double values containing expected
- * amount of values.
- * @param name Name of the setting
- * @param expectedCount how many values are expected
- * @return Array of values that were comma-separated
- * @see #getCsvSetting(String, int)
- */
- public double[] getCsvDoubles(String name, int expectedCount) {
- return parseDoubles(getCsvSetting(name, expectedCount),name);
- }
-
- /**
- * Returns an array of CSV setting double values.
- * @param name Name of the setting
- * @return Array of values that were comma-separated
- * @see #getCsvSetting(String)
- */
- public double[] getCsvDoubles(String name) {
- return parseDoubles(getCsvSetting(name), name);
- }
-
- /**
- * Parses a double array out of a String array
- * @param strings The array of strings containing double values
- * @param name Name of the setting
- * @return Array of double values parsed from the string values
- */
- private double[] parseDoubles(String[] strings, String name) {
- double[] values = new double[strings.length];
- for (int i=0; i 1) { // take the suffix away before parsing
+ value = value.substring(0,value.length()-1);
+ }
+
+ try {
+ number = Double.parseDouble(value) * multiplier;
+ } catch (NumberFormatException e) {
+ throw new SettingsError("Invalid numeric setting '" + value +
+ "' for '" + setting +"'\n" + e.getMessage());
+ }
+ return number;
+ }
+
+ /**
+ * Returns a CSV setting. Value part of the setting must be a list of
+ * comma separated values. Whitespace between values is trimmed away.
+ * @param name Name of the setting
+ * @return Array of values that were comma-separated
+ * @throws SettingsError if something went wrong with reading
+ */
+ public String[] getCsvSetting(String name) {
+ ArrayList values = new ArrayList();
+ String csv = getSetting(name);
+ Scanner s = new Scanner(csv);
+ s.useDelimiter(",");
+
+ while (s.hasNext()) {
+ values.add(s.next().trim());
+ }
+
+ return values.toArray(new String[0]);
+ }
+
+ /**
+ * Returns a CSV setting containing expected amount of values.
+ * Value part of the setting must be a list of
+ * comma separated values. Whitespace between values is trimmed away.
+ * @param name Name of the setting
+ * @param expectedCount how many values are expected
+ * @return Array of values that were comma-separated
+ * @throws SettingsError if something went wrong with reading or didn't
+ * read the expected amount of values.
+ */
+ public String[] getCsvSetting(String name, int expectedCount) {
+ String[] values = getCsvSetting(name);
+
+ if (values.length != expectedCount) {
+ throw new SettingsError("Read unexpected amount (" + values.length +
+ ") of comma separated values for setting '"
+ + name + "' (expected " + expectedCount + ")");
+ }
+
+ return values;
+ }
+
+ /**
+ * Returns an array of CSV setting double values containing expected
+ * amount of values.
+ * @param name Name of the setting
+ * @param expectedCount how many values are expected
+ * @return Array of values that were comma-separated
+ * @see #getCsvSetting(String, int)
+ */
+ public double[] getCsvDoubles(String name, int expectedCount) {
+ return parseDoubles(getCsvSetting(name, expectedCount),name);
+ }
+
+ /**
+ * Returns an array of CSV setting double values.
+ * @param name Name of the setting
+ * @return Array of values that were comma-separated
+ * @see #getCsvSetting(String)
+ */
+ public double[] getCsvDoubles(String name) {
+ return parseDoubles(getCsvSetting(name), name);
+ }
+
+ /**
+ * Parses a double array out of a String array
+ * @param strings The array of strings containing double values
+ * @param name Name of the setting
+ * @return Array of double values parsed from the string values
+ */
+ private double[] parseDoubles(String[] strings, String name) {
+ double[] values = new double[strings.length];
+ for (int i=0; i[] argsClass = {Settings.class};
- Object[] args = {this};
-
- return loadObject(className, argsClass, args);
- }
-
- /**
- * Creates (and dynamically loads the class of) an object using the
- * constructor without any parameters.
- * @param className Name of the class of the object
- * @return Initialized object
- * @throws SettingsError if object couldn't be created
- */
- public Object createObject(String className) {
- return loadObject(className, null, null);
- }
-
- /**
- * Dynamically loads and creates an object.
- * @param className Name of the class of the object
- * @param argsClass Class(es) of the argument(s) or null if no-argument
- * constructor should be called
- * @param args Argument(s)
- * @return The new object
- * @throws SettingsError if object couldn't be created
- */
- private Object loadObject(String className, Class>[] argsClass,
- Object[] args) {
- Object o = null;
- Class> objClass = getClass(className);
- Constructor> constructor;
-
- try {
- if (argsClass != null) { // use a specific constructor
- constructor = objClass.getConstructor((Class[])argsClass);
- o = constructor.newInstance(args);
- }
- else { // call empty constructor
- o = objClass.newInstance();
- }
- } catch (SecurityException e) {
- e.printStackTrace();
- throw new SettingsError("Fatal exception " + e, e);
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- throw new SettingsError("Fatal exception " + e, e);
- } catch (NoSuchMethodException e) {
- throw new SettingsError("Class '" + className +
- "' doesn't have a suitable constructor", e);
- } catch (InstantiationException e) {
- throw new SettingsError("Can't create an instance of '" +
- className + "'", e);
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- throw new SettingsError("Fatal exception " + e, e);
- } catch (InvocationTargetException e) {
- // this exception occurs if initialization of the object fails
+ }
+
+ /**
+ * Creates (and dynamically loads the class of) an object that
+ * initializes itself using the settings in this Settings object
+ * (given as the only parameter to the constructor).
+ * @param className Name of the class of the object
+ * @return Initialized object
+ * @throws SettingsError if object couldn't be created
+ */
+ public Object createIntializedObject(String className) {
+ Class>[] argsClass = {Settings.class};
+ Object[] args = {this};
+
+ return loadObject(className, argsClass, args);
+ }
+
+ /**
+ * Creates (and dynamically loads the class of) an object using the
+ * constructor without any parameters.
+ * @param className Name of the class of the object
+ * @return Initialized object
+ * @throws SettingsError if object couldn't be created
+ */
+ public Object createObject(String className) {
+ return loadObject(className, null, null);
+ }
+
+ /**
+ * Dynamically loads and creates an object.
+ * @param className Name of the class of the object
+ * @param argsClass Class(es) of the argument(s) or null if no-argument
+ * constructor should be called
+ * @param args Argument(s)
+ * @return The new object
+ * @throws SettingsError if object couldn't be created
+ */
+ private Object loadObject(String className, Class>[] argsClass,
+ Object[] args) {
+ Object o = null;
+ Class> objClass = getClass(className);
+ Constructor> constructor;
+
+ try {
+ if (argsClass != null) { // use a specific constructor
+ constructor = objClass.getConstructor((Class[])argsClass);
+ o = constructor.newInstance(args);
+ }
+ else { // call empty constructor
+ o = objClass.newInstance();
+ }
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ throw new SettingsError("Fatal exception " + e, e);
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ throw new SettingsError("Fatal exception " + e, e);
+ } catch (NoSuchMethodException e) {
+ throw new SettingsError("Class '" + className +
+ "' doesn't have a suitable constructor", e);
+ } catch (InstantiationException e) {
+ throw new SettingsError("Can't create an instance of '" +
+ className + "'", e);
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ throw new SettingsError("Fatal exception " + e, e);
+ } catch (InvocationTargetException e) {
+ // this exception occurs if initialization of the object fails
if (e.getCause() instanceof SettingsError) {
throw (SettingsError)e.getCause();
}
- else {
- e.printStackTrace();
- throw new SimError("Couldn't create settings-accepting object"+
+ else {
+ e.printStackTrace();
+ throw new SimError("Couldn't create settings-accepting object"+
" for '" + className + "'\n" + "cause: " + e.getCause(), e);
- }
- }
-
- return o;
- }
-
- /**
- * Returns a Class object for the name of class of throws SettingsError
- * if such class wasn't found.
- * @param name Full name of the class (including package name)
- * @return A Class object of that class
- * @throws SettingsError if such class wasn't found or couldn't be loaded
- */
- private Class> getClass(String name) {
- String className = name;
- Class> c;
-
- try {
- c = Class.forName(className);
- } catch (ClassNotFoundException e) {
- throw new SettingsError("Couldn't find class '" + className + "'"+
- "\n" + e.getMessage(),e);
- }
-
- return c;
- }
-
- /**
- * Fills a String formatted in a special way with values from Settings.
- * String can contain (fully qualified) setting names surrounded by
- * delimiters (see {@link #FILL_DELIMITER}). Values for those settings
- * are retrieved and filled in the place of place holders.
- * @param input The input string that may contain value requests
- * @return A string filled with requested values (or the original string
- * if no requests were found)
- * @throws SettingsError if such settings were not found
- */
- public String valueFillString(String input) {
- if (!input.contains(FILL_DELIMITER)) {
- return input; // nothing to fill
- }
-
- Settings s = new Settings(); // don't use any namespace
- String result = "";
- Scanner scan = new Scanner(input);
- scan.useDelimiter(FILL_DELIMITER);
-
- if (input.startsWith(FILL_DELIMITER)) {
- result += s.getSetting(scan.next());
- }
-
- while(scan.hasNext()) {
- result += scan.next();
- if (!scan.hasNext()) {
- break;
- }
- result += s.getSetting(scan.next());
- }
-
- return result;
- }
-
- /**
- * Returns a String representation of the stored settings
- * @return a String representation of the stored settings
- */
- public String toString() {
- return props.toString();
- }
-
-}
\ No newline at end of file
+ }
+ }
+
+ return o;
+ }
+
+ /**
+ * Returns a Class object for the name of class of throws SettingsError
+ * if such class wasn't found.
+ * @param name Full name of the class (including package name)
+ * @return A Class object of that class
+ * @throws SettingsError if such class wasn't found or couldn't be loaded
+ */
+ private Class> getClass(String name) {
+ String className = name;
+ Class> c;
+
+ try {
+ c = Class.forName(className);
+ } catch (ClassNotFoundException e) {
+ throw new SettingsError("Couldn't find class '" + className + "'"+
+ "\n" + e.getMessage(),e);
+ }
+
+ return c;
+ }
+
+ /**
+ * Fills a String formatted in a special way with values from Settings.
+ * String can contain (fully qualified) setting names surrounded by
+ * delimiters (see {@link #FILL_DELIMITER}). Values for those settings
+ * are retrieved and filled in the place of place holders.
+ * @param input The input string that may contain value requests
+ * @return A string filled with requested values (or the original string
+ * if no requests were found)
+ * @throws SettingsError if such settings were not found
+ */
+ public String valueFillString(String input) {
+ if (!input.contains(FILL_DELIMITER)) {
+ return input; // nothing to fill
+ }
+
+ Settings s = new Settings(); // don't use any namespace
+ String result = "";
+ Scanner scan = new Scanner(input);
+ scan.useDelimiter(FILL_DELIMITER);
+
+ if (input.startsWith(FILL_DELIMITER)) {
+ result += s.getSetting(scan.next());
+ }
+
+ while(scan.hasNext()) {
+ result += scan.next();
+ if (!scan.hasNext()) {
+ break;
+ }
+ result += s.getSetting(scan.next());
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns a String representation of the stored settings
+ * @return a String representation of the stored settings
+ */
+ public String toString() {
+ return props.toString();
+ }
+
+}
diff --git a/core/SettingsError.java b/core/SettingsError.java
index 5f4e42a18..e20085075 100644
--- a/core/SettingsError.java
+++ b/core/SettingsError.java
@@ -1,25 +1,25 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package core;
-
-/**
- * Settings related error
- *
- */
-public class SettingsError extends SimError {
-
- public SettingsError(String cause) {
- super(cause);
- }
-
- public SettingsError(String cause, Exception e) {
- super(cause,e);
- }
-
- public SettingsError(Exception e) {
- super(e);
- }
-
-}
+package core;
+
+/**
+ * Settings related error
+ *
+ */
+public class SettingsError extends SimError {
+
+ public SettingsError(String cause) {
+ super(cause);
+ }
+
+ public SettingsError(String cause, Exception e) {
+ super(cause,e);
+ }
+
+ public SettingsError(Exception e) {
+ super(e);
+ }
+
+}
diff --git a/core/SimClock.java b/core/SimClock.java
index d67c5fde2..788d7300d 100644
--- a/core/SimClock.java
+++ b/core/SimClock.java
@@ -1,50 +1,50 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
package core;
-
-/**
- * Wall clock for checking the simulation time.
- */
-public class SimClock {
- private static double clockTime = 0.0;
+
+/**
+ * Wall clock for checking the simulation time.
+ */
+public class SimClock {
+ private static double clockTime = 0.0;
private static SimClock clock = null;
-
- private SimClock() {}
-
+
+ private SimClock() {}
+
static {
- DTNSim.registerForReset(SimClock.class.getCanonicalName());
- reset();
- }
-
- /**
- * Get the instance of the class that can also change the time.
- * @return The instance of this clock
- */
- public static SimClock getInstance() {
- if (clock == null) {
- clock = new SimClock();
- }
- return clock;
- }
-
- /**
- * Returns the current time (seconds since start)
- * @return Time as a double
- */
- public static double getTime() {
- return clockTime;
- }
-
- /**
- * Returns the current time rounded to the nearest integer
- * @return Time as integer
- */
- public static int getIntTime() {
- return (int)Math.round(clockTime);
- }
-
+ DTNSim.registerForReset(SimClock.class.getCanonicalName());
+ reset();
+ }
+
+ /**
+ * Get the instance of the class that can also change the time.
+ * @return The instance of this clock
+ */
+ public static SimClock getInstance() {
+ if (clock == null) {
+ clock = new SimClock();
+ }
+ return clock;
+ }
+
+ /**
+ * Returns the current time (seconds since start)
+ * @return Time as a double
+ */
+ public static double getTime() {
+ return clockTime;
+ }
+
+ /**
+ * Returns the current time rounded to the nearest integer
+ * @return Time as integer
+ */
+ public static int getIntTime() {
+ return (int)Math.round(clockTime);
+ }
+
/**
* Returns a string presentation of the sim time shown with the given amount
* of decimals
@@ -54,35 +54,35 @@ public static int getIntTime() {
public static String getFormattedTime(int decimals) {
return String.format("%." + decimals + "f", clockTime);
}
-
- /**
- * Advances the time by n seconds
- * @param time Nrof seconds to increase the time
- */
- public void advance(double time) {
- clockTime += time;
- }
-
- /**
- * Sets the time of the clock.
- * @param time the time to set
- */
- public void setTime(double time) {
- clockTime = time;
- }
-
- /**
- * Returns the current simulation time in a string
- * @return the current simulation time in a string
- */
- public String toString() {
- return "SimTime: " + clockTime;
- }
-
- /**
- * Resets the static fields of the class
- */
- public static void reset() {
- clockTime = 0;
- }
-}
+
+ /**
+ * Advances the time by n seconds
+ * @param time Nrof seconds to increase the time
+ */
+ public void advance(double time) {
+ clockTime += time;
+ }
+
+ /**
+ * Sets the time of the clock.
+ * @param time the time to set
+ */
+ public void setTime(double time) {
+ clockTime = time;
+ }
+
+ /**
+ * Returns the current simulation time in a string
+ * @return the current simulation time in a string
+ */
+ public String toString() {
+ return "SimTime: " + clockTime;
+ }
+
+ /**
+ * Resets the static fields of the class
+ */
+ public static void reset() {
+ clockTime = 0;
+ }
+}
diff --git a/core/SimError.java b/core/SimError.java
index fdccc0500..9d60a127b 100644
--- a/core/SimError.java
+++ b/core/SimError.java
@@ -1,32 +1,32 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package core;
-
-/**
- * Error in the simulation
- *
- */
-public class SimError extends AssertionError {
- private Exception e;
-
- public SimError(String cause) {
- super(cause);
- e = null;
- }
-
- public SimError(String cause, Exception e) {
- super(cause);
- this.e = e;
- }
-
- public SimError(Exception e) {
- this(e.getMessage(),e);
- }
-
- public Exception getException() {
- return e;
- }
-
-}
+package core;
+
+/**
+ * Error in the simulation
+ *
+ */
+public class SimError extends AssertionError {
+ private Exception e;
+
+ public SimError(String cause) {
+ super(cause);
+ e = null;
+ }
+
+ public SimError(String cause, Exception e) {
+ super(cause);
+ this.e = e;
+ }
+
+ public SimError(Exception e) {
+ this(e.getMessage(),e);
+ }
+
+ public Exception getException() {
+ return e;
+ }
+
+}
diff --git a/core/SimScenario.java b/core/SimScenario.java
index b2fcf5767..8fc4a7038 100644
--- a/core/SimScenario.java
+++ b/core/SimScenario.java
@@ -1,9 +1,9 @@
-/*
+/*
* Copyright 2011 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package core;
-
+package core;
+
import input.EventQueue;
import input.EventQueueHandler;
@@ -15,30 +15,30 @@
import movement.MovementModel;
import movement.map.SimMap;
import routing.MessageRouter;
-
-/**
- * A simulation scenario used for getting and storing the settings of a
- * simulation run.
- */
+
+/**
+ * A simulation scenario used for getting and storing the settings of a
+ * simulation run.
+ */
public class SimScenario implements Serializable {
-
- /** a way to get a hold of this... */
+
+ /** a way to get a hold of this... */
private static SimScenario myinstance=null;
-
- /** namespace of scenario settings ({@value})*/
- public static final String SCENARIO_NS = "Scenario";
- /** number of host groups -setting id ({@value})*/
- public static final String NROF_GROUPS_S = "nrofHostGroups";
+
+ /** namespace of scenario settings ({@value})*/
+ public static final String SCENARIO_NS = "Scenario";
+ /** number of host groups -setting id ({@value})*/
+ public static final String NROF_GROUPS_S = "nrofHostGroups";
/** number of interface types -setting id ({@value})*/
public static final String NROF_INTTYPES_S = "nrofInterfaceTypes";
- /** scenario name -setting id ({@value})*/
- public static final String NAME_S = "name";
- /** end time -setting id ({@value})*/
- public static final String END_TIME_S = "endTime";
- /** update interval -setting id ({@value})*/
- public static final String UP_INT_S = "updateInterval";
- /** simulate connections -setting id ({@value})*/
- public static final String SIM_CON_S = "simulateConnections";
+ /** scenario name -setting id ({@value})*/
+ public static final String NAME_S = "name";
+ /** end time -setting id ({@value})*/
+ public static final String END_TIME_S = "endTime";
+ /** update interval -setting id ({@value})*/
+ public static final String UP_INT_S = "updateInterval";
+ /** simulate connections -setting id ({@value})*/
+ public static final String SIM_CON_S = "simulateConnections";
/** namespace for interface type settings ({@value}) */
public static final String INTTYPE_NS = "Interface";
@@ -53,119 +53,119 @@ public class SimScenario implements Serializable {
public static final String APPTYPE_S = "type";
/** setting name for the number of applications */
public static final String APPCOUNT_S = "nrofApplications";
-
- /** namespace for host group settings ({@value})*/
- public static final String GROUP_NS = "Group";
- /** group id -setting id ({@value})*/
- public static final String GROUP_ID_S = "groupID";
- /** number of hosts in the group -setting id ({@value})*/
- public static final String NROF_HOSTS_S = "nrofHosts";
- /** movement model class -setting id ({@value})*/
- public static final String MOVEMENT_MODEL_S = "movementModel";
- /** router class -setting id ({@value})*/
- public static final String ROUTER_S = "router";
+
+ /** namespace for host group settings ({@value})*/
+ public static final String GROUP_NS = "Group";
+ /** group id -setting id ({@value})*/
+ public static final String GROUP_ID_S = "groupID";
+ /** number of hosts in the group -setting id ({@value})*/
+ public static final String NROF_HOSTS_S = "nrofHosts";
+ /** movement model class -setting id ({@value})*/
+ public static final String MOVEMENT_MODEL_S = "movementModel";
+ /** router class -setting id ({@value})*/
+ public static final String ROUTER_S = "router";
/** number of interfaces in the group -setting id ({@value})*/
public static final String NROF_INTERF_S = "nrofInterfaces";
/** interface name in the group -setting id ({@value})*/
public static final String INTERFACENAME_S = "interface";
/** application name in the group -setting id ({@value})*/
public static final String GAPPNAME_S = "application";
-
- /** package where to look for movement models */
- private static final String MM_PACKAGE = "movement.";
- /** package where to look for router classes */
- private static final String ROUTING_PACKAGE = "routing.";
+
+ /** package where to look for movement models */
+ private static final String MM_PACKAGE = "movement.";
+ /** package where to look for router classes */
+ private static final String ROUTING_PACKAGE = "routing.";
/** package where to look for interface classes */
private static final String INTTYPE_PACKAGE = "interfaces.";
-
+
/** package where to look for application classes */
private static final String APP_PACKAGE = "applications.";
-
+
/** The world instance */
- private World world;
- /** List of hosts in this simulation */
- protected List hosts;
- /** Name of the simulation */
- private String name;
- /** number of host groups */
- int nrofGroups;
- /** Width of the world */
- private int worldSizeX;
- /** Height of the world */
- private int worldSizeY;
- /** Largest host's radio range */
- private double maxHostRange;
- /** Simulation end time */
- private double endTime;
- /** Update interval of sim time */
- private double updateInterval;
- /** External events queue */
- private EventQueueHandler eqHandler;
- /** Should connections between hosts be simulated */
- private boolean simulateConnections;
- /** Map used for host movement (if any) */
- private SimMap simMap;
-
- /** Global connection event listeners */
- private List connectionListeners;
- /** Global message event listeners */
- private List messageListeners;
- /** Global movement event listeners */
- private List movementListeners;
- /** Global update event listeners */
+ private World world;
+ /** List of hosts in this simulation */
+ protected List hosts;
+ /** Name of the simulation */
+ private String name;
+ /** number of host groups */
+ int nrofGroups;
+ /** Width of the world */
+ private int worldSizeX;
+ /** Height of the world */
+ private int worldSizeY;
+ /** Largest host's radio range */
+ private double maxHostRange;
+ /** Simulation end time */
+ private double endTime;
+ /** Update interval of sim time */
+ private double updateInterval;
+ /** External events queue */
+ private EventQueueHandler eqHandler;
+ /** Should connections between hosts be simulated */
+ private boolean simulateConnections;
+ /** Map used for host movement (if any) */
+ private SimMap simMap;
+
+ /** Global connection event listeners */
+ private List connectionListeners;
+ /** Global message event listeners */
+ private List messageListeners;
+ /** Global movement event listeners */
+ private List movementListeners;
+ /** Global update event listeners */
private List updateListeners;
/** Global application event listeners */
- private List appListeners;
+ private List appListeners;
static {
DTNSim.registerForReset(SimScenario.class.getCanonicalName());
reset();
}
-
+
public static void reset() {
myinstance = null;
- }
-
- /**
- * Creates a scenario based on Settings object.
- */
- protected SimScenario() {
- Settings s = new Settings(SCENARIO_NS);
- nrofGroups = s.getInt(NROF_GROUPS_S);
-
- this.name = s.valueFillString(s.getSetting(NAME_S));
- this.endTime = s.getDouble(END_TIME_S);
- this.updateInterval = s.getDouble(UP_INT_S);
- this.simulateConnections = s.getBoolean(SIM_CON_S);
-
- s.ensurePositiveValue(nrofGroups, NROF_GROUPS_S);
- s.ensurePositiveValue(endTime, END_TIME_S);
- s.ensurePositiveValue(updateInterval, UP_INT_S);
-
- this.simMap = null;
- this.maxHostRange = 1;
-
- this.connectionListeners = new ArrayList();
- this.messageListeners = new ArrayList();
- this.movementListeners = new ArrayList();
+ }
+
+ /**
+ * Creates a scenario based on Settings object.
+ */
+ protected SimScenario() {
+ Settings s = new Settings(SCENARIO_NS);
+ nrofGroups = s.getInt(NROF_GROUPS_S);
+
+ this.name = s.valueFillString(s.getSetting(NAME_S));
+ this.endTime = s.getDouble(END_TIME_S);
+ this.updateInterval = s.getDouble(UP_INT_S);
+ this.simulateConnections = s.getBoolean(SIM_CON_S);
+
+ s.ensurePositiveValue(nrofGroups, NROF_GROUPS_S);
+ s.ensurePositiveValue(endTime, END_TIME_S);
+ s.ensurePositiveValue(updateInterval, UP_INT_S);
+
+ this.simMap = null;
+ this.maxHostRange = 1;
+
+ this.connectionListeners = new ArrayList();
+ this.messageListeners = new ArrayList();
+ this.movementListeners = new ArrayList();
this.updateListeners = new ArrayList();
- this.appListeners = new ArrayList();
- this.eqHandler = new EventQueueHandler();
+ this.appListeners = new ArrayList();
+ this.eqHandler = new EventQueueHandler();
/* TODO: check size from movement models */
s.setNameSpace(MovementModel.MOVEMENT_MODEL_NS);
int [] worldSize = s.getCsvInts(MovementModel.WORLD_SIZE, 2);
this.worldSizeX = worldSize[0];
this.worldSizeY = worldSize[1];
-
+
createHosts();
-
- this.world = new World(hosts, worldSizeX, worldSizeY, updateInterval,
- updateListeners, simulateConnections,
+
+ this.world = new World(hosts, worldSizeX, worldSizeY, updateInterval,
+ updateListeners, simulateConnections,
eqHandler.getEventQueues());
}
-
+
/**
* Returns the SimScenario instance and creates one if it doesn't exist yet
*/
@@ -174,132 +174,132 @@ public static SimScenario getInstance() {
myinstance = new SimScenario();
}
return myinstance;
- }
-
-
-
- /**
- * Returns the name of the simulation run
- * @return the name of the simulation run
- */
- public String getName() {
- return this.name;
- }
-
- /**
- * Returns true if connections should be simulated
- * @return true if connections should be simulated (false if not)
- */
- public boolean simulateConnections() {
- return this.simulateConnections;
- }
-
- /**
- * Returns the width of the world
- * @return the width of the world
- */
- public int getWorldSizeX() {
- return this.worldSizeX;
- }
-
- /**
- * Returns the height of the world
- * @return the height of the world
- */
- public int getWorldSizeY() {
- return worldSizeY;
- }
-
- /**
- * Returns simulation's end time
- * @return simulation's end time
- */
- public double getEndTime() {
- return endTime;
- }
-
- /**
- * Returns update interval (simulated seconds) of the simulation
- * @return update interval (simulated seconds) of the simulation
- */
- public double getUpdateInterval() {
- return updateInterval;
- }
-
- /**
- * Returns how long range the hosts' radios have
- * @return Range in meters
- */
- public double getMaxHostRange() {
- return maxHostRange;
- }
-
- /**
- * Returns the (external) event queue(s) of this scenario or null if there
- * aren't any
- * @return External event queues in a list or null
- */
- public List getExternalEvents() {
- return this.eqHandler.getEventQueues();
- }
-
- /**
- * Returns the SimMap this scenario uses, or null if scenario doesn't
- * use any map
- * @return SimMap or null if no map is used
- */
- public SimMap getMap() {
- return this.simMap;
- }
-
- /**
- * Adds a new connection listener for all nodes
- * @param cl The listener
- */
- public void addConnectionListener(ConnectionListener cl){
- this.connectionListeners.add(cl);
- }
-
- /**
- * Adds a new message listener for all nodes
- * @param ml The listener
- */
- public void addMessageListener(MessageListener ml){
- this.messageListeners.add(ml);
- }
-
- /**
- * Adds a new movement listener for all nodes
- * @param ml The listener
- */
- public void addMovementListener(MovementListener ml){
- this.movementListeners.add(ml);
- }
-
- /**
- * Adds a new update listener for the world
- * @param ul The listener
- */
- public void addUpdateListener(UpdateListener ul) {
- this.updateListeners.add(ul);
- }
-
- /**
- * Returns the list of registered update listeners
- * @return the list of registered update listeners
- */
- public List getUpdateListeners() {
- return this.updateListeners;
- }
-
- /**
+ }
+
+
+
+ /**
+ * Returns the name of the simulation run
+ * @return the name of the simulation run
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * Returns true if connections should be simulated
+ * @return true if connections should be simulated (false if not)
+ */
+ public boolean simulateConnections() {
+ return this.simulateConnections;
+ }
+
+ /**
+ * Returns the width of the world
+ * @return the width of the world
+ */
+ public int getWorldSizeX() {
+ return this.worldSizeX;
+ }
+
+ /**
+ * Returns the height of the world
+ * @return the height of the world
+ */
+ public int getWorldSizeY() {
+ return worldSizeY;
+ }
+
+ /**
+ * Returns simulation's end time
+ * @return simulation's end time
+ */
+ public double getEndTime() {
+ return endTime;
+ }
+
+ /**
+ * Returns update interval (simulated seconds) of the simulation
+ * @return update interval (simulated seconds) of the simulation
+ */
+ public double getUpdateInterval() {
+ return updateInterval;
+ }
+
+ /**
+ * Returns how long range the hosts' radios have
+ * @return Range in meters
+ */
+ public double getMaxHostRange() {
+ return maxHostRange;
+ }
+
+ /**
+ * Returns the (external) event queue(s) of this scenario or null if there
+ * aren't any
+ * @return External event queues in a list or null
+ */
+ public List getExternalEvents() {
+ return this.eqHandler.getEventQueues();
+ }
+
+ /**
+ * Returns the SimMap this scenario uses, or null if scenario doesn't
+ * use any map
+ * @return SimMap or null if no map is used
+ */
+ public SimMap getMap() {
+ return this.simMap;
+ }
+
+ /**
+ * Adds a new connection listener for all nodes
+ * @param cl The listener
+ */
+ public void addConnectionListener(ConnectionListener cl){
+ this.connectionListeners.add(cl);
+ }
+
+ /**
+ * Adds a new message listener for all nodes
+ * @param ml The listener
+ */
+ public void addMessageListener(MessageListener ml){
+ this.messageListeners.add(ml);
+ }
+
+ /**
+ * Adds a new movement listener for all nodes
+ * @param ml The listener
+ */
+ public void addMovementListener(MovementListener ml){
+ this.movementListeners.add(ml);
+ }
+
+ /**
+ * Adds a new update listener for the world
+ * @param ul The listener
+ */
+ public void addUpdateListener(UpdateListener ul) {
+ this.updateListeners.add(ul);
+ }
+
+ /**
+ * Returns the list of registered update listeners
+ * @return the list of registered update listeners
+ */
+ public List getUpdateListeners() {
+ return this.updateListeners;
+ }
+
+ /**
* Adds a new application event listener for all nodes.
* @param al The listener
*/
public void addApplicationListener(ApplicationListener al) {
this.appListeners.add(al);
}
-
+
/**
* Returns the list of registered application event listeners
* @return the list of registered application event listeners
@@ -307,46 +307,46 @@ public void addApplicationListener(ApplicationListener al) {
public List getApplicationListeners() {
return this.appListeners;
}
-
- /**
- * Creates hosts for the scenario
- */
- protected void createHosts() {
- this.hosts = new ArrayList();
-
+
+ /**
+ * Creates hosts for the scenario
+ */
+ protected void createHosts() {
+ this.hosts = new ArrayList();
+
for (int i=1; i<=nrofGroups; i++) {
- List interfaces =
- new ArrayList();
- Settings s = new Settings(GROUP_NS+i);
- s.setSecondaryNamespace(GROUP_NS);
- String gid = s.getSetting(GROUP_ID_S);
+ List interfaces =
+ new ArrayList();
+ Settings s = new Settings(GROUP_NS+i);
+ s.setSecondaryNamespace(GROUP_NS);
+ String gid = s.getSetting(GROUP_ID_S);
int nrofHosts = s.getInt(NROF_HOSTS_S);
- int nrofInterfaces = s.getInt(NROF_INTERF_S);
- int appCount;
-
- // creates prototypes of MessageRouter and MovementModel
- MovementModel mmProto =
- (MovementModel)s.createIntializedObject(MM_PACKAGE +
- s.getSetting(MOVEMENT_MODEL_S));
- MessageRouter mRouterProto =
- (MessageRouter)s.createIntializedObject(ROUTING_PACKAGE +
+ int nrofInterfaces = s.getInt(NROF_INTERF_S);
+ int appCount;
+
+ // creates prototypes of MessageRouter and MovementModel
+ MovementModel mmProto =
+ (MovementModel)s.createIntializedObject(MM_PACKAGE +
+ s.getSetting(MOVEMENT_MODEL_S));
+ MessageRouter mRouterProto =
+ (MessageRouter)s.createIntializedObject(ROUTING_PACKAGE +
s.getSetting(ROUTER_S));
-
- /* checks that these values are positive (throws Error if not) */
- s.ensurePositiveValue(nrofHosts, NROF_HOSTS_S);
+
+ /* checks that these values are positive (throws Error if not) */
+ s.ensurePositiveValue(nrofHosts, NROF_HOSTS_S);
s.ensurePositiveValue(nrofInterfaces, NROF_INTERF_S);
// setup interfaces
for (int j=1;j<=nrofInterfaces;j++) {
String intName = s.getSetting(INTERFACENAME_S + j);
- Settings intSettings = new Settings(intName);
- NetworkInterface iface =
+ Settings intSettings = new Settings(intName);
+ NetworkInterface iface =
(NetworkInterface)intSettings.createIntializedObject(
INTTYPE_PACKAGE +intSettings.getSetting(INTTYPE_S));
iface.setClisteners(connectionListeners);
iface.setGroupSettings(s);
interfaces.add(iface);
- }
+ }
// setup applications
if (s.contains(APPCOUNT_S)) {
@@ -376,40 +376,40 @@ protected void createHosts() {
System.err.println("Caught at " + se.getStackTrace()[0]);
System.exit(-1);
}
- }
-
- if (mmProto instanceof MapBasedMovement) {
- this.simMap = ((MapBasedMovement)mmProto).getMap();
- }
-
- // creates hosts of ith group
- for (int j=0; j getHosts() {
- return this.hosts;
+
+ // prototypes are given to new DTNHost which replicates
+ // new instances of movement model and message router
+ DTNHost host = new DTNHost(this.messageListeners,
+ this.movementListeners, gid, interfaces, comBus,
+ mmProto, mRouterProto);
+ hosts.add(host);
+ }
+ }
}
-
+
+ /**
+ * Returns the list of nodes for this scenario.
+ * @return the list of nodes for this scenario.
+ */
+ public List getHosts() {
+ return this.hosts;
+ }
+
/**
* Returns the World object of this scenario
* @return the World object
*/
public World getWorld() {
return this.world;
- }
-
-}
\ No newline at end of file
+ }
+
+}
diff --git a/core/UpdateListener.java b/core/UpdateListener.java
index 276d7cae6..83b52a50f 100644
--- a/core/UpdateListener.java
+++ b/core/UpdateListener.java
@@ -1,24 +1,24 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package core;
-
+package core;
+
import java.util.List;
-
-/**
- * Interface for classes that want to be informed about every single update
+
+/**
+ * Interface for classes that want to be informed about every single update
* call to the World object.
- * NOTE: if update interval is large (if, e.g., no movement or
+ * NOTE: if update interval is large (if, e.g., no movement or
* connection simulation is needed), update listeners may not get called at all
- * during the simulation.
- */
-public interface UpdateListener {
-
- /**
- * Method is called on every update cycle.
- * @param hosts A list of all hosts in the world
- */
- public void updated(List hosts);
-
-}
+ * during the simulation.
+ */
+public interface UpdateListener {
+
+ /**
+ * Method is called on every update cycle.
+ * @param hosts A list of all hosts in the world
+ */
+ public void updated(List hosts);
+
+}
diff --git a/core/VBRConnection.java b/core/VBRConnection.java
index 6750e2130..c2ad1603a 100644
--- a/core/VBRConnection.java
+++ b/core/VBRConnection.java
@@ -1,113 +1,113 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
- */
-package core;
-
-import routing.MessageRouter;
-
-/**
- * A connection between two DTN nodes. The transmission speed
- * is updated every round from the end point transmission speeds
- */
-public class VBRConnection extends Connection {
- private int msgsize;
- private int msgsent;
- private int currentspeed = 0;
- private double lastUpdate = 0;
-
-
- /**
- * Creates a new connection between nodes and sets the connection
- * state to "up".
- * @param fromNode The node that initiated the connection
- * @param fromInterface The interface that initiated the connection
- * @param toNode The node in the other side of the connection
- * @param toInterface The interface in the other side of the connection
- */
- public VBRConnection(DTNHost fromNode, NetworkInterface fromInterface,
- DTNHost toNode, NetworkInterface toInterface) {
- super(fromNode, fromInterface, toNode, toInterface);
- this.msgsent = 0;
- }
-
- /**
- * Sets a message that this connection is currently transferring. If message
- * passing is controlled by external events, this method is not needed
- * (but then e.g. {@link #finalizeTransfer()} and
- * {@link #isMessageTransferred()} will not work either). Only a one message
- * at a time can be transferred using one connection.
- * @param from The host sending the message
- * @param m The message
- * @return The value returned by
- * {@link MessageRouter#receiveMessage(Message, DTNHost)}
- */
- public int startTransfer(DTNHost from, Message m) {
- assert this.msgOnFly == null : "Already transferring " +
- this.msgOnFly + " from " + this.msgFromNode + " to " +
- this.getOtherNode(this.msgFromNode) + ". Can't "+
- "start transfer of " + m + " from " + from;
-
- this.msgFromNode = from;
- Message newMessage = m.replicate();
- int retVal = getOtherNode(from).receiveMessage(newMessage, from);
-
- if (retVal == MessageRouter.RCV_OK) {
- this.msgOnFly = newMessage;
- this.msgsize = m.getSize();
- this.msgsent = 0;
- }
-
- return retVal;
- }
-
- /**
- * Calculate the current transmission speed from the information
- * given by the interfaces, and calculate the missing data amount.
- *
- */
- public void update() {
- currentspeed = this.fromInterface.getTransmitSpeed(toInterface);
- int othspeed = this.toInterface.getTransmitSpeed(fromInterface);
- double now = core.SimClock.getTime();
-
- if (othspeed < currentspeed) {
- currentspeed = othspeed;
- }
-
-
- msgsent += currentspeed * (now - this.lastUpdate);
- this.lastUpdate = now;
- }
-
- /**
- * returns the current speed of the connection
- */
- public double getSpeed() {
- return this.currentspeed;
- }
-
- /**
- * Returns the amount of bytes to be transferred before ongoing transfer
- * is ready or 0 if there's no ongoing transfer or it has finished
- * already
- * @return the amount of bytes to be transferred
- */
- public int getRemainingByteCount() {
- int bytesLeft = msgsize - msgsent;
- return (bytesLeft > 0 ? bytesLeft : 0);
- }
-
- /**
- * Returns true if the current message transfer is done.
- * @return True if the transfer is done, false if not
- */
- public boolean isMessageTransferred() {
- if (msgsent >= msgsize) {
- return true;
- } else {
- return false;
- }
- }
-
-}
+ * Released under GPLv3. See LICENSE.txt for details.
+ */
+package core;
+
+import routing.MessageRouter;
+
+/**
+ * A connection between two DTN nodes. The transmission speed
+ * is updated every round from the end point transmission speeds
+ */
+public class VBRConnection extends Connection {
+ private int msgsize;
+ private int msgsent;
+ private int currentspeed = 0;
+ private double lastUpdate = 0;
+
+
+ /**
+ * Creates a new connection between nodes and sets the connection
+ * state to "up".
+ * @param fromNode The node that initiated the connection
+ * @param fromInterface The interface that initiated the connection
+ * @param toNode The node in the other side of the connection
+ * @param toInterface The interface in the other side of the connection
+ */
+ public VBRConnection(DTNHost fromNode, NetworkInterface fromInterface,
+ DTNHost toNode, NetworkInterface toInterface) {
+ super(fromNode, fromInterface, toNode, toInterface);
+ this.msgsent = 0;
+ }
+
+ /**
+ * Sets a message that this connection is currently transferring. If message
+ * passing is controlled by external events, this method is not needed
+ * (but then e.g. {@link #finalizeTransfer()} and
+ * {@link #isMessageTransferred()} will not work either). Only a one message
+ * at a time can be transferred using one connection.
+ * @param from The host sending the message
+ * @param m The message
+ * @return The value returned by
+ * {@link MessageRouter#receiveMessage(Message, DTNHost)}
+ */
+ public int startTransfer(DTNHost from, Message m) {
+ assert this.msgOnFly == null : "Already transferring " +
+ this.msgOnFly + " from " + this.msgFromNode + " to " +
+ this.getOtherNode(this.msgFromNode) + ". Can't "+
+ "start transfer of " + m + " from " + from;
+
+ this.msgFromNode = from;
+ Message newMessage = m.replicate();
+ int retVal = getOtherNode(from).receiveMessage(newMessage, from);
+
+ if (retVal == MessageRouter.RCV_OK) {
+ this.msgOnFly = newMessage;
+ this.msgsize = m.getSize();
+ this.msgsent = 0;
+ }
+
+ return retVal;
+ }
+
+ /**
+ * Calculate the current transmission speed from the information
+ * given by the interfaces, and calculate the missing data amount.
+ *
+ */
+ public void update() {
+ currentspeed = this.fromInterface.getTransmitSpeed(toInterface);
+ int othspeed = this.toInterface.getTransmitSpeed(fromInterface);
+ double now = core.SimClock.getTime();
+
+ if (othspeed < currentspeed) {
+ currentspeed = othspeed;
+ }
+
+
+ msgsent += currentspeed * (now - this.lastUpdate);
+ this.lastUpdate = now;
+ }
+
+ /**
+ * returns the current speed of the connection
+ */
+ public double getSpeed() {
+ return this.currentspeed;
+ }
+
+ /**
+ * Returns the amount of bytes to be transferred before ongoing transfer
+ * is ready or 0 if there's no ongoing transfer or it has finished
+ * already
+ * @return the amount of bytes to be transferred
+ */
+ public int getRemainingByteCount() {
+ int bytesLeft = msgsize - msgsent;
+ return (bytesLeft > 0 ? bytesLeft : 0);
+ }
+
+ /**
+ * Returns true if the current message transfer is done.
+ * @return True if the transfer is done, false if not
+ */
+ public boolean isMessageTransferred() {
+ if (msgsent >= msgsize) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+}
diff --git a/core/World.java b/core/World.java
index ebdcdc381..c3c4dbcc4 100644
--- a/core/World.java
+++ b/core/World.java
@@ -1,9 +1,9 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package core;
-
+package core;
+
import input.EventQueue;
import input.ExternalEvent;
import input.ScheduledUpdatesQueue;
@@ -12,77 +12,77 @@
import java.util.Collections;
import java.util.List;
import java.util.Random;
-
-/**
- * World contains all the nodes and is responsible for updating their
- * location and connections.
- */
+
+/**
+ * World contains all the nodes and is responsible for updating their
+ * location and connections.
+ */
public class World {
/** name space of optimization settings ({@value})*/
public static final String OPTIMIZATION_SETTINGS_NS = "Optimization";
/**
- * Should the order of node updates be different (random) within every
- * update step -setting id ({@value}). Boolean (true/false) variable.
+ * Should the order of node updates be different (random) within every
+ * update step -setting id ({@value}). Boolean (true/false) variable.
* Default is @link {@link #DEF_RANDOMIZE_UPDATES}.
*/
public static final String RANDOMIZE_UPDATES_S = "randomizeUpdateOrder";
/** should the update order of nodes be randomized -setting's default value
* ({@value}) */
public static final boolean DEF_RANDOMIZE_UPDATES = true;
-
+
/**
- * Should the connectivity simulation be stopped after one round
- * -setting id ({@value}). Boolean (true/false) variable.
+ * Should the connectivity simulation be stopped after one round
+ * -setting id ({@value}). Boolean (true/false) variable.
*/
public static final String SIMULATE_CON_ONCE_S = "simulateConnectionsOnce";
- private int sizeX;
- private int sizeY;
- private List eventQueues;
- private double updateInterval;
- private SimClock simClock;
+ private int sizeX;
+ private int sizeY;
+ private List eventQueues;
+ private double updateInterval;
+ private SimClock simClock;
private double nextQueueEventTime;
private EventQueue nextEventQueue;
- /** list of nodes; nodes are indexed by their network address */
- private List hosts;
+ /** list of nodes; nodes are indexed by their network address */
+ private List hosts;
private boolean simulateConnections;
- /** nodes in the order they should be updated (if the order should be
+ /** nodes in the order they should be updated (if the order should be
* randomized; null value means that the order should not be randomized) */
- private ArrayList updateOrder;
+ private ArrayList updateOrder;
/** is cancellation of simulation requested from UI */
- private boolean isCancelled;
+ private boolean isCancelled;
private List updateListeners;
/** Queue of scheduled update requests */
private ScheduledUpdatesQueue scheduledUpdates;
private boolean simulateConOnce;
-
- /**
- * Constructor.
- */
- public World(List hosts, int sizeX, int sizeY,
+
+ /**
+ * Constructor.
+ */
+ public World(List hosts, int sizeX, int sizeY,
double updateInterval, List updateListeners,
boolean simulateConnections, List eventQueues) {
this.hosts = hosts;
this.sizeX = sizeX;
- this.sizeY = sizeY;
- this.updateInterval = updateInterval;
- this.updateListeners = updateListeners;
- this.simulateConnections = simulateConnections;
- this.eventQueues = eventQueues;
-
+ this.sizeY = sizeY;
+ this.updateInterval = updateInterval;
+ this.updateListeners = updateListeners;
+ this.simulateConnections = simulateConnections;
+ this.eventQueues = eventQueues;
+
this.simClock = SimClock.getInstance();
this.scheduledUpdates = new ScheduledUpdatesQueue();
this.isCancelled = false;
-
+
setNextEventQueue();
initSettings();
- }
+ }
- /**
- * Initializes settings fields that can be configured using Settings class
- */
- private void initSettings() {
+ /**
+ * Initializes settings fields that can be configured using Settings class
+ */
+ private void initSettings() {
Settings s = new Settings(OPTIMIZATION_SETTINGS_NS);
boolean randomizeUpdates = DEF_RANDOMIZE_UPDATES;
@@ -90,40 +90,40 @@ private void initSettings() {
randomizeUpdates = s.getBoolean(RANDOMIZE_UPDATES_S);
}
simulateConOnce = s.getBoolean(SIMULATE_CON_ONCE_S, false);
-
+
if(randomizeUpdates) {
// creates the update order array that can be shuffled
this.updateOrder = new ArrayList(this.hosts);
}
else { // null pointer means "don't randomize"
this.updateOrder = null;
- }
- }
-
- /**
- * Moves hosts in the world for the time given time initialize host
- * positions properly. SimClock must be set to -time
before
- * calling this method.
- * @param time The total time (seconds) to move
- */
- public void warmupMovementModel(double time) {
- if (time <= 0) {
- return;
- }
-
- while(SimClock.getTime() < -updateInterval) {
- moveHosts(updateInterval);
- simClock.advance(updateInterval);
- }
-
- double finalStep = -SimClock.getTime();
-
- moveHosts(finalStep);
- simClock.setTime(0);
- }
+ }
+ }
+
+ /**
+ * Moves hosts in the world for the time given time initialize host
+ * positions properly. SimClock must be set to -time
before
+ * calling this method.
+ * @param time The total time (seconds) to move
+ */
+ public void warmupMovementModel(double time) {
+ if (time <= 0) {
+ return;
+ }
+
+ while(SimClock.getTime() < -updateInterval) {
+ moveHosts(updateInterval);
+ simClock.advance(updateInterval);
+ }
+
+ double finalStep = -SimClock.getTime();
+
+ moveHosts(finalStep);
+ simClock.setTime(0);
+ }
/**
- * Goes through all event Queues and sets the
+ * Goes through all event Queues and sets the
* event queue that has the next event.
*/
public void setNextEventQueue() {
@@ -133,7 +133,7 @@ public void setNextEventQueue() {
/* find the queue that has the next event */
for (EventQueue eq : eventQueues) {
if (eq.nextEventsTime() < earliest){
- nextQueue = eq;
+ nextQueue = eq;
earliest = eq.nextEventsTime();
}
}
@@ -141,36 +141,36 @@ public void setNextEventQueue() {
this.nextEventQueue = nextQueue;
this.nextQueueEventTime = earliest;
}
-
- /**
- * Update (move, connect, disconnect etc.) all hosts in the world.
+
+ /**
+ * Update (move, connect, disconnect etc.) all hosts in the world.
* Runs all external events that are due between the time when
- * this method is called and after one update interval.
- */
- public void update () {
- double runUntil = SimClock.getTime() + this.updateInterval;
+ * this method is called and after one update interval.
+ */
+ public void update () {
+ double runUntil = SimClock.getTime() + this.updateInterval;
setNextEventQueue();
-
+
/* process all events that are due until next interval update */
while (this.nextQueueEventTime <= runUntil) {
simClock.setTime(this.nextQueueEventTime);
- ExternalEvent ee = this.nextEventQueue.nextEvent();
+ ExternalEvent ee = this.nextEventQueue.nextEvent();
ee.processEvent(this);
updateHosts(); // update all hosts after every event
- setNextEventQueue();
- }
+ setNextEventQueue();
+ }
- moveHosts(this.updateInterval);
+ moveHosts(this.updateInterval);
simClock.setTime(runUntil);
updateHosts();
-
- /* inform all update listeners */
- for (UpdateListener ul : this.updateListeners) {
- ul.updated(this.hosts);
- }
- }
+
+ /* inform all update listeners */
+ for (UpdateListener ul : this.updateListeners) {
+ ul.updated(this.hosts);
+ }
+ }
/**
* Updates all hosts (calls update for every one of them). If update
@@ -187,89 +187,89 @@ private void updateHosts() {
}
}
else { // update order randomizing is on
- assert this.updateOrder.size() == this.hosts.size() :
+ assert this.updateOrder.size() == this.hosts.size() :
"Nrof hosts has changed unexpectedly";
Random rng = new Random(SimClock.getIntTime());
- Collections.shuffle(this.updateOrder, rng);
+ Collections.shuffle(this.updateOrder, rng);
for (int i=0, n = hosts.size();i < n; i++) {
if (this.isCancelled) {
break;
}
this.updateOrder.get(i).update(simulateConnections);
- }
+ }
}
-
+
if (simulateConOnce && simulateConnections) {
simulateConnections = false;
}
}
-
- /**
- * Moves all hosts in the world for a given amount of time
- * @param timeIncrement The time how long all nodes should move
- */
- private void moveHosts(double timeIncrement) {
- for (int i=0,n = hosts.size(); i getHosts() {
- return this.hosts;
- }
-
- /**
- * Returns the x-size (width) of the world
- * @return the x-size (width) of the world
- */
- public int getSizeX() {
- return this.sizeX;
- }
-
- /**
- * Returns the y-size (height) of the world
- * @return the y-size (height) of the world
- */
- public int getSizeY() {
- return this.sizeY;
- }
-
- /**
- * Returns a node from the world by its address
- * @param address The address of the node
- * @return The requested node or null if it wasn't found
- */
- public DTNHost getNodeByAddress(int address) {
- if (address < 0 || address >= hosts.size()) {
- throw new SimError("No host for address " + address + ". Address " +
- "range of 0-" + (hosts.size()-1) + " is valid");
- }
-
- DTNHost node = this.hosts.get(address);
- assert node.getAddress() == address : "Node indexing failed. " +
- "Node " + node + " in index " + address;
-
- return node;
- }
/**
- * Schedules an update request to all nodes to happen at the specified
+ * Moves all hosts in the world for a given amount of time
+ * @param timeIncrement The time how long all nodes should move
+ */
+ private void moveHosts(double timeIncrement) {
+ for (int i=0,n = hosts.size(); i getHosts() {
+ return this.hosts;
+ }
+
+ /**
+ * Returns the x-size (width) of the world
+ * @return the x-size (width) of the world
+ */
+ public int getSizeX() {
+ return this.sizeX;
+ }
+
+ /**
+ * Returns the y-size (height) of the world
+ * @return the y-size (height) of the world
+ */
+ public int getSizeY() {
+ return this.sizeY;
+ }
+
+ /**
+ * Returns a node from the world by its address
+ * @param address The address of the node
+ * @return The requested node or null if it wasn't found
+ */
+ public DTNHost getNodeByAddress(int address) {
+ if (address < 0 || address >= hosts.size()) {
+ throw new SimError("No host for address " + address + ". Address " +
+ "range of 0-" + (hosts.size()-1) + " is valid");
+ }
+
+ DTNHost node = this.hosts.get(address);
+ assert node.getAddress() == address : "Node indexing failed. " +
+ "Node " + node + " in index " + address;
+
+ return node;
+ }
+
+ /**
+ * Schedules an update request to all nodes to happen at the specified
* simulation time.
* @param simTime The time of the update
*/
public void scheduleUpdate(double simTime) {
scheduledUpdates.addUpdate(simTime);
- }
-}
+ }
+}
diff --git a/core/package.html b/core/package.html
index 81ea38f32..56ab9f991 100644
--- a/core/package.html
+++ b/core/package.html
@@ -1,14 +1,14 @@
-
-
-
-
-Contains core classes and interfaces of the simulator.
-
-Almost all of these classes are needed for every run of the simulator.
-DTNSim is the main class of the program. It starts up a proper user interface
-which in turn starts the simulation.
-
-@see ui.DTNSimUI
-
-
-
\ No newline at end of file
+
+
+
+
+Contains core classes and interfaces of the simulator.
+
+Almost all of these classes are needed for every run of the simulator.
+DTNSim is the main class of the program. It starts up a proper user interface
+which in turn starts the simulation.
+
+@see ui.DTNSimUI
+
+
+
diff --git a/data/CentralPOIs.wkt b/data/CentralPOIs.wkt
index 5167d943e..2519079f4 100644
--- a/data/CentralPOIs.wkt
+++ b/data/CentralPOIs.wkt
@@ -4,4 +4,4 @@ POINT (2552275.9398973365 6673509.820852942)
POINT (2552361.289603607 6673630.088457832)
-POINT (2552782.3212060533 6673285.5993876355)
\ No newline at end of file
+POINT (2552782.3212060533 6673285.5993876355)
diff --git a/data/HelsinkiMedium/A_bus.wkt b/data/HelsinkiMedium/A_bus.wkt
index ff8a92e55..d7c4fed7d 100644
--- a/data/HelsinkiMedium/A_bus.wkt
+++ b/data/HelsinkiMedium/A_bus.wkt
@@ -1,2 +1,2 @@
-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,
- 2552253.088680792 6672172.793966631)
\ No newline at end of file
+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,
+ 2552253.088680792 6672172.793966631)
diff --git a/data/HelsinkiMedium/A_homes.wkt b/data/HelsinkiMedium/A_homes.wkt
index e1789ca07..76953a5ab 100644
--- a/data/HelsinkiMedium/A_homes.wkt
+++ b/data/HelsinkiMedium/A_homes.wkt
@@ -280,4 +280,4 @@ POINT (2552850.64386866 6672373.590055137)
POINT (2552608.387975143 6671893.399837605)
-POINT (2553619.970908834 6672194.188877382)
\ No newline at end of file
+POINT (2553619.970908834 6672194.188877382)
diff --git a/data/HelsinkiMedium/A_meetingspots.wkt b/data/HelsinkiMedium/A_meetingspots.wkt
index a49b45d41..69d776a95 100644
--- a/data/HelsinkiMedium/A_meetingspots.wkt
+++ b/data/HelsinkiMedium/A_meetingspots.wkt
@@ -4,4 +4,4 @@ POINT (2552398.0412894213 6673352.814815518)
POINT (2552271.1386670014 6673506.220026447)
-POINT (2552747.310172474 6672343.373119477)
\ No newline at end of file
+POINT (2552747.310172474 6672343.373119477)
diff --git a/data/HelsinkiMedium/A_offices.wkt b/data/HelsinkiMedium/A_offices.wkt
index 0a8d77521..b7c77db94 100644
--- a/data/HelsinkiMedium/A_offices.wkt
+++ b/data/HelsinkiMedium/A_offices.wkt
@@ -56,4 +56,4 @@ POINT (2552250.077599912 6673094.855606426)
POINT (2552478.6805102592 6673256.062608091)
-POINT (2552844.266976823 6672450.797776541)
\ No newline at end of file
+POINT (2552844.266976823 6672450.797776541)
diff --git a/data/HelsinkiMedium/B_bus.wkt b/data/HelsinkiMedium/B_bus.wkt
index d4b4091a4..2801c672b 100644
--- a/data/HelsinkiMedium/B_bus.wkt
+++ b/data/HelsinkiMedium/B_bus.wkt
@@ -1,2 +1,2 @@
-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,
- 2548409.3490672903 6672539.118048595, 2548204.9172993526 6672577.186786471, 2547920.50627351 6672635.070072358, 2547945.8323510517 6672417.580152135, 2548008.8175634407 6672181.105874455, 2547895.0977006014 6671978.22930842)
\ No newline at end of file
+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,
+ 2548409.3490672903 6672539.118048595, 2548204.9172993526 6672577.186786471, 2547920.50627351 6672635.070072358, 2547945.8323510517 6672417.580152135, 2548008.8175634407 6672181.105874455, 2547895.0977006014 6671978.22930842)
diff --git a/data/HelsinkiMedium/B_homes.wkt b/data/HelsinkiMedium/B_homes.wkt
index 8ef6dc479..47d67c13d 100644
--- a/data/HelsinkiMedium/B_homes.wkt
+++ b/data/HelsinkiMedium/B_homes.wkt
@@ -238,4 +238,4 @@ POINT (2548841.591790056 6671231.327872955)
POINT (2548324.791316539 6672456.579103522)
-POINT (2548615.777223099 6672593.840609004)
\ No newline at end of file
+POINT (2548615.777223099 6672593.840609004)
diff --git a/data/HelsinkiMedium/B_meetingspots.wkt b/data/HelsinkiMedium/B_meetingspots.wkt
index c5fe0ca7b..9a7f978e7 100644
--- a/data/HelsinkiMedium/B_meetingspots.wkt
+++ b/data/HelsinkiMedium/B_meetingspots.wkt
@@ -1 +1 @@
-POINT (2548669.62194887 6672165.182219516)
\ No newline at end of file
+POINT (2548669.62194887 6672165.182219516)
diff --git a/data/HelsinkiMedium/B_offices.wkt b/data/HelsinkiMedium/B_offices.wkt
index 1c6e61331..43f15b1c5 100644
--- a/data/HelsinkiMedium/B_offices.wkt
+++ b/data/HelsinkiMedium/B_offices.wkt
@@ -16,4 +16,4 @@ POINT (2549125.4665960157 6671310.466037451)
POINT (2548899.0168147366 6671469.6525753625)
-POINT (2549038.92070693 6671689.052934085)
\ No newline at end of file
+POINT (2549038.92070693 6671689.052934085)
diff --git a/data/HelsinkiMedium/C_bus.wkt b/data/HelsinkiMedium/C_bus.wkt
index c6102e8c2..d8064d00b 100644
--- a/data/HelsinkiMedium/C_bus.wkt
+++ b/data/HelsinkiMedium/C_bus.wkt
@@ -1,2 +1,2 @@
-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,
- 2548569.3983280044 6677113.988113486)
\ No newline at end of file
+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,
+ 2548569.3983280044 6677113.988113486)
diff --git a/data/HelsinkiMedium/C_homes.wkt b/data/HelsinkiMedium/C_homes.wkt
index 0ceca8213..6a3a60a8f 100644
--- a/data/HelsinkiMedium/C_homes.wkt
+++ b/data/HelsinkiMedium/C_homes.wkt
@@ -186,4 +186,4 @@ POINT (2551657.6371247726 6675606.672140909)
POINT (2550018.5036879224 6675800.976739431)
-POINT (2549939.365882756 6675948.670639449)
\ No newline at end of file
+POINT (2549939.365882756 6675948.670639449)
diff --git a/data/HelsinkiMedium/C_meetingspots.wkt b/data/HelsinkiMedium/C_meetingspots.wkt
index 3c3cec952..e902d6336 100644
--- a/data/HelsinkiMedium/C_meetingspots.wkt
+++ b/data/HelsinkiMedium/C_meetingspots.wkt
@@ -1,3 +1,3 @@
POINT (2551019.4859670075 6675223.744247892)
-POINT (2551776.083972117 6676132.332795221)
\ No newline at end of file
+POINT (2551776.083972117 6676132.332795221)
diff --git a/data/HelsinkiMedium/C_offices.wkt b/data/HelsinkiMedium/C_offices.wkt
index 5c42fe405..9cbc004a4 100644
--- a/data/HelsinkiMedium/C_offices.wkt
+++ b/data/HelsinkiMedium/C_offices.wkt
@@ -36,4 +36,4 @@ POINT (2550826.0508314357 6675180.984433278)
POINT (2550853.835270902 6674980.93851696)
-POINT (2550585.040617954 6675171.722307353)
\ No newline at end of file
+POINT (2550585.040617954 6675171.722307353)
diff --git a/data/HelsinkiMedium/D_bus.wkt b/data/HelsinkiMedium/D_bus.wkt
index 91da8b1ae..cd4c3d475 100644
--- a/data/HelsinkiMedium/D_bus.wkt
+++ b/data/HelsinkiMedium/D_bus.wkt
@@ -1 +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)
\ No newline at end of file
+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)
diff --git a/data/HelsinkiMedium/D_homes.wkt b/data/HelsinkiMedium/D_homes.wkt
index 29285b3d7..5914b6df3 100644
--- a/data/HelsinkiMedium/D_homes.wkt
+++ b/data/HelsinkiMedium/D_homes.wkt
@@ -242,4 +242,4 @@ POINT (2552211.8574965727 6677157.938201302)
POINT (2552070.9719095165 6676855.328743686)
-POINT (2551526.3952460703 6675568.953483388)
\ No newline at end of file
+POINT (2551526.3952460703 6675568.953483388)
diff --git a/data/HelsinkiMedium/D_meetingspots.wkt b/data/HelsinkiMedium/D_meetingspots.wkt
index 8c2c40054..93721c1e9 100644
--- a/data/HelsinkiMedium/D_meetingspots.wkt
+++ b/data/HelsinkiMedium/D_meetingspots.wkt
@@ -1,3 +1,3 @@
POINT (2553423.037969719 6674726.15003564)
-POINT (2551506.1838812567 6676962.873428298)
\ No newline at end of file
+POINT (2551506.1838812567 6676962.873428298)
diff --git a/data/HelsinkiMedium/D_offices.wkt b/data/HelsinkiMedium/D_offices.wkt
index 17e0dc2d1..a8c35ce9f 100644
--- a/data/HelsinkiMedium/D_offices.wkt
+++ b/data/HelsinkiMedium/D_offices.wkt
@@ -36,4 +36,4 @@ POINT (2553890.89394224 6675364.116467373)
POINT (2554326.5684722555 6675869.682509391)
-POINT (2553932.7438417096 6677359.32442526)
\ No newline at end of file
+POINT (2553932.7438417096 6677359.32442526)
diff --git a/data/HelsinkiMedium/E_bus.wkt b/data/HelsinkiMedium/E_bus.wkt
index fcc880ca1..027b5a658 100644
--- a/data/HelsinkiMedium/E_bus.wkt
+++ b/data/HelsinkiMedium/E_bus.wkt
@@ -1,2 +1,2 @@
-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,
- 2552256.454491749 6673534.296470803, 2552719.2287496882 6673650.273090789, 2553233.3316247175 6673542.7184038805)
\ No newline at end of file
+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,
+ 2552256.454491749 6673534.296470803, 2552719.2287496882 6673650.273090789, 2553233.3316247175 6673542.7184038805)
diff --git a/data/HelsinkiMedium/E_homes.wkt b/data/HelsinkiMedium/E_homes.wkt
index e9c327f85..ad0dd108c 100644
--- a/data/HelsinkiMedium/E_homes.wkt
+++ b/data/HelsinkiMedium/E_homes.wkt
@@ -180,4 +180,4 @@ POINT (2552089.277631362 6672241.849816945)
POINT (2552615.251589643 6672065.289291202)
-POINT (2552879.3357571587 6673419.2100551445)
\ No newline at end of file
+POINT (2552879.3357571587 6673419.2100551445)
diff --git a/data/HelsinkiMedium/E_meetingspots.wkt b/data/HelsinkiMedium/E_meetingspots.wkt
index 82d0bf105..7bcf94063 100644
--- a/data/HelsinkiMedium/E_meetingspots.wkt
+++ b/data/HelsinkiMedium/E_meetingspots.wkt
@@ -1,3 +1,3 @@
POINT (2552080.145394281 6673330.999808344)
-POINT (2552531.1145652616 6673268.445450311)
\ No newline at end of file
+POINT (2552531.1145652616 6673268.445450311)
diff --git a/data/HelsinkiMedium/E_offices.wkt b/data/HelsinkiMedium/E_offices.wkt
index 85ac6c45d..92480d88c 100644
--- a/data/HelsinkiMedium/E_offices.wkt
+++ b/data/HelsinkiMedium/E_offices.wkt
@@ -40,4 +40,4 @@ POINT (2551923.44544545 6672987.520970024)
POINT (2551768.7088863445 6672875.395233927)
-POINT (2552330.7745675067 6672982.3197762)
\ No newline at end of file
+POINT (2552330.7745675067 6672982.3197762)
diff --git a/data/HelsinkiMedium/F_bus.wkt b/data/HelsinkiMedium/F_bus.wkt
index b4d5e6796..42aae1cf9 100644
--- a/data/HelsinkiMedium/F_bus.wkt
+++ b/data/HelsinkiMedium/F_bus.wkt
@@ -1,2 +1,2 @@
-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,
- 2551083.634364065 6675615.144085466, 2550671.0337880836 6675975.426780757, 2550010.88111605 6676239.047289281, 2549500.1028042943 6676330.738335026, 2548940.256248493 6676559.490840337)
\ No newline at end of file
+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,
+ 2551083.634364065 6675615.144085466, 2550671.0337880836 6675975.426780757, 2550010.88111605 6676239.047289281, 2549500.1028042943 6676330.738335026, 2548940.256248493 6676559.490840337)
diff --git a/data/HelsinkiMedium/F_homes.wkt b/data/HelsinkiMedium/F_homes.wkt
index 2711e7c96..9bab8569f 100644
--- a/data/HelsinkiMedium/F_homes.wkt
+++ b/data/HelsinkiMedium/F_homes.wkt
@@ -178,4 +178,4 @@ POINT (2548140.6864069286 6676740.502387718)
POINT (2548118.3136635106 6677359.964572192)
-POINT (2548761.0020664376 6677528.1531763375)
\ No newline at end of file
+POINT (2548761.0020664376 6677528.1531763375)
diff --git a/data/HelsinkiMedium/F_meetingspots.wkt b/data/HelsinkiMedium/F_meetingspots.wkt
index 9d271a7dd..5d7fe6990 100644
--- a/data/HelsinkiMedium/F_meetingspots.wkt
+++ b/data/HelsinkiMedium/F_meetingspots.wkt
@@ -4,4 +4,4 @@ POINT (2552669.1210640236 6673406.247079767)
POINT (2550808.454569743 6675266.964168113)
-POINT (2550105.5033015246 6676255.961171506)
\ No newline at end of file
+POINT (2550105.5033015246 6676255.961171506)
diff --git a/data/HelsinkiMedium/F_offices.wkt b/data/HelsinkiMedium/F_offices.wkt
index ecf8ffb4f..9905454f9 100644
--- a/data/HelsinkiMedium/F_offices.wkt
+++ b/data/HelsinkiMedium/F_offices.wkt
@@ -56,4 +56,4 @@ POINT (2553381.666543376 6673728.240986674)
POINT (2553263.7229177677 6673904.271390739)
-POINT (2553841.6277093147 6673119.391238062)
\ No newline at end of file
+POINT (2553841.6277093147 6673119.391238062)
diff --git a/data/HelsinkiMedium/G_bus.wkt b/data/HelsinkiMedium/G_bus.wkt
index 8a66b5fe7..6031c6b2d 100644
--- a/data/HelsinkiMedium/G_bus.wkt
+++ b/data/HelsinkiMedium/G_bus.wkt
@@ -1,2 +1,2 @@
-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,
- 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)
\ No newline at end of file
+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,
+ 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)
diff --git a/data/HelsinkiMedium/G_homes.wkt b/data/HelsinkiMedium/G_homes.wkt
index cc4f87e1d..cd4dc3dc3 100644
--- a/data/HelsinkiMedium/G_homes.wkt
+++ b/data/HelsinkiMedium/G_homes.wkt
@@ -262,4 +262,4 @@ POINT (2551551.655327319 6676622.915398106)
POINT (2551366.758462189 6676642.349858876)
-POINT (2552220.610254967 6677124.070427668)
\ No newline at end of file
+POINT (2552220.610254967 6677124.070427668)
diff --git a/data/HelsinkiMedium/G_meetingspots.wkt b/data/HelsinkiMedium/G_meetingspots.wkt
index 49ca52af1..d9dbf5086 100644
--- a/data/HelsinkiMedium/G_meetingspots.wkt
+++ b/data/HelsinkiMedium/G_meetingspots.wkt
@@ -4,4 +4,4 @@ POINT (2552122.746001586 6673002.154328803)
POINT (2552677.906820565 6673285.539373861)
-POINT (2552459.211603745 6673074.480929848)
\ No newline at end of file
+POINT (2552459.211603745 6673074.480929848)
diff --git a/data/HelsinkiMedium/G_offices.wkt b/data/HelsinkiMedium/G_offices.wkt
index b86aa7afe..bba807234 100644
--- a/data/HelsinkiMedium/G_offices.wkt
+++ b/data/HelsinkiMedium/G_offices.wkt
@@ -56,4 +56,4 @@ POINT (2551364.993061344 6672039.063271573)
POINT (2550978.2795313974 6672002.13479542)
-POINT (2551001.279239602 6672187.047238169)
\ No newline at end of file
+POINT (2551001.279239602 6672187.047238169)
diff --git a/data/HelsinkiMedium/H_bus.wkt b/data/HelsinkiMedium/H_bus.wkt
index 8f99f4b07..ea5198cf3 100644
--- a/data/HelsinkiMedium/H_bus.wkt
+++ b/data/HelsinkiMedium/H_bus.wkt
@@ -1,2 +1,2 @@
-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,
- 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)
\ No newline at end of file
+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,
+ 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)
diff --git a/data/HelsinkiMedium/roads.wkt b/data/HelsinkiMedium/roads.wkt
index 445026b37..e089d2909 100644
--- a/data/HelsinkiMedium/roads.wkt
+++ b/data/HelsinkiMedium/roads.wkt
@@ -120,7 +120,7 @@ LINESTRING (2552808.4227400413 6675372.088297138, 2552796.3371688365 6675371.648
LINESTRING (2553144.0138913146 6676147.986388173, 2553156.487190742 6676159.188959487)
-LINESTRING (2547988.259718087 6672227.376494899, 2547998.5468903002 6672231.24738338, 2548040.3060448663 6672264.735069772, 2548094.447753957 6672319.50764166, 2548124.368823418 6672366.038321796, 2548133.5258091087 6672398.905865847, 2548132.453369343 6672426.1721242415, 2548125.5815053065 6672450.737762765, 2548112.4894906296 6672473.472981155, 2548083.162387808 6672500.249127055,
+LINESTRING (2547988.259718087 6672227.376494899, 2547998.5468903002 6672231.24738338, 2548040.3060448663 6672264.735069772, 2548094.447753957 6672319.50764166, 2548124.368823418 6672366.038321796, 2548133.5258091087 6672398.905865847, 2548132.453369343 6672426.1721242415, 2548125.5815053065 6672450.737762765, 2548112.4894906296 6672473.472981155, 2548083.162387808 6672500.249127055,
2548058.529271345 6672511.001595057, 2548002.440671603 6672518.123229678, 2547927.510130133 6672506.360529798)
LINESTRING (2552817.3899863893 6675825.142286122, 2552672.198141197 6675830.973624582)
@@ -249,7 +249,7 @@ LINESTRING (2551445.1950567393 6673509.880866717, 2551290.1450152406 6673526.754
LINESTRING (2548787.3180883788 6676110.747840851, 2548815.193272748 6676123.740823115, 2548851.441736826 6676140.604693861, 2548909.716463783 6676167.730920114)
-LINESTRING (2553505.937563602 6677026.928130704, 2553513.782872964 6677018.266142528, 2553515.969000179 6677009.334092364, 2553513.626131768 6676989.269486957, 2553510.895535134 6676969.885037665, 2553512.0257216557 6676942.078655297, 2553514.7893164367 6676936.40735357, 2553530.3231939645 6676923.54440115, 2553543.2667169822 6676917.793081056, 2553584.448403982 6676899.478877417,
+LINESTRING (2553505.937563602 6677026.928130704, 2553513.782872964 6677018.266142528, 2553515.969000179 6677009.334092364, 2553513.626131768 6676989.269486957, 2553510.895535134 6676969.885037665, 2553512.0257216557 6676942.078655297, 2553514.7893164367 6676936.40735357, 2553530.3231939645 6676923.54440115, 2553543.2667169822 6676917.793081056, 2553584.448403982 6676899.478877417,
2553587.4264867157 6676880.294474042)
LINESTRING (2552859.4626233485 6674782.643002409, 2552835.0769929853 6674799.846951212, 2552698.3739210153 6674904.100880502)
@@ -574,7 +574,7 @@ LINESTRING (2551849.810081235 6674219.603768633, 2551844.6623703605 6674216.3330
LINESTRING (2553505.937563602 6677026.928130704, 2553467.412227406 6677039.220952262, 2553418.81420695 6677066.027105048)
-LINESTRING (2551010.510471123 6674129.593108585, 2551015.4271949716 6674107.267984324, 2551014.2392616924 6674078.951484869, 2551005.090525538 6674055.06600246, 2550970.731205355 6674013.506463345, 2550957.655689751 6673913.943610793, 2550959.4458392058 6673875.394762719, 2550972.37286315 6673819.982043899, 2550981.414355328 6673794.056093143, 2551025.4503820115 6673705.495765989,
+LINESTRING (2551010.510471123 6674129.593108585, 2551015.4271949716 6674107.267984324, 2551014.2392616924 6674078.951484869, 2551005.090525538 6674055.06600246, 2550970.731205355 6674013.506463345, 2550957.655689751 6673913.943610793, 2550959.4458392058 6673875.394762719, 2550972.37286315 6673819.982043899, 2550981.414355328 6673794.056093143, 2551025.4503820115 6673705.495765989,
2551039.1363633284 6673648.872769374)
LINESTRING (2547785.263369528 6677662.604036695, 2547626.23705136 6677528.873341636, 2547565.3719698926 6677523.182035317)
@@ -617,7 +617,7 @@ LINESTRING (2550574.0522351246 6672733.982775682, 2550466.775260416 6672725.7608
LINESTRING (2549342.239670795 6671574.806711275, 2549323.9009508025 6671664.947401169)
-LINESTRING (2550933.6990352944 6673730.841583586, 2550952.3512376794 6673762.378822294, 2550956.591499522 6673790.235216142, 2550954.025893621 6673808.149327948, 2550946.8735453384 6673823.68289335, 2550935.695423166 6673836.845914644, 2550919.9223090746 6673848.198520395, 2550889.720755367 6673857.050552192, 2550856.8546013194 6673849.638850993, 2550839.654317386 6673838.396270496,
+LINESTRING (2550933.6990352944 6673730.841583586, 2550952.3512376794 6673762.378822294, 2550956.591499522 6673790.235216142, 2550954.025893621 6673808.149327948, 2550946.8735453384 6673823.68289335, 2550935.695423166 6673836.845914644, 2550919.9223090746 6673848.198520395, 2550889.720755367 6673857.050552192, 2550856.8546013194 6673849.638850993, 2550839.654317386 6673838.396270496,
2550818.6674961266 6673809.159559825, 2550817.034087868 6673801.027693327)
LINESTRING (2547493.01528386 6677618.133829498, 2547492.503812587 6677591.537724922, 2547506.0907994634 6677552.968872257, 2547534.6341963024 6677531.023835236, 2547565.3719698926 6677523.182035317)
@@ -648,7 +648,7 @@ LINESTRING (2552243.915196028 6677050.3635098, 2552237.761041681 6677048.7931493
LINESTRING (2552110.0169665217 6675223.784257075, 2552115.544156083 6675204.8399088, 2552129.799355429 6675149.907300179, 2552131.2677729544 6675131.773137865, 2552123.7689441317 6675083.262003157, 2552115.6266514496 6675038.991841876, 2552121.393077574 6674982.378847557, 2552141.422952581 6674921.104783389, 2552161.4693266614 6674891.928086493, 2552177.8116587824 6674881.545703436)
-LINESTRING (2549102.912362791 6676997.70142233, 2549086.5535315974 6676993.160380029, 2549076.84382695 6676995.090823121, 2548934.143341829 6677096.614125654, 2548918.2299856143 6677103.31566385, 2548899.899515159 6677105.536173522, 2548817.9156198455 6677099.934887865, 2548806.64675277 6677095.843948876, 2548804.7906070217 6677084.011232926, 2548812.825655727 6677068.397649157,
+LINESTRING (2549102.912362791 6676997.70142233, 2549086.5535315974 6676993.160380029, 2549076.84382695 6676995.090823121, 2548934.143341829 6677096.614125654, 2548918.2299856143 6677103.31566385, 2548899.899515159 6677105.536173522, 2548817.9156198455 6677099.934887865, 2548806.64675277 6677095.843948876, 2548804.7906070217 6677084.011232926, 2548812.825655727 6677068.397649157,
2548816.042975024 6677024.077476396)
LINESTRING (2549209.8346074237 6675962.77387655, 2549169.8903509225 6676020.817199169, 2549159.636176856 6676030.589442181)
@@ -753,7 +753,7 @@ LINESTRING (2552665.84599797 6672078.382296425, 2552615.251589643 6672065.289291
LINESTRING (2553369.1437467285 6674168.962144917, 2553366.421399631 6674205.580549899)
-LINESTRING (2552118.0437656906 6673737.923209025, 2552177.8364073923 6673801.157723173, 2552199.0789642883 6673818.001589327, 2552221.748691026 6673826.953644082, 2552240.5658841445 6673806.108859601, 2552297.924912532 6673716.958396994, 2552318.0207838323 6673714.7078804355, 2552341.8371961657 6673705.855848638, 2552354.4919854 6673692.762843415, 2552359.6396962753 6673678.47956499,
+LINESTRING (2552118.0437656906 6673737.923209025, 2552177.8364073923 6673801.157723173, 2552199.0789642883 6673818.001589327, 2552221.748691026 6673826.953644082, 2552240.5658841445 6673806.108859601, 2552297.924912532 6673716.958396994, 2552318.0207838323 6673714.7078804355, 2552341.8371961657 6673705.855848638, 2552354.4919854 6673692.762843415, 2552359.6396962753 6673678.47956499,
2552359.0127314893 6673658.444966471)
LINESTRING (2552558.552524188 6676065.787521157, 2552502.199939273 6676110.617811005)
@@ -800,10 +800,10 @@ LINESTRING (2554142.290322375 6674448.276255577, 2554189.4694225257 6674406.6467
LINESTRING (2553224.2818830027 6677495.7457378935, 2553192.3231779872 6677528.62328424, 2553250.2101767207 6677586.04646452)
-LINESTRING (2548102.3838082226 6676803.586867429, 2548035.6450566542 6676890.086721646, 2548013.2558141625 6676917.543023661, 2548002.613911873 6676926.014968216, 2547947.927733363 6676937.697649729, 2547879.547324 6676971.225345305, 2547841.0632354873 6676976.256500101, 2547817.79954211 6676989.749597156, 2547808.3373235622 6677001.832370502, 2547758.4853735343 6677106.116306678,
+LINESTRING (2548102.3838082226 6676803.586867429, 2548035.6450566542 6676890.086721646, 2548013.2558141625 6676917.543023661, 2548002.613911873 6676926.014968216, 2547947.927733363 6676937.697649729, 2547879.547324 6676971.225345305, 2547841.0632354873 6676976.256500101, 2547817.79954211 6676989.749597156, 2547808.3373235622 6677001.832370502, 2547758.4853735343 6677106.116306678,
2547743.512464499 6677123.490294511, 2547626.9547610492 6677181.243550552, 2547611.5776247173 6677186.774820139, 2547570.989904357 6677188.935316035)
-LINESTRING (2551150.8268401497 6677498.466362355, 2551069.0574327894 6677537.415302263, 2550922.133184899 6677611.7023532875, 2550907.853236943 6677625.3754916685, 2550898.514761445 6677640.66900197, 2550893.301054277 6677658.333056382, 2550893.103065397 6677671.966185579, 2550896.155393961 6677691.5306761945, 2550903.3819880737 6677707.824416079, 2550950.742578031 6677759.3762487145,
+LINESTRING (2551150.8268401497 6677498.466362355, 2551069.0574327894 6677537.415302263, 2550922.133184899 6677611.7023532875, 2550907.853236943 6677625.3754916685, 2550898.514761445 6677640.66900197, 2550893.301054277 6677658.333056382, 2550893.103065397 6677671.966185579, 2550896.155393961 6677691.5306761945, 2550903.3819880737 6677707.824416079, 2550950.742578031 6677759.3762487145,
2550958.6786322966 6677784.922112228, 2550960.6090238746 6677807.277243377, 2550962.2424321333 6677826.231593948)
LINESTRING (2552952.212164001 6673697.553943111, 2552938.220949828 6673883.426606258)
@@ -940,10 +940,10 @@ LINESTRING (2551902.1451417976 6673644.191694933, 2551743.440555559 6673647.4224
LINESTRING (2550848.6793104904 6672658.8755364, 2550854.3137440286 6672591.750129179, 2550611.983604681 6672531.376271633)
-LINESTRING (2552559.517719977 6673146.45745054, 2552473.318311431 6673253.912114491, 2552440.104393391 6673297.548247428, 2552408.7574375407 6673338.7315830095, 2552398.0412894213 6673352.814815518, 2552387.0611561285 6673365.997841404, 2552275.9398973365 6673509.820852942, 2552256.454491749 6673534.296470803, 2552195.9111422114 6673612.1843483215, 2552172.432960881 6673639.590638857,
- 2552153.657015446 6673654.484057328, 2552149.2847610167 6673657.954853976, 2552146.0756912567 6673660.495437113, 2552144.1535492153 6673662.015786077, 2552140.721741965 6673665.156506963, 2552137.4466759115 6673668.147193412, 2552124.4206575276 6673683.880804731, 2552092.0164775327 6673747.715456628, 2552068.1670670523 6673793.766026565, 2552022.431635817 6673885.937182508,
- 2551970.2203183044 6673991.151332197, 2551943.3598269443 6674056.316289438, 2551910.081196063 6674119.950895418, 2551906.723634643 6674125.11208006, 2551861.5739205102 6674198.388899207, 2551849.810081235 6674219.603768633, 2551800.86558024 6674295.731242088, 2551770.499035799 6674351.273990754, 2551761.5729668215 6674388.38925647, 2551760.913074202 6674391.1331395805,
- 2551737.2616526014 6674473.952148937, 2551726.108279039 6674513.03111869, 2551681.816516719 6674680.479552944, 2551677.856739123 6674695.442987485, 2551640.0986098363 6674817.1909321565, 2551637.1205271026 6674824.482605807, 2551634.975647571 6674829.743813406, 2551583.8285202878 6674895.818979566, 2551512.1730448706 6674985.079467428, 2551501.1186657483 6674998.4825438205,
+LINESTRING (2552559.517719977 6673146.45745054, 2552473.318311431 6673253.912114491, 2552440.104393391 6673297.548247428, 2552408.7574375407 6673338.7315830095, 2552398.0412894213 6673352.814815518, 2552387.0611561285 6673365.997841404, 2552275.9398973365 6673509.820852942, 2552256.454491749 6673534.296470803, 2552195.9111422114 6673612.1843483215, 2552172.432960881 6673639.590638857,
+ 2552153.657015446 6673654.484057328, 2552149.2847610167 6673657.954853976, 2552146.0756912567 6673660.495437113, 2552144.1535492153 6673662.015786077, 2552140.721741965 6673665.156506963, 2552137.4466759115 6673668.147193412, 2552124.4206575276 6673683.880804731, 2552092.0164775327 6673747.715456628, 2552068.1670670523 6673793.766026565, 2552022.431635817 6673885.937182508,
+ 2551970.2203183044 6673991.151332197, 2551943.3598269443 6674056.316289438, 2551910.081196063 6674119.950895418, 2551906.723634643 6674125.11208006, 2551861.5739205102 6674198.388899207, 2551849.810081235 6674219.603768633, 2551800.86558024 6674295.731242088, 2551770.499035799 6674351.273990754, 2551761.5729668215 6674388.38925647, 2551760.913074202 6674391.1331395805,
+ 2551737.2616526014 6674473.952148937, 2551726.108279039 6674513.03111869, 2551681.816516719 6674680.479552944, 2551677.856739123 6674695.442987485, 2551640.0986098363 6674817.1909321565, 2551637.1205271026 6674824.482605807, 2551634.975647571 6674829.743813406, 2551583.8285202878 6674895.818979566, 2551512.1730448706 6674985.079467428, 2551501.1186657483 6674998.4825438205,
2551447.7276644935 6675063.277416117, 2551330.3532569148 6675214.352092121, 2551307.84852091 6675247.109610918, 2551200.670540641 6675403.125421056, 2551140.25918369 6675519.112043337)
LINESTRING (2553320.273491563 6674457.528379207, 2553336.030106581 6674451.717045338, 2553487.0213760436 6674460.4490495855, 2553489.306497698 6674471.071487742)
@@ -1038,7 +1038,7 @@ LINESTRING (2551229.33768053 6672340.972568481, 2551228.2487416905 6672315.82679
LINESTRING (2553126.3186351815 6676295.190175696, 2553165.0089621106 6676347.372152968)
-LINESTRING (2551458.9717829595 6675914.192725771, 2551704.9729661196 6676045.46285606, 2551713.659728221 6676052.784536597, 2551715.8293563626 6676064.487222701, 2551694.933280006 6676090.3431573855, 2551681.618527839 6676127.911780471, 2551633.457732826 6676168.98120709, 2551638.489950188 6676195.097201467, 2551619.318026993 6676238.087068884, 2551592.4327870226 6676276.495884816,
+LINESTRING (2551458.9717829595 6675914.192725771, 2551704.9729661196 6676045.46285606, 2551713.659728221 6676052.784536597, 2551715.8293563626 6676064.487222701, 2551694.933280006 6676090.3431573855, 2551681.618527839 6676127.911780471, 2551633.457732826 6676168.98120709, 2551638.489950188 6676195.097201467, 2551619.318026993 6676238.087068884, 2551592.4327870226 6676276.495884816,
2551586.5921150683 6676283.857574537, 2551566.2652567415 6676286.59820359, 2551550.7066306034 6676302.861936587, 2551539.9657338737 6676322.26639047)
LINESTRING (2549063.232091463 6676502.957864385, 2549067.1588709126 6676512.280004086)
@@ -1151,7 +1151,7 @@ LINESTRING (2552520.4974115817 6672638.460850639, 2552526.3050853894 6672709.167
LINESTRING (2552518.484524637 6672622.867271462, 2552520.4974115817 6672638.460850639)
-LINESTRING (2554373.49183677 6675472.6113700885, 2554389.0999601283 6675470.040780064, 2554414.9292594064 6675465.779802047, 2554390.57662719 6675476.172187399, 2554372.8318738374 6675483.753927628, 2554167.1296772542 6675553.870021298, 2554127.870132296 6675559.891403379, 2554104.5899398453 6675563.462222985, 2554060.1661849385 6675561.271720201, 2554008.3260965757 6675547.978669061,
+LINESTRING (2554373.49183677 6675472.6113700885, 2554389.0999601283 6675470.040780064, 2554414.9292594064 6675465.779802047, 2554390.57662719 6675476.172187399, 2554372.8318738374 6675483.753927628, 2554167.1296772542 6675553.870021298, 2554127.870132296 6675559.891403379, 2554104.5899398453 6675563.462222985, 2554060.1661849385 6675561.271720201, 2554008.3260965757 6675547.978669061,
2553991.158810789 6675540.406931129)
LINESTRING (2551114.611374218 6675220.503504047, 2551061.5256058197 6675212.5716834655)
@@ -1248,7 +1248,7 @@ LINESTRING (2553233.0593900075 6674893.908541065, 2553151.1827386706 6674957.583
LINESTRING (2549709.2533072005 6677274.374926895, 2549697.596711902 6677264.142578275, 2549679.752964109 6677240.377123416, 2549675.9251790997 6677233.775608178)
-LINESTRING (2549176.6384719093 6674324.00773236, 2549165.8893256434 6674317.4062171215, 2549159.4629365862 6674308.824247311, 2549155.47841038 6674299.692151231, 2549155.7836432364 6674288.779646496, 2549160.5601249617 6674278.587307059, 2549165.608841397 6674274.036262463, 2549171.9527350874 6674274.026260167, 2549187.016389026 6674286.979233249, 2549184.0300567555 6674306.553726161,
+LINESTRING (2549176.6384719093 6674324.00773236, 2549165.8893256434 6674317.4062171215, 2549159.4629365862 6674308.824247311, 2549155.47841038 6674299.692151231, 2549155.7836432364 6674288.779646496, 2549160.5601249617 6674278.587307059, 2549165.608841397 6674274.036262463, 2549171.9527350874 6674274.026260167, 2549187.016389026 6674286.979233249, 2549184.0300567555 6674306.553726161,
2549176.6384719093 6674324.00773236)
LINESTRING (2551312.9137364184 6673244.529961015, 2551308.689973649 6673268.8555444395, 2551291.341198056 6673494.177262286)
@@ -1371,7 +1371,7 @@ LINESTRING (2551658.899303881 6673651.903465007, 2551649.1483515506 6673666.1167
LINESTRING (2552322.863261851 6673626.757693326, 2552317.179331093 6673633.669279735)
-LINESTRING (2547371.3676162916 6674760.517924064, 2547369.51972008 6674773.991016528, 2547365.81567812 6674799.196801984, 2547360.288488559 6674811.499625837, 2547352.4926764164 6674819.611487744, 2547331.2088718372 6674825.532846867, 2547266.8707354367 6674835.175060034, 2547250.330414436 6674830.3439511545, 2547207.1523395646 6674787.63414802, 2547189.729318142 6674775.731416,
+LINESTRING (2547371.3676162916 6674760.517924064, 2547369.51972008 6674773.991016528, 2547365.81567812 6674799.196801984, 2547360.288488559 6674811.499625837, 2547352.4926764164 6674819.611487744, 2547331.2088718372 6674825.532846867, 2547266.8707354367 6674835.175060034, 2547250.330414436 6674830.3439511545, 2547207.1523395646 6674787.63414802, 2547189.729318142 6674775.731416,
2547154.3718040227 6674762.088284506, 2547129.020977871 6674761.358116913)
LINESTRING (2553491.401880009 6676038.891347708, 2553485.651952958 6676036.060697992)
@@ -1596,7 +1596,7 @@ LINESTRING (2549314.974952138 6671750.76709927, 2549129.1046416825 6671709.01751
LINESTRING (2553532.6743119126 6673185.456401926, 2553555.352288187 6673221.024565848, 2553557.5136667914 6673231.256914468)
-LINESTRING (2551481.427021744 6671124.963459249, 2551445.178557666 6671054.67732655, 2551435.180119236 6671046.105359036, 2551419.3410088513 6671039.603866755, 2551404.846572942 6671040.844151436, 2551386.400608973 6671047.835756212, 2551312.4600119023 6671088.845169057, 2551297.338611207 6671100.237783992, 2551288.8415884483 6671108.17960687, 2551285.1210474153 6671126.433796734,
+LINESTRING (2551481.427021744 6671124.963459249, 2551445.178557666 6671054.67732655, 2551435.180119236 6671046.105359036, 2551419.3410088513 6671039.603866755, 2551404.846572942 6671040.844151436, 2551386.400608973 6671047.835756212, 2551312.4600119023 6671088.845169057, 2551297.338611207 6671100.237783992, 2551288.8415884483 6671108.17960687, 2551285.1210474153 6671126.433796734,
2551335.657708986 6671225.196465621, 2551491.2522199047 6671144.017832778)
LINESTRING (2552037.8417702955 6673754.316971866, 2551998.169748504 6673877.825320601, 2552022.431635817 6673885.937182508)
@@ -1779,7 +1779,7 @@ LINESTRING (2550396.332466888 6677132.652397479, 2550485.9636826837 6677154.5574
LINESTRING (2550692.136102856 6672000.934519922, 2550779.399701631 6671848.84961204)
-LINESTRING (2549580.527537179 6675520.572378526, 2549585.370015198 6675542.347376517, 2549589.305044184 6675593.18904615, 2549568.0542377513 6675623.075906048, 2549549.723767296 6675639.769737765, 2549518.738507606 6675693.672109917, 2549495.606806815 6675723.839034098, 2549475.5274345884 6675739.022519146, 2549453.171190243 6675762.447895947, 2549442.5787851736 6675782.422480692,
+LINESTRING (2549580.527537179 6675520.572378526, 2549585.370015198 6675542.347376517, 2549589.305044184 6675593.18904615, 2549568.0542377513 6675623.075906048, 2549549.723767296 6675639.769737765, 2549518.738507606 6675693.672109917, 2549495.606806815 6675723.839034098, 2549475.5274345884 6675739.022519146, 2549453.171190243 6675762.447895947, 2549442.5787851736 6675782.422480692,
2549433.677535119 6675822.911774155, 2549389.6992551917 6675872.5131591065, 2549385.1950081764 6675885.236079384, 2549378.3726413595 6675899.999468008)
LINESTRING (2551245.6800126503 6674810.619423806, 2551166.9711833904 6674761.498149053)
@@ -1798,7 +1798,7 @@ LINESTRING (2549880.1094609373 6676167.43085124, 2549897.6067281906 6676183.1444
LINESTRING (2552715.260722555 6675284.768254665, 2552710.8142222962 6675361.675907194)
-LINESTRING (2547920.50627351 6672635.070072358, 2547903.0502539403 6672620.406706692, 2547890.1892262893 6672621.67699826, 2547718.00489715 6672586.118836634, 2547710.035844738 6672587.629183303, 2547706.455545828 6672588.299337123, 2547688.455056839 6672619.506500068, 2547682.754627008 6672635.990283573, 2547679.520808638 6672648.253098243, 2547679.702298444 6672689.502566188,
+LINESTRING (2547920.50627351 6672635.070072358, 2547903.0502539403 6672620.406706692, 2547890.1892262893 6672621.67699826, 2547718.00489715 6672586.118836634, 2547710.035844738 6672587.629183303, 2547706.455545828 6672588.299337123, 2547688.455056839 6672619.506500068, 2547682.754627008 6672635.990283573, 2547679.520808638 6672648.253098243, 2547679.702298444 6672689.502566188,
2547676.1549976813 6672704.17593415, 2547665.834827321 6672719.939552356)
LINESTRING (2552179.7832980435 6672378.541191566, 2552056.98894488 6672339.2921827845)
@@ -2005,12 +2005,12 @@ LINESTRING (2553394.2553363172 6675336.7501860205, 2553372.5013081483 6675350.28
LINESTRING (2547874.358365441 6671779.45368367, 2547987.030537125 6671903.372126534)
-LINESTRING (2552565.003661855 6673149.448136989, 2552576.849996497 6673154.089202248, 2552643.456755479 6673204.110683623, 2552681.874847698 6673207.531468792, 2552788.4341127174 6673214.002954185, 2552892.741254229 6673220.99455896, 2552983.1231778613 6673226.425805588, 2552993.2701079515 6673230.756799676, 2553050.2414081157 6673236.108027938, 2553055.265375941 6673247.010530378,
- 2553055.669603237 6673293.861283979, 2553119.9004956614 6673301.242978292, 2553205.6544292276 6673309.334835607, 2553290.806146618 6673314.916116672, 2553304.1373978583 6673315.44623835, 2553311.495984558 6673318.586959236, 2553315.5877547404 6673324.248258668, 2553324.134274719 6673336.040965435, 2553344.139401116 6673364.037391424, 2553379.109187012 6673412.298468736,
- 2553382.615240092 6673431.512878998, 2553383.2587039513 6673452.957801227, 2553384.355892327 6673489.416169477, 2553390.7657823106 6673499.708531871, 2553398.388354183 6673503.7994708605, 2553399.287553679 6673503.929500706, 2553433.0446576863 6673508.920646318, 2553438.126372268 6673509.670818504, 2553443.909297466 6673513.061596786, 2553451.424625362 6673526.524686954,
- 2553479.8277800772 6673656.594541744, 2553493.3322715876 6673718.438736775, 2553545.51884049 6673950.411981339, 2553561.6796828043 6674022.26847448, 2553559.7905389094 6674043.833424259, 2553548.8516533 6674160.680243981, 2553547.647220948 6674163.500891401, 2553538.020011667 6674185.976050099, 2553503.4132053843 6674218.46350691, 2553481.741672582 6674232.366698094,
- 2553470.2088203332 6674233.837035579, 2553446.1614209735 6674233.516962113, 2553433.2838942492 6674233.7470149165, 2553381.4190572766 6674234.637219245, 2553366.974118587 6674236.167570504, 2553355.1937802387 6674240.948667904, 2553331.1958780987 6674260.173080462, 2553328.6632703445 6674268.35495844, 2553317.6418893686 6674303.933124657, 2553310.6380327456 6674361.746394473,
- 2553308.1714212843 6674396.504372434, 2553303.452686316 6674437.443769208, 2553301.3325553946 6674456.0780463135, 2553296.5148259858 6674498.487780573, 2553292.9180280026 6674525.553993051, 2553290.3854202484 6674548.879346894, 2553291.6228507473 6674559.161706992, 2553292.8767803195 6674569.574096937, 2553318.961815234 6674603.681925669, 2553350.2193096336 6674645.361492335,
+LINESTRING (2552565.003661855 6673149.448136989, 2552576.849996497 6673154.089202248, 2552643.456755479 6673204.110683623, 2552681.874847698 6673207.531468792, 2552788.4341127174 6673214.002954185, 2552892.741254229 6673220.99455896, 2552983.1231778613 6673226.425805588, 2552993.2701079515 6673230.756799676, 2553050.2414081157 6673236.108027938, 2553055.265375941 6673247.010530378,
+ 2553055.669603237 6673293.861283979, 2553119.9004956614 6673301.242978292, 2553205.6544292276 6673309.334835607, 2553290.806146618 6673314.916116672, 2553304.1373978583 6673315.44623835, 2553311.495984558 6673318.586959236, 2553315.5877547404 6673324.248258668, 2553324.134274719 6673336.040965435, 2553344.139401116 6673364.037391424, 2553379.109187012 6673412.298468736,
+ 2553382.615240092 6673431.512878998, 2553383.2587039513 6673452.957801227, 2553384.355892327 6673489.416169477, 2553390.7657823106 6673499.708531871, 2553398.388354183 6673503.7994708605, 2553399.287553679 6673503.929500706, 2553433.0446576863 6673508.920646318, 2553438.126372268 6673509.670818504, 2553443.909297466 6673513.061596786, 2553451.424625362 6673526.524686954,
+ 2553479.8277800772 6673656.594541744, 2553493.3322715876 6673718.438736775, 2553545.51884049 6673950.411981339, 2553561.6796828043 6674022.26847448, 2553559.7905389094 6674043.833424259, 2553548.8516533 6674160.680243981, 2553547.647220948 6674163.500891401, 2553538.020011667 6674185.976050099, 2553503.4132053843 6674218.46350691, 2553481.741672582 6674232.366698094,
+ 2553470.2088203332 6674233.837035579, 2553446.1614209735 6674233.516962113, 2553433.2838942492 6674233.7470149165, 2553381.4190572766 6674234.637219245, 2553366.974118587 6674236.167570504, 2553355.1937802387 6674240.948667904, 2553331.1958780987 6674260.173080462, 2553328.6632703445 6674268.35495844, 2553317.6418893686 6674303.933124657, 2553310.6380327456 6674361.746394473,
+ 2553308.1714212843 6674396.504372434, 2553303.452686316 6674437.443769208, 2553301.3325553946 6674456.0780463135, 2553296.5148259858 6674498.487780573, 2553292.9180280026 6674525.553993051, 2553290.3854202484 6674548.879346894, 2553291.6228507473 6674559.161706992, 2553292.8767803195 6674569.574096937, 2553318.961815234 6674603.681925669, 2553350.2193096336 6674645.361492335,
2553370.414175374 6674668.426786486, 2553403.107089152 6674705.765356767, 2553423.037969719 6674726.15003564, 2553532.7980549624 6674875.254259368, 2553603.3563420037 6674962.294237559, 2553719.84804916 6675104.546888653, 2553778.3455136064 6675172.792553006, 2553801.2297282973 6675205.690103944, 2553801.5432106904 6675206.240230214)
LINESTRING (2549236.2578733414 6676538.766083406, 2549231.959864742 6676574.844364415)
@@ -2063,7 +2063,7 @@ LINESTRING (2552938.220949828 6673883.426606258, 2553085.706166211 6673889.87808
LINESTRING (2548872.9647779684 6672919.015245981, 2548857.389652757 6672908.682874403, 2548845.477321822 6672891.298884274, 2548836.732812964 6672864.812804954, 2548834.2249538195 6672841.207386828)
-LINESTRING (2551445.7807738422 6677291.28880912, 2551490.7077504853 6677321.915838908, 2551491.862685617 6677333.628527309, 2551488.8103570538 6677348.812012357, 2551479.859609779 6677362.795221908, 2551465.1341868434 6677369.146679751, 2551442.546955472 6677361.174849985, 2551435.048126649 6677367.406280279, 2551429.405443575 6677382.089650537, 2551427.532798753 6677405.685066367,
+LINESTRING (2551445.7807738422 6677291.28880912, 2551490.7077504853 6677321.915838908, 2551491.862685617 6677333.628527309, 2551488.8103570538 6677348.812012357, 2551479.859609779 6677362.795221908, 2551465.1341868434 6677369.146679751, 2551442.546955472 6677361.174849985, 2551435.048126649 6677367.406280279, 2551429.405443575 6677382.089650537, 2551427.532798753 6677405.685066367,
2551436.1040673414 6677417.707825937, 2551446.300494652 6677423.239095524)
LINESTRING (2552599.255738062 6672877.725768852, 2552579.465099618 6673027.760206092)
@@ -2124,7 +2124,7 @@ LINESTRING (2553412.2310766964 6676283.58751255, 2553391.442244317 6676304.27226
LINESTRING (2550335.93760901 6676264.013019638, 2550341.3410555213 6676302.441840163, 2550353.7648577294 6676318.595547906, 2550370.8661472225 6676327.617618732, 2550473.8038656493 6676379.129442184)
-LINESTRING (2552087.8834596667 6676362.1955553675, 2552066.946135627 6676364.3160420805, 2552056.9229485868 6676370.257405795, 2552051.288515049 6676379.01941693, 2552029.122010047 6676463.828883153, 2552022.9101089435 6676473.691146828, 2551967.8527012835 6676502.227696791, 2551956.7818230875 6676503.728041164, 2551906.0059249536 6676502.46775189, 2551894.4648231682 6676498.436826677,
+LINESTRING (2552087.8834596667 6676362.1955553675, 2552066.946135627 6676364.3160420805, 2552056.9229485868 6676370.257405795, 2552051.288515049 6676379.01941693, 2552029.122010047 6676463.828883153, 2552022.9101089435 6676473.691146828, 2551967.8527012835 6676502.227696791, 2551956.7818230875 6676503.728041164, 2551906.0059249536 6676502.46775189, 2551894.4648231682 6676498.436826677,
2551876.4973323257 6676480.502710278, 2551871.7373496736 6676465.50926885, 2551871.374370061 6676451.686096033, 2551878.0069975345 6676411.426855373, 2551883.7156769023 6676397.683700923, 2551905.6676939507 6676368.146921378)
LINESTRING (2552915.658467067 6674300.512339488, 2552992.4286552123 6674304.88334276, 2553005.4134259126 6674311.614887844, 2553009.026722969 6674320.076830104, 2553001.5361436834 6674453.237394302)
@@ -2331,7 +2331,7 @@ LINESTRING (2553224.2818830027 6677495.7457378935, 2553284.569496904 6677555.169
LINESTRING (2551230.715353152 6673946.261028575, 2551337.0023834617 6674078.751438953)
-LINESTRING (2553293.561491862 6675401.385021583, 2553271.7744655465 6675414.678072723, 2553214.7784167724 6675407.696470243, 2553205.431691738 6675413.437788041, 2553193.997833929 6675415.13817833, 2553184.139637622 6675413.457792633, 2553169.1997267334 6675400.264764451, 2553137.793740674 6675394.893531599, 2553126.500124988 6675385.761435519, 2553121.1296766233 6675372.718441775,
+LINESTRING (2553293.561491862 6675401.385021583, 2553271.7744655465 6675414.678072723, 2553214.7784167724 6675407.696470243, 2553205.431691738 6675413.437788041, 2553193.997833929 6675415.13817833, 2553184.139637622 6675413.457792633, 2553169.1997267334 6675400.264764451, 2553137.793740674 6675394.893531599, 2553126.500124988 6675385.761435519, 2553121.1296766233 6675372.718441775,
2553123.942768624 6675325.787669806, 2553131.986066866 6675319.296179822)
LINESTRING (2553824.559417968 6675403.835584058, 2553897.2378359307 6675544.497870117)
@@ -2514,7 +2514,7 @@ LINESTRING (2553932.14987507 6675424.730380017, 2553933.700787962 6675426.800855
LINESTRING (2549363.721464254 6672660.605933576, 2549366.9222844774 6672680.400476996, 2549410.9500616244 6672715.178459547, 2549456.974226643 6672783.074043546)
-LINESTRING (2548760.7710794113 6677439.552839999, 2548739.8750030547 6677437.032261454, 2548728.8866202254 6677437.8524497105, 2548709.2857211246 6677445.674245039, 2548638.4304507636 6677488.664112455, 2548604.7723411964 6677507.0383298695, 2548580.93942979 6677511.469346916, 2548561.817003815 6677519.291142244, 2548484.3786032004 6677568.612462913, 2548468.869474282 6677590.167410396,
+LINESTRING (2548760.7710794113 6677439.552839999, 2548739.8750030547 6677437.032261454, 2548728.8866202254 6677437.8524497105, 2548709.2857211246 6677445.674245039, 2548638.4304507636 6677488.664112455, 2548604.7723411964 6677507.0383298695, 2548580.93942979 6677511.469346916, 2548561.817003815 6677519.291142244, 2548484.3786032004 6677568.612462913, 2548468.869474282 6677590.167410396,
2548464.35697773 6677596.738918747)
LINESTRING (2550948.0037318603 6675344.031857374, 2550808.454569743 6675266.964168113)
@@ -2547,7 +2547,7 @@ LINESTRING (2548287.684900649 6672795.936995965, 2548263.2415235294 6672807.7597
LINESTRING (2553182.3164900206 6674153.00848309, 2553179.3384072864 6674191.97742759)
-LINESTRING (2549202.9957415336 6677369.356727963, 2549229.6252458678 6677307.102438805, 2549254.588343797 6677276.985526103, 2549267.127639518 6677269.363776691, 2549260.016538918 6677253.920231951, 2549273.3065424752 6677182.453828346, 2549271.9206203166 6677176.532469223, 2549259.4803190352 6677171.941415444, 2549187.4536144687 6677164.309663736, 2549153.9439965617 6677347.191640435,
+LINESTRING (2549202.9957415336 6677369.356727963, 2549229.6252458678 6677307.102438805, 2549254.588343797 6677276.985526103, 2549267.127639518 6677269.363776691, 2549260.016538918 6677253.920231951, 2549273.3065424752 6677182.453828346, 2549271.9206203166 6677176.532469223, 2549259.4803190352 6677171.941415444, 2549187.4536144687 6677164.309663736, 2549153.9439965617 6677347.191640435,
2549202.9957415336 6677369.356727963)
LINESTRING (2550252.6502869045 6676539.466244114, 2550329.32148061 6676544.68744253, 2550543.784685124 6676559.450831154)
@@ -2614,7 +2614,7 @@ LINESTRING (2552698.3739210153 6674904.100880502, 2552760.872410741 6674986.3297
LINESTRING (2554612.423167014 6675880.555004942, 2554597.4255093685 6675833.024095225, 2554597.260518635 6675818.020651501, 2554621.7368939016 6675740.422840561)
-LINESTRING (2548983.7478057574 6674894.218612235, 2548997.4750347575 6674898.389569591, 2549009.428613376 6674897.039259655, 2549031.091896641 6674889.337491877, 2549086.7927681603 6674882.215857256, 2549105.6594584985 6674871.443384662, 2549120.731361974 6674873.913951729, 2549157.8047797177 6674893.198378062, 2549195.595907151 6674905.581220282, 2549232.3640920385 6674913.663075302,
+LINESTRING (2548983.7478057574 6674894.218612235, 2548997.4750347575 6674898.389569591, 2549009.428613376 6674897.039259655, 2549031.091896641 6674889.337491877, 2549086.7927681603 6674882.215857256, 2549105.6594584985 6674871.443384662, 2549120.731361974 6674873.913951729, 2549157.8047797177 6674893.198378062, 2549195.595907151 6674905.581220282, 2549232.3640920385 6674913.663075302,
2549285.705596073 6674955.702724616, 2549305.116755831 6674955.132593755, 2549335.5245479546 6674985.489561556)
LINESTRING (2551117.853442125 6675055.035524365, 2551105.0584107675 6675048.4140045345, 2551027.08379027 6674989.990594673)
@@ -2737,7 +2737,7 @@ LINESTRING (2550933.6990352944 6673730.841583586, 2550817.034087868 6673801.0276
LINESTRING (2553373.384008571 6673347.723646948, 2553377.95425188 6673345.213070698, 2553557.5136667914 6673231.256914468)
-LINESTRING (2551906.43490086 6671776.923102828, 2551921.572800629 6671722.220547011, 2551916.697324463 6671708.97750735, 2551897.690392002 6671693.523960315, 2551873.7749852287 6671666.857839669, 2551855.8652411425 6671639.501560613, 2551795.7261189013 6671523.915030164, 2551805.782304088 6671476.494145701, 2551804.5366240526 6671466.011739685, 2551679.473648308 6671222.705893962,
+LINESTRING (2551906.43490086 6671776.923102828, 2551921.572800629 6671722.220547011, 2551916.697324463 6671708.97750735, 2551897.690392002 6671693.523960315, 2551873.7749852287 6671666.857839669, 2551855.8652411425 6671639.501560613, 2551795.7261189013 6671523.915030164, 2551805.782304088 6671476.494145701, 2551804.5366240526 6671466.011739685, 2551679.473648308 6671222.705893962,
2551671.422100529 6671215.784305258, 2551660.813196386 6671215.63427082, 2551571.1077347603 6671261.264744333, 2551561.926000459 6671263.085162171, 2551553.84970407 6671260.544579034, 2551547.093333547 6671252.882820439, 2551491.2522199047 6671144.017832778)
LINESTRING (2551661.514407002 6673021.638801052, 2551612.3884162 6672988.061093998)
@@ -2890,14 +2890,14 @@ LINESTRING (2553672.239973103 6677388.731174959, 2553693.0370550198 6677366.9761
LINESTRING (2553322.5008664606 6675477.422474376, 2553296.729313939 6675472.141262185)
-LINESTRING (2552540.7087763953 6673856.620453472, 2552537.656447832 6673859.791181246, 2552526.197841413 6673969.586382417, 2552522.6257920396 6673981.93921775, 2552497.6379455007 6674020.528075008, 2552484.6531748 6674074.850543585, 2552475.850919185 6674149.257622159, 2552457.3059607767 6674203.500072369, 2552433.3163081734 6674251.000975199, 2552457.9659237093 6674315.865863565,
+LINESTRING (2552540.7087763953 6673856.620453472, 2552537.656447832 6673859.791181246, 2552526.197841413 6673969.586382417, 2552522.6257920396 6673981.93921775, 2552497.6379455007 6674020.528075008, 2552484.6531748 6674074.850543585, 2552475.850919185 6674149.257622159, 2552457.3059607767 6674203.500072369, 2552433.3163081734 6674251.000975199, 2552457.9659237093 6674315.865863565,
2552469.9772490845 6674314.32551001, 2552538.7948838905 6674256.922334322, 2552572.4117457746 6674236.2575911665, 2552769.740662649 6674190.066989088, 2552873.2723477148 6674175.9337451, 2552913.356846339 6674178.394309871)
LINESTRING (2549124.6828900333 6676320.435970336, 2549179.492811593 6676363.095761991)
LINESTRING (2552394.7992215143 6671836.756836399, 2552326.2620709543 6671842.438140423, 2552268.0945879743 6671857.091503793, 2552210.3148332173 6671883.367534901, 2552192.6443256945 6671895.100227893)
-LINESTRING (2553258.6824508696 6671752.257441346, 2553307.899186575 6671743.005317716, 2553327.4588379925 6671743.275379703, 2553356.2414713944 6671753.047622715, 2553364.416762223 6671759.249046122, 2553372.229073439 6671765.190409836, 2553384.3393932534 6671781.114064775, 2553425.45508396 6671872.695085266, 2553439.4132999866 6671885.367994064, 2553475.3317825985 6671896.300503392,
+LINESTRING (2553258.6824508696 6671752.257441346, 2553307.899186575 6671743.005317716, 2553327.4588379925 6671743.275379703, 2553356.2414713944 6671753.047622715, 2553364.416762223 6671759.249046122, 2553372.229073439 6671765.190409836, 2553384.3393932534 6671781.114064775, 2553425.45508396 6671872.695085266, 2553439.4132999866 6671885.367994064, 2553475.3317825985 6671896.300503392,
2553498.7274685623 6671899.161159995, 2553558.3551195306 6671918.175524341, 2553586.8572686864 6671931.4285662975)
LINESTRING (2553350.22755917 6673302.153187211, 2553415.7866269965 6673260.363595292, 2553532.6743119126 6673185.456401926)
@@ -3060,7 +3060,7 @@ LINESTRING (2554117.6819545226 6673171.423180896, 2554115.636069431 6673175.2140
LINESTRING (2553477.9386361823 6676032.269827878, 2553426.9647491686 6676010.044726576)
-LINESTRING (2549341.2497263956 6674960.123739366, 2549344.145313763 6674946.490610169, 2549349.4662649077 6674942.769756126, 2549344.425798009 6674937.468539343, 2549338.9893533513 6674916.443713538, 2549318.283016338 6674889.847608964, 2549302.6088966867 6674852.118949146, 2549295.2750585973 6674810.4193778895, 2549304.605284558 6674782.392945013, 2549319.8504283032 6674725.119799171,
+LINESTRING (2549341.2497263956 6674960.123739366, 2549344.145313763 6674946.490610169, 2549349.4662649077 6674942.769756126, 2549344.425798009 6674937.468539343, 2549338.9893533513 6674916.443713538, 2549318.283016338 6674889.847608964, 2549302.6088966867 6674852.118949146, 2549295.2750585973 6674810.4193778895, 2549304.605284558 6674782.392945013, 2549319.8504283032 6674725.119799171,
2549324.709405395 6674705.355262639, 2549331.0615486223 6674700.614174422)
LINESTRING (2550305.4720701296 6676712.665998463, 2550341.9845193806 6676750.574699605, 2550362.4351207577 6676788.45339386)
@@ -3141,10 +3141,10 @@ LINESTRING (2549247.0812654374 6672845.548383213, 2549207.2030052296 6672804.628
LINESTRING (2553594.125110483 6673282.258620833, 2553609.6342394007 6673306.284135383)
-LINESTRING (2549078.5514810383 6677099.384761594, 2549106.962885291 6676998.751663391, 2549127.4134866674 6676931.256171225, 2549142.2461535796 6676882.284930909, 2549199.143207914 6676677.207859796, 2549222.4811471216 6676594.02876779, 2549236.2578733414 6676538.766083406, 2549249.1106514554 6676487.214250771, 2549251.0327934967 6676472.100781793, 2549248.1949528866 6676444.04434203,
- 2549248.326945473 6676428.60079729, 2549258.9688477623 6676424.309812385, 2549305.5374822007 6676406.915819961, 2549398.204527487 6676372.2978741415, 2549467.2284007096 6676343.601287446, 2549500.1028042943 6676330.738335026, 2549534.6766124307 6676310.113601054, 2549556.2574003297 6676298.991048107, 2549596.680129957 6676263.692946172, 2549607.06629661 6676254.200767443,
- 2549651.97677418 6676213.151345414, 2549716.207666604 6676154.457873566, 2549810.7061090283 6676078.2503817445, 2549830.537995156 6676063.476990825, 2549989.9437920107 6675953.431732257, 2550072.9093821864 6675894.198136435, 2550098.0704689953 6675883.225617925, 2550112.045184095 6675878.084437876, 2550173.908459498 6675874.073517254, 2550230.508530513 6675872.463147627,
- 2550277.86912047 6675871.0628262125, 2550369.2079903544 6675868.362206343, 2550494.980426252 6675865.161471682, 2550508.748902935 6675864.831395919, 2550600.854979729 6675862.360828853, 2550689.6034951024 6675859.940273265, 2550769.4590099575 6675857.869798032, 2550821.79407052 6675856.429467434, 2550825.6548536764 6675860.640433973, 2550829.325897489 6675864.911414286,
+LINESTRING (2549078.5514810383 6677099.384761594, 2549106.962885291 6676998.751663391, 2549127.4134866674 6676931.256171225, 2549142.2461535796 6676882.284930909, 2549199.143207914 6676677.207859796, 2549222.4811471216 6676594.02876779, 2549236.2578733414 6676538.766083406, 2549249.1106514554 6676487.214250771, 2549251.0327934967 6676472.100781793, 2549248.1949528866 6676444.04434203,
+ 2549248.326945473 6676428.60079729, 2549258.9688477623 6676424.309812385, 2549305.5374822007 6676406.915819961, 2549398.204527487 6676372.2978741415, 2549467.2284007096 6676343.601287446, 2549500.1028042943 6676330.738335026, 2549534.6766124307 6676310.113601054, 2549556.2574003297 6676298.991048107, 2549596.680129957 6676263.692946172, 2549607.06629661 6676254.200767443,
+ 2549651.97677418 6676213.151345414, 2549716.207666604 6676154.457873566, 2549810.7061090283 6676078.2503817445, 2549830.537995156 6676063.476990825, 2549989.9437920107 6675953.431732257, 2550072.9093821864 6675894.198136435, 2550098.0704689953 6675883.225617925, 2550112.045184095 6675878.084437876, 2550173.908459498 6675874.073517254, 2550230.508530513 6675872.463147627,
+ 2550277.86912047 6675871.0628262125, 2550369.2079903544 6675868.362206343, 2550494.980426252 6675865.161471682, 2550508.748902935 6675864.831395919, 2550600.854979729 6675862.360828853, 2550689.6034951024 6675859.940273265, 2550769.4590099575 6675857.869798032, 2550821.79407052 6675856.429467434, 2550825.6548536764 6675860.640433973, 2550829.325897489 6675864.911414286,
2550833.4836639655 6675869.752525461)
LINESTRING (2553689.1515232534 6675997.631877468, 2553689.5640000864 6676056.635420486, 2553689.547501013 6676086.742330892)
@@ -3375,7 +3375,7 @@ LINESTRING (2552735.637078102 6676535.095240842, 2552785.5550244236 6676634.3080
LINESTRING (2551303.7237525806 6672909.38303511, 2551073.289445095 6672891.4089095285)
-LINESTRING (2547582.9599820487 6674466.060337538, 2547514.439330562 6674425.63105785, 2547503.739681516 6674414.138419957, 2547498.682715544 6674402.2756971195, 2547497.618525315 6674376.589801464, 2547529.6019789404 6674324.277794347, 2547535.591142555 6674307.073845543, 2547536.5233401973 6674253.351514716, 2547540.2356316936 6674218.303470177, 2547531.2683853456 6674184.245652923,
+LINESTRING (2547582.9599820487 6674466.060337538, 2547514.439330562 6674425.63105785, 2547503.739681516 6674414.138419957, 2547498.682715544 6674402.2756971195, 2547497.618525315 6674376.589801464, 2547529.6019789404 6674324.277794347, 2547535.591142555 6674307.073845543, 2547536.5233401973 6674253.351514716, 2547540.2356316936 6674218.303470177, 2547531.2683853456 6674184.245652923,
2547532.4315700145 6674137.264869476, 2547537.0925582265 6674094.465045679, 2547540.9863395295 6674079.161533081, 2547553.3853931273 6674054.625901445, 2547582.5970024355 6674017.757439067, 2547658.220504985 6673958.333799625, 2547691.1691544 6673914.113649822, 2547700.161149358 6673908.902453702, 2547741.219093308 6673902.38095683)
LINESTRING (2553203.32805989 6675312.814692133, 2553241.9111428424 6675316.725589797)
@@ -3566,7 +3566,7 @@ LINESTRING (2552733.706686524 6674363.156718183, 2552629.5150385257 6674398.8349
LINESTRING (2547830.4048341243 6672948.171938284, 2547782.706013164 6673175.964223197, 2547776.2631250336 6673220.1143569285, 2547776.114633374 6673256.982819306, 2547781.8480613516 6673283.718956022)
-LINESTRING (2550674.9523179964 6674116.500103362, 2550664.4836559766 6674113.329375588, 2550650.0139686773 6674100.476425465, 2550640.1475228337 6674080.841918779, 2550633.943871266 6674042.0630179, 2550645.8562022015 6673991.161334492, 2550645.410727222 6673981.349082297, 2550637.8129039593 6673962.314713359, 2550616.265114207 6673944.200555637, 2550609.1292649973 6673933.918195537,
+LINESTRING (2550674.9523179964 6674116.500103362, 2550664.4836559766 6674113.329375588, 2550650.0139686773 6674100.476425465, 2550640.1475228337 6674080.841918779, 2550633.943871266 6674042.0630179, 2550645.8562022015 6673991.161334492, 2550645.410727222 6673981.349082297, 2550637.8129039593 6673962.314713359, 2550616.265114207 6673944.200555637, 2550609.1292649973 6673933.918195537,
2550602.87611621 6673919.264832167, 2550599.832037183 6673900.880612458, 2550603.0493564797 6673873.6943724295, 2550611.1504014786 6673856.980536122)
LINESTRING (2553001.2886575833 6672957.1539999265, 2552994.8622685266 6673053.926211947)
@@ -3687,7 +3687,7 @@ LINESTRING (2554689.003615816 6675483.063769217, 2554673.997708634 6675411.23728
LINESTRING (2553210.7361438093 6675702.444123347, 2553255.448632499 6675777.9514544625, 2553136.3335726853 6675843.806570115, 2553036.877158729 6675914.892886478)
-LINESTRING (2551999.085447073 6675223.374162947, 2551999.836154909 6675231.335990416, 2552005.198353737 6675330.548762615, 2552011.3030108646 6675365.086690067, 2552030.169701203 6675410.377085522, 2552054.712072762 6675461.248762041, 2552048.7806559047 6675498.237251969, 2551956.270351815 6675854.0589233255, 2551924.6168796555 6675975.806867997, 2551878.3452285375 6676036.390773755,
+LINESTRING (2551999.085447073 6675223.374162947, 2551999.836154909 6675231.335990416, 2552005.198353737 6675330.548762615, 2552011.3030108646 6675365.086690067, 2552030.169701203 6675410.377085522, 2552054.712072762 6675461.248762041, 2552048.7806559047 6675498.237251969, 2551956.270351815 6675854.0589233255, 2551924.6168796555 6675975.806867997, 2551878.3452285375 6676036.390773755,
2551873.568746812 6676050.864095801)
LINESTRING (2551433.3982193177 6673228.386255568, 2551424.051494283 6673230.496739985)
@@ -3720,7 +3720,7 @@ LINESTRING (2552932.009048724 6672051.656162005, 2552909.710551136 6672140.62658
LINESTRING (2553248.6180161457 6676044.322594336, 2553284.1240219246 6676080.130813357)
-LINESTRING (2554628.592258865 6675609.082694202, 2554618.8495560708 6675592.478883147, 2554608.5623838576 6675549.84909838, 2554616.7129260763 6675534.875661543, 2554630.959875886 6675521.212525458, 2554637.8564885324 6675500.547782303, 2554633.59147808 6675465.359705622, 2554623.0238216203 6675421.849718823, 2554615.458996504 6675390.722574243, 2554594.686663198 6675384.011033751,
+LINESTRING (2554628.592258865 6675609.082694202, 2554618.8495560708 6675592.478883147, 2554608.5623838576 6675549.84909838, 2554616.7129260763 6675534.875661543, 2554630.959875886 6675521.212525458, 2554637.8564885324 6675500.547782303, 2554633.59147808 6675465.359705622, 2554623.0238216203 6675421.849718823, 2554615.458996504 6675390.722574243, 2554594.686663198 6675384.011033751,
2554435.9490788123 6675418.588970386, 2554418.1960759233 6675429.631504968, 2554413.4278437346 6675436.513084489, 2554417.3463736475 6675464.429492111, 2554417.577360674 6675465.189666593, 2554433.705204841 6675518.5819216585, 2554453.2236085758 6675553.930035072)
LINESTRING (2551832.205570006 6673236.458108292, 2551686.7332405676 6673273.27655919)
@@ -3737,7 +3737,7 @@ LINESTRING (2552498.4628991666 6676774.4501797175, 2552471.6106573427 6676767.93
LINESTRING (2554429.1597101423 6676121.850389206, 2554406.572478771 6676113.638504341, 2554385.791895928 6676101.185646051, 2554362.7756886506 6676066.617711711, 2554376.2801801604 6676032.549892161, 2554377.773346296 6676022.447573387, 2554374.828261709 6676016.516211968, 2554346.812835216 6675966.984843087)
-LINESTRING (2547873.426167799 6672736.283303719, 2547884.785779778 6672749.516341084, 2547916.3072593505 6672756.8680285085, 2547939.174974968 6672759.738687407, 2547955.566804309 6672757.418154778, 2547968.4113328867 6672749.226274505, 2547975.844165416 6672737.33354478, 2547977.477573674 6672724.620626798, 2547974.3839974273 6672712.217779986, 2547968.3123384467 6672704.125922671,
+LINESTRING (2547873.426167799 6672736.283303719, 2547884.785779778 6672749.516341084, 2547916.3072593505 6672756.8680285085, 2547939.174974968 6672759.738687407, 2547955.566804309 6672757.418154778, 2547968.4113328867 6672749.226274505, 2547975.844165416 6672737.33354478, 2547977.477573674 6672724.620626798, 2547974.3839974273 6672712.217779986, 2547968.3123384467 6672704.125922671,
2547948.818683322 6672694.033606193, 2547920.7125119264 6672681.830805297)
LINESTRING (2550948.0037318603 6675344.031857374, 2550915.244821789 6675393.543221664)
@@ -3962,10 +3962,10 @@ LINESTRING (2552925.557911057 6674460.349026627, 2552918.4798086043 6674594.7698
LINESTRING (2552103.912309394 6674035.331472816, 2552084.14641956 6674019.7879051175)
-LINESTRING (2554412.3554039686 6675566.242861222, 2554390.57662719 6675476.172187399, 2554389.0999601283 6675470.040780064, 2554388.472995342 6675467.460187743, 2554379.431503164 6675430.071605983, 2554375.158243175 6675410.9972278625, 2554288.1503800363 6675429.891564659, 2554273.8456834704 6675439.653805375, 2554238.446921668 6675479.002837115, 2554207.3379189284 6675494.726446138,
- 2554173.8860477777 6675504.448677671, 2554079.6020933064 6675514.631014812, 2554042.000705216 6675510.840144698, 2554007.4763943 6675496.876939738, 2553978.9164983877 6675474.841882056, 2553933.700787962 6675426.800855252, 2553991.158810789 6675540.406931129, 2554008.458089162 6675550.689291228, 2554046.6369448183 6675568.053276764, 2554062.0553288334 6675571.724119329,
- 2554093.4943130394 6675575.6750261765, 2554099.6319683134 6675575.384959597, 2554162.3449459923 6675572.354263965, 2554200.2515669386 6675562.872087532, 2554275.4873412657 6675529.864511339, 2554327.5254185083 6675517.011561216, 2554364.772076522 6675514.701030882, 2554378.4168101554 6675519.092038745, 2554390.2218971136 6675529.964534298, 2554412.3554039686 6675566.242861222,
- 2554425.736152429 6675609.322749301, 2554468.641992591 6675824.642171331, 2554480.909053602 6675905.650765144, 2554476.825532956 6675953.481743736, 2554451.334464681 6676058.205780929, 2554429.1597101423 6676121.850389206, 2554414.8467640397 6676158.238741385, 2554379.8934772173 6676217.332305065, 2554291.7966752397 6676321.246156297, 2554048.9550646194 6676589.457718601,
+LINESTRING (2554412.3554039686 6675566.242861222, 2554390.57662719 6675476.172187399, 2554389.0999601283 6675470.040780064, 2554388.472995342 6675467.460187743, 2554379.431503164 6675430.071605983, 2554375.158243175 6675410.9972278625, 2554288.1503800363 6675429.891564659, 2554273.8456834704 6675439.653805375, 2554238.446921668 6675479.002837115, 2554207.3379189284 6675494.726446138,
+ 2554173.8860477777 6675504.448677671, 2554079.6020933064 6675514.631014812, 2554042.000705216 6675510.840144698, 2554007.4763943 6675496.876939738, 2553978.9164983877 6675474.841882056, 2553933.700787962 6675426.800855252, 2553991.158810789 6675540.406931129, 2554008.458089162 6675550.689291228, 2554046.6369448183 6675568.053276764, 2554062.0553288334 6675571.724119329,
+ 2554093.4943130394 6675575.6750261765, 2554099.6319683134 6675575.384959597, 2554162.3449459923 6675572.354263965, 2554200.2515669386 6675562.872087532, 2554275.4873412657 6675529.864511339, 2554327.5254185083 6675517.011561216, 2554364.772076522 6675514.701030882, 2554378.4168101554 6675519.092038745, 2554390.2218971136 6675529.964534298, 2554412.3554039686 6675566.242861222,
+ 2554425.736152429 6675609.322749301, 2554468.641992591 6675824.642171331, 2554480.909053602 6675905.650765144, 2554476.825532956 6675953.481743736, 2554451.334464681 6676058.205780929, 2554429.1597101423 6676121.850389206, 2554414.8467640397 6676158.238741385, 2554379.8934772173 6676217.332305065, 2554291.7966752397 6676321.246156297, 2554048.9550646194 6676589.457718601,
2553915.7250475828 6676736.621496942, 2553857.3925738693 6676805.917402355, 2553716.66372801 6676949.040253185, 2553701.558826388 6676964.403779559)
LINESTRING (2551050.380481794 6676014.395725255, 2551042.279436795 6676028.979072555)
@@ -4028,7 +4028,7 @@ LINESTRING (2552883.7245106613 6672239.799346303, 2552708.001130296 6672220.4849
LINESTRING (2547919.3513383777 6672037.772975412, 2547917.4126972626 6672072.730999289, 2547919.3348393044 6672089.184775907, 2547941.9715678957 6672164.342026668, 2548008.8175634407 6672181.105874455)
-LINESTRING (2547822.9555025217 6675118.270038513, 2547815.8774000686 6675135.994106699, 2547787.639236086 6675171.432240775, 2547832.689955779 6675216.082489297, 2547969.0712958192 6675331.919077141, 2547992.9702035193 6675351.2235080665, 2548071.4397962163 6675384.621173795, 2548114.2713905475 6675401.815120303, 2548130.036255102 6675412.527579122, 2548133.360818376 6675415.518265571,
+LINESTRING (2547822.9555025217 6675118.270038513, 2547815.8774000686 6675135.994106699, 2547787.639236086 6675171.432240775, 2547832.689955779 6675216.082489297, 2547969.0712958192 6675331.919077141, 2547992.9702035193 6675351.2235080665, 2548071.4397962163 6675384.621173795, 2548114.2713905475 6675401.815120303, 2548130.036255102 6675412.527579122, 2548133.360818376 6675415.518265571,
2548161.7639730913 6675445.2650933275, 2548197.1462358204 6675461.698865353, 2548265.4029021338 6675448.585855539, 2548284.533577645 6675458.298084776, 2548320.2128236936 6675473.841652474, 2548327.4889150267 6675467.790263506, 2548394.1946684485 6675373.758680539)
LINESTRING (2548937.352411589 6676552.259180462, 2548815.5315037514 6676605.441387315, 2548768.484396187 6676625.876077668)
@@ -4125,7 +4125,7 @@ LINESTRING (2550574.0522351246 6672733.982775682, 2550591.8217370873 6672639.351
LINESTRING (2552416.008780264 6676004.983564893, 2552350.466211511 6676058.945950819)
-LINESTRING (2550305.4720701296 6676712.665998463, 2550319.603526426 6676708.114953866, 2550358.986814434 6676710.765562258, 2550374.264956326 6676708.565057178, 2550419.4311695322 6676691.251083121, 2550483.3073318796 6676692.771432085, 2550494.8319345918 6676690.410890272, 2550508.2044335157 6676682.489071986, 2550520.0507681575 6676671.396525926, 2550528.589038599 6676657.773399024,
+LINESTRING (2550305.4720701296 6676712.665998463, 2550319.603526426 6676708.114953866, 2550358.986814434 6676710.765562258, 2550374.264956326 6676708.565057178, 2550419.4311695322 6676691.251083121, 2550483.3073318796 6676692.771432085, 2550494.8319345918 6676690.410890272, 2550508.2044335157 6676682.489071986, 2550520.0507681575 6676671.396525926, 2550528.589038599 6676657.773399024,
2550535.328910049 6676638.418956621, 2550543.784685124 6676559.450831154)
LINESTRING (2552706.5574613805 6672882.976974156, 2552692.5414985977 6673061.627979725)
@@ -4186,7 +4186,7 @@ LINESTRING (2550945.1988893966 6672062.238590978, 2550905.988841658 6672124.8129
LINESTRING (2551820.4664793406 6674029.830210117, 2551774.252574979 6674172.703003552)
-LINESTRING (2552103.912309394 6674035.331472816, 2552115.816390793 6674056.896422595, 2552118.159259204 6674071.259719387, 2552103.541080245 6674163.490889105, 2552103.6483242214 6674198.088830333, 2552109.596240152 6674212.962244211, 2552214.6540894997 6674348.383327263, 2552243.164488192 6674399.625088728, 2552256.8504695087 6674439.934340866, 2552263.9120728886 6674476.642766511,
+LINESTRING (2552103.912309394 6674035.331472816, 2552115.816390793 6674056.896422595, 2552118.159259204 6674071.259719387, 2552103.541080245 6674163.490889105, 2552103.6483242214 6674198.088830333, 2552109.596240152 6674212.962244211, 2552214.6540894997 6674348.383327263, 2552243.164488192 6674399.625088728, 2552256.8504695087 6674439.934340866, 2552263.9120728886 6674476.642766511,
2552262.1714206534 6674516.3718854925, 2552255.5717913266 6674537.866819201)
LINESTRING (2549176.6384719093 6674324.00773236, 2549204.851887282 6674370.64843775, 2549202.0552943544 6674387.532313087, 2549178.5936120977 6674436.473546514, 2549162.54001376 6674500.83832009)
@@ -4257,10 +4257,10 @@ LINESTRING (2547742.1430414137 6672483.21521728, 2547716.033257889 6672484.28546
LINESTRING (2549757.9255734864 6677481.262413552, 2549744.9490523227 6677469.449702193, 2549739.232123418 6677456.1766556455, 2549751.8044172856 6677393.642302204)
-LINESTRING (2553787.7499853973 6675169.691841302, 2553923.867340265 6675169.641829823, 2553945.72861241 6675174.152865237, 2553962.425674607 6675185.365438846, 2554002.2709366684 6675228.945441716, 2554011.444421433 6675235.837023534, 2554028.2899752897 6675236.907269185, 2554040.1528090048 6675232.85633938, 2554053.7892931015 6675222.083866786, 2554176.6496425583 6675114.949276302,
+LINESTRING (2553787.7499853973 6675169.691841302, 2553923.867340265 6675169.641829823, 2553945.72861241 6675174.152865237, 2553962.425674607 6675185.365438846, 2554002.2709366684 6675228.945441716, 2554011.444421433 6675235.837023534, 2554028.2899752897 6675236.907269185, 2554040.1528090048 6675232.85633938, 2554053.7892931015 6675222.083866786, 2554176.6496425583 6675114.949276302,
2554188.5454744203 6675108.357763359, 2554212.931104783 6675112.068615107, 2554239.172880894 6675133.953638352)
-LINESTRING (2548472.3342796788 6677228.03429038, 2548452.221909305 6677348.741996286, 2548434.0894277296 6677375.8282133555, 2548419.2485112804 6677386.240603301, 2548391.010347298 6677396.202889933, 2548355.471343373 6677398.4334019, 2548342.2885837923 6677396.432942737, 2548319.7343505677 6677381.069416364, 2548311.2785754926 6677367.286252729, 2548308.6634723716 6677355.553559737,
+LINESTRING (2548472.3342796788 6677228.03429038, 2548452.221909305 6677348.741996286, 2548434.0894277296 6677375.8282133555, 2548419.2485112804 6677386.240603301, 2548391.010347298 6677396.202889933, 2548355.471343373 6677398.4334019, 2548342.2885837923 6677396.432942737, 2548319.7343505677 6677381.069416364, 2548311.2785754926 6677367.286252729, 2548308.6634723716 6677355.553559737,
2548305.462652148 6677327.097028141, 2548293.6328165797 6677280.036226327)
LINESTRING (2553240.327231804 6672440.575430216, 2553257.577012957 6672503.50987549, 2553265.8842963725 6672521.714053876)
@@ -4289,7 +4289,7 @@ LINESTRING (2551760.913074202 6674391.1331395805, 2551754.717672171 6674389.8428
LINESTRING (2553209.226478601 6675582.396568964, 2553052.246045524 6675578.855756246)
-LINESTRING (2554288.274123086 6677394.042394036, 2554323.4088997156 6677433.221386747, 2554345.5671551805 6677468.3994611325, 2554369.5898059304 6677532.834250779, 2554377.0968842898 6677580.555204117, 2554376.148187574 6677595.79870294, 2554366.7519653197 6677629.8965293765, 2554365.0195626216 6677647.730622817, 2554367.7749078656 6677663.394218065, 2554428.00477501 6677820.860361095,
+LINESTRING (2554288.274123086 6677394.042394036, 2554323.4088997156 6677433.221386747, 2554345.5671551805 6677468.3994611325, 2554369.5898059304 6677532.834250779, 2554377.0968842898 6677580.555204117, 2554376.148187574 6677595.79870294, 2554366.7519653197 6677629.8965293765, 2554365.0195626216 6677647.730622817, 2554367.7749078656 6677663.394218065, 2554428.00477501 6677820.860361095,
2554430.0754087116 6677849.676975341)
LINESTRING (2553517.874643147 6675334.66970849, 2553526.3386677587 6675339.550828849, 2553746.7085405206 6675232.42624066, 2553788.31095389 6675212.56168117)
@@ -4430,7 +4430,7 @@ LINESTRING (2547582.9599820487 6674466.060337538, 2547591.2012691707 6674453.197
LINESTRING (2553530.776918481 6676863.170543605, 2553536.576342752 6676888.54636809, 2553543.2667169822 6676917.793081056, 2553551.4997545676 6676953.7513345145, 2553570.820169422 6677006.193371478, 2553580.340134726 6677032.019299274)
-LINESTRING (2551757.291527609 6676327.267538378, 2551753.7442268454 6676516.801041795, 2551746.872362809 6676550.868861344, 2551731.693215357 6676588.177424737, 2551726.999228998 6676599.710071813, 2551691.509722293 6676652.712237342, 2551682.9632023145 6676821.631009081, 2551662.3063625214 6676893.987617014, 2551653.61960042 6676966.014149185, 2551637.326765519 6677060.915931887,
+LINESTRING (2551757.291527609 6676327.267538378, 2551753.7442268454 6676516.801041795, 2551746.872362809 6676550.868861344, 2551731.693215357 6676588.177424737, 2551726.999228998 6676599.710071813, 2551691.509722293 6676652.712237342, 2551682.9632023145 6676821.631009081, 2551662.3063625214 6676893.987617014, 2551653.61960042 6676966.014149185, 2551637.326765519 6677060.915931887,
2551629.761940403 6677082.770948244, 2551584.183250364 6677169.180781798)
LINESTRING (2553485.148731222 6673735.572669507, 2553381.666543376 6673728.240986674)
@@ -4441,7 +4441,7 @@ LINESTRING (2553302.165758597 6672544.049180432, 2553306.0677894363 6672556.5020
LINESTRING (2551230.715353152 6673946.261028575, 2551201.2315091337 6673936.978898058)
-LINESTRING (2552554.469003542 6673143.706819191, 2552508.7708714856 6673110.496865532, 2552459.211603745 6673074.480929848, 2552330.7745675067 6672982.3197762, 2552261.900555275 6672932.613958296, 2552203.5997103774 6672890.538709792, 2552065.320976905 6672790.54575852, 2551986.7936374517 6672734.5429042475, 2551898.243110958 6672671.248376324, 2551824.970726356 6672617.436024834,
+LINESTRING (2552554.469003542 6673143.706819191, 2552508.7708714856 6673110.496865532, 2552459.211603745 6673074.480929848, 2552330.7745675067 6672982.3197762, 2552261.900555275 6672932.613958296, 2552203.5997103774 6672890.538709792, 2552065.320976905 6672790.54575852, 2551986.7936374517 6672734.5429042475, 2551898.243110958 6672671.248376324, 2551824.970726356 6672617.436024834,
2551800.230365917 6672605.523290517, 2551795.8003647313 6672629.388768334, 2551790.0999349 6672641.201479693, 2551733.574109715 6672719.2894031275, 2551619.8624964124 6672639.221025121, 2551531.089232429 6672581.677817292, 2551522.3364740345 6672575.816471944, 2551503.8905100655 6672563.463636612, 2551487.9111575577 6672562.0333083095)
LINESTRING (2551273.0354762105 6676879.604315631, 2551260.479681416 6676899.398859051, 2551251.314446188 6676921.94403382)
@@ -4766,7 +4766,7 @@ LINESTRING (2553932.7438417096 6677359.32442526, 2553875.4425600786 6677416.4275
LINESTRING (2548826.3961435305 6676796.665278725, 2548822.997334427 6676901.8294169335, 2548791.005631265 6676900.409090928, 2548780.256484999 6676907.05061535, 2548654.855278251 6677031.539189075)
-LINESTRING (2553636.857710374 6677136.563295143, 2553601.5909411586 6677123.940397823, 2553575.456409024 6677123.720347315, 2553552.7619336764 6677113.357968849, 2553538.242749157 6677080.780491377, 2553519.7555375053 6677022.507115954, 2553570.820169422 6677006.193371478, 2553701.558826388 6676964.403779559, 2553684.4162892113 6676981.82777887, 2553659.279951012 6676995.380889701,
+LINESTRING (2553636.857710374 6677136.563295143, 2553601.5909411586 6677123.940397823, 2553575.456409024 6677123.720347315, 2553552.7619336764 6677113.357968849, 2553538.242749157 6677080.780491377, 2553519.7555375053 6677022.507115954, 2553570.820169422 6677006.193371478, 2553701.558826388 6676964.403779559, 2553684.4162892113 6676981.82777887, 2553659.279951012 6676995.380889701,
2553649.0092778723 6677005.473206178, 2553633.293910538 6677032.589430136, 2553627.568732097 6677051.813842694, 2553626.4962923313 6677070.998246069, 2553628.2286950294 6677094.623668786, 2553630.315827804 6677124.7905929675)
LINESTRING (2549184.987003008 6672841.267400604, 2549145.2159867766 6672828.484466551)
@@ -4839,7 +4839,7 @@ LINESTRING (2551374.3892835984 6672043.314247294, 2551364.5310872914 6671947.522
LINESTRING (2553096.81829209 6676021.077258861, 2553171.336356728 6675959.843203875, 2553183.3311830293 6675952.131433801, 2553201.7441488514 6675946.3501068195)
-LINESTRING (2551800.230365917 6672605.523290517, 2551785.174961515 6672603.022716563, 2551761.795774624 6672609.224139969, 2551737.7731238743 6672604.973164247, 2551675.596366078 6672560.723007558, 2551609.583573736 6672512.792006007, 2551592.7710180255 6672511.671748877, 2551562.9076953214 6672521.093911535, 2551507.050082606 6672544.609308998, 2551487.9111575577 6672562.0333083095,
+LINESTRING (2551800.230365917 6672605.523290517, 2551785.174961515 6672603.022716563, 2551761.795774624 6672609.224139969, 2551737.7731238743 6672604.973164247, 2551675.596366078 6672560.723007558, 2551609.583573736 6672512.792006007, 2551592.7710180255 6672511.671748877, 2551562.9076953214 6672521.093911535, 2551507.050082606 6672544.609308998, 2551487.9111575577 6672562.0333083095,
2551420.1329643703 6672640.221254703, 2551414.6140243458 6672657.84529993, 2551395.013125245 6672698.214565843, 2551382.737814697 6672714.818376898, 2551364.7703238544 6672731.342169586, 2551332.7043748624 6672762.019210854, 2551326.104745535 6672791.0058641285, 2551317.2612422374 6672889.818544494)
LINESTRING (2551519.869862573 6672942.42061819, 2551428.9187209117 6672931.848191513)
@@ -5322,7 +5322,7 @@ LINESTRING (2548275.4590873206 6676549.548558296, 2548318.8434006083 6676596.559
LINESTRING (2554280.189577161 6673075.421145655, 2554266.635588431 6673100.146820912)
-LINESTRING (2551912.597304744 6677299.730746788, 2551917.1592985163 6677415.157240504, 2551924.130156993 6677482.70274415, 2551938.0141271893 6677573.793652145, 2551941.0829548263 6677586.416549465, 2551947.6495860065 6677613.392741281, 2551956.550836061 6677631.126811762, 2551968.199181823 6677649.330990147, 2551983.5680686184 6677661.813855326, 2551999.8279053723 6677670.175774627,
+LINESTRING (2551912.597304744 6677299.730746788, 2551917.1592985163 6677415.157240504, 2551924.130156993 6677482.70274415, 2551938.0141271893 6677573.793652145, 2551941.0829548263 6677586.416549465, 2551947.6495860065 6677613.392741281, 2551956.550836061 6677631.126811762, 2551968.199181823 6677649.330990147, 2551983.5680686184 6677661.813855326, 2551999.8279053723 6677670.175774627,
2552016.566215253 6677675.446984523, 2552033.717001966 6677679.347879891, 2552054.5470820293 6677678.557698522, 2552090.440816031 6677666.6749710925, 2552102.732625652 6677655.452395187, 2552123.009986759 6677628.6462424, 2552136.176247266 6677605.070831162)
LINESTRING (2546952.1096642264 6672967.336337067, 2547052.3002869454 6672935.599052443)
@@ -5855,33 +5855,33 @@ LINESTRING (2552089.5251174616 6676457.277379394, 2552060.3300072267 6676568.232
LINESTRING (2552609.3944186154 6675551.299431273, 2552627.8981293407 6675578.555687371, 2552679.7877149233 6675641.640167083)
-LINESTRING (2549044.6953825913 6677254.21029853, 2549022.611372956 6677239.146841031, 2549005.5925788293 6677219.95243536, 2548989.3492411487 6677203.238599052, 2548967.37247549 6677184.804367863, 2548950.23818785 6677173.841851649, 2548923.212705756 6677162.749305589, 2548895.25502602 6677159.888648985, 2548853.2071376713 6677163.419459408, 2548816.1007217807 6677167.030288198,
- 2548774.3415672146 6677162.519252785, 2548855.731495889 6677158.098238034, 2548923.121960853 6677157.91819671, 2548967.8179504694 6677161.789085191, 2549061.2027054452 6677165.359904797, 2549078.5514810383 6677099.384761594, 2549060.1137666064 6677088.8123349175, 2549031.2816359843 6677090.07262419, 2548983.393075681 6677098.46455038, 2548942.013399801 6677113.54801247,
- 2548906.3671518993 6677130.371874033, 2548854.2465792904 6677147.775868752, 2548774.3415672146 6677162.519252785, 2548621.5271501504 6677157.598123243, 2548561.2972830054 6677146.435561113, 2548245.7607553494 6677087.942135181, 2548227.554027944 6677086.711852795, 2548071.703781389 6677086.111715047, 2547917.338451433 6677110.957417854, 2547839.223588812 6677132.572379112,
+LINESTRING (2549044.6953825913 6677254.21029853, 2549022.611372956 6677239.146841031, 2549005.5925788293 6677219.95243536, 2548989.3492411487 6677203.238599052, 2548967.37247549 6677184.804367863, 2548950.23818785 6677173.841851649, 2548923.212705756 6677162.749305589, 2548895.25502602 6677159.888648985, 2548853.2071376713 6677163.419459408, 2548816.1007217807 6677167.030288198,
+ 2548774.3415672146 6677162.519252785, 2548855.731495889 6677158.098238034, 2548923.121960853 6677157.91819671, 2548967.8179504694 6677161.789085191, 2549061.2027054452 6677165.359904797, 2549078.5514810383 6677099.384761594, 2549060.1137666064 6677088.8123349175, 2549031.2816359843 6677090.07262419, 2548983.393075681 6677098.46455038, 2548942.013399801 6677113.54801247,
+ 2548906.3671518993 6677130.371874033, 2548854.2465792904 6677147.775868752, 2548774.3415672146 6677162.519252785, 2548621.5271501504 6677157.598123243, 2548561.2972830054 6677146.435561113, 2548245.7607553494 6677087.942135181, 2548227.554027944 6677086.711852795, 2548071.703781389 6677086.111715047, 2547917.338451433 6677110.957417854, 2547839.223588812 6677132.572379112,
2547608.5335456906 6677220.122474389, 2547152.6888985443 6677394.032391741, 2547130.3904009564 6677402.35430186, 2547035.0257571824 6677437.392344103, 2546989.15833336 6677455.196430655, 2546745.0545436316 6677547.607641699)
-LINESTRING (2551018.1247934587 6672888.988353942, 2551072.6047335523 6672871.274288051, 2551102.270067377 6672869.903973524, 2551317.2612422374 6672889.818544494, 2551321.592248983 6672912.583769771, 2551325.197296503 6672931.528118047, 2551241.192264708 6672922.67608625, 2551065.2048991695 6672911.10342999, 2551041.9824534757 6672913.1939098155, 2551011.1951826657 6672922.7561046155,
- 2550961.2442381973 6672948.942115062, 2550937.0813453244 6672957.334041252, 2550914.815845883 6672972.847602062, 2550869.4433942605 6673004.914962448, 2550737.005332743 6673085.04335423, 2550585.098364711 6673131.2839677865, 2550450.465926442 6673161.500903447, 2550327.5230816184 6673173.463649243, 2550187.660437108 6673162.511135324, 2550058.967665233 6673135.564950396,
- 2549996.1556931143 6673120.591513559, 2549774.5483898534 6673069.78985311, 2549472.961828687 6672995.92289851, 2549214.371852586 6672931.748168554, 2549163.067984106 6672916.744724831, 2549161.253086041 6672916.204600857, 2549140.975724934 6672910.24323255, 2548982.9063530182 6672863.72255471, 2548979.8127767714 6672862.812345791, 2548865.771182002 6672820.342597757,
- 2548836.0316023477 6672809.280058584, 2548832.525549268 6672807.819723395, 2548831.1808747924 6672807.259594829, 2548738.0518554533 6672768.48069395, 2548584.362987503 6672703.2157137515, 2548574.620284709 6672699.644894145, 2548403.161914796 6672636.710448871, 2548393.798690689 6672633.859794564, 2548383.8002522583 6672630.819096636, 2548259.2982450062 6672612.834968759,
- 2548147.4097793056 6672620.4867250575, 2548121.2587480973 6672625.987987757, 2548090.2074921145 6672629.168717826, 2547920.7125119264 6672681.830805297, 2547882.871887273 6672694.0436084885, 2547881.403469748 6672694.513716391, 2547833.382916858 6672710.027277202, 2547685.3779796655 6672758.648437164, 2547673.3171570706 6672763.109461098, 2547663.2857204936 6672766.830315141,
- 2547607.287865655 6672785.594622091, 2547597.809148034 6672788.495287878, 2547570.4371854006 6672796.867209476, 2547532.654307504 6672810.190267503, 2547314.5613068603 6672884.447311641, 2547067.850663547 6672968.146523029, 2547062.1089860327 6672970.096970713, 2547022.6514521944 6672983.550058586, 2546848.379990281 6673049.56521097, 2546831.484939204 6673057.83710961,
+LINESTRING (2551018.1247934587 6672888.988353942, 2551072.6047335523 6672871.274288051, 2551102.270067377 6672869.903973524, 2551317.2612422374 6672889.818544494, 2551321.592248983 6672912.583769771, 2551325.197296503 6672931.528118047, 2551241.192264708 6672922.67608625, 2551065.2048991695 6672911.10342999, 2551041.9824534757 6672913.1939098155, 2551011.1951826657 6672922.7561046155,
+ 2550961.2442381973 6672948.942115062, 2550937.0813453244 6672957.334041252, 2550914.815845883 6672972.847602062, 2550869.4433942605 6673004.914962448, 2550737.005332743 6673085.04335423, 2550585.098364711 6673131.2839677865, 2550450.465926442 6673161.500903447, 2550327.5230816184 6673173.463649243, 2550187.660437108 6673162.511135324, 2550058.967665233 6673135.564950396,
+ 2549996.1556931143 6673120.591513559, 2549774.5483898534 6673069.78985311, 2549472.961828687 6672995.92289851, 2549214.371852586 6672931.748168554, 2549163.067984106 6672916.744724831, 2549161.253086041 6672916.204600857, 2549140.975724934 6672910.24323255, 2548982.9063530182 6672863.72255471, 2548979.8127767714 6672862.812345791, 2548865.771182002 6672820.342597757,
+ 2548836.0316023477 6672809.280058584, 2548832.525549268 6672807.819723395, 2548831.1808747924 6672807.259594829, 2548738.0518554533 6672768.48069395, 2548584.362987503 6672703.2157137515, 2548574.620284709 6672699.644894145, 2548403.161914796 6672636.710448871, 2548393.798690689 6672633.859794564, 2548383.8002522583 6672630.819096636, 2548259.2982450062 6672612.834968759,
+ 2548147.4097793056 6672620.4867250575, 2548121.2587480973 6672625.987987757, 2548090.2074921145 6672629.168717826, 2547920.7125119264 6672681.830805297, 2547882.871887273 6672694.0436084885, 2547881.403469748 6672694.513716391, 2547833.382916858 6672710.027277202, 2547685.3779796655 6672758.648437164, 2547673.3171570706 6672763.109461098, 2547663.2857204936 6672766.830315141,
+ 2547607.287865655 6672785.594622091, 2547597.809148034 6672788.495287878, 2547570.4371854006 6672796.867209476, 2547532.654307504 6672810.190267503, 2547314.5613068603 6672884.447311641, 2547067.850663547 6672968.146523029, 2547062.1089860327 6672970.096970713, 2547022.6514521944 6672983.550058586, 2546848.379990281 6673049.56521097, 2546831.484939204 6673057.83710961,
2546816.7595162685 6673065.048764894)
-LINESTRING (2550184.0718886615 6676346.001838442, 2550178.858181493 6676383.270392652, 2550180.2771017984 6676468.249897904, 2550177.3732648944 6676527.243438627, 2550175.8718492226 6676545.997743282, 2550174.3951821607 6676564.371960695, 2550164.2812502175 6676695.402035885, 2550143.2531812745 6676741.2425576085, 2550075.136757084 6676897.898514678, 2550071.4079665146 6676906.480484488,
- 2550063.5791562255 6676933.906779615, 2550055.882338523 6676982.537941873, 2550043.483284925 6677192.91622977, 2550037.131141698 6677349.362138627, 2550035.6709737093 6677366.696117276, 2550031.117229474 6677442.883604506, 2550033.0971182715 6677584.066009948, 2550031.5049576964 6677619.0840476, 2550029.3765772386 6677630.906761254, 2550023.1976742814 6677665.124615241,
+LINESTRING (2550184.0718886615 6676346.001838442, 2550178.858181493 6676383.270392652, 2550180.2771017984 6676468.249897904, 2550177.3732648944 6676527.243438627, 2550175.8718492226 6676545.997743282, 2550174.3951821607 6676564.371960695, 2550164.2812502175 6676695.402035885, 2550143.2531812745 6676741.2425576085, 2550075.136757084 6676897.898514678, 2550071.4079665146 6676906.480484488,
+ 2550063.5791562255 6676933.906779615, 2550055.882338523 6676982.537941873, 2550043.483284925 6677192.91622977, 2550037.131141698 6677349.362138627, 2550035.6709737093 6677366.696117276, 2550031.117229474 6677442.883604506, 2550033.0971182715 6677584.066009948, 2550031.5049576964 6677619.0840476, 2550029.3765772386 6677630.906761254, 2550023.1976742814 6677665.124615241,
2550019.0399078056 6677686.849601753, 2550021.143539653 6677692.1808254225, 2550022.8016965217 6677696.371787369, 2550035.6874727826 6677729.009278617, 2550035.695722319 6677810.307939009)
-LINESTRING (2553675.4737914735 6675736.161862543, 2553667.5707353544 6675743.563561447, 2553636.0575053184 6675773.070334104, 2553569.1702620904 6675865.6115749935, 2553545.0156187536 6675913.912661488, 2553506.539779778 6675989.219946686, 2553485.651952958 6676036.060697992, 2553474.5315775424 6676055.495158763, 2553471.5039975885 6676060.786373249, 2553457.2570477794 6676073.959396839,
- 2553438.2088676346 6676092.903745115, 2553403.569063205 6676127.341649609, 2553366.2564088977 6676164.4401647905, 2553330.758652656 6676200.098349375, 2553295.4341366836 6676235.586494929, 2553280.9561998476 6676250.11983075, 2553266.857741698 6676263.442888777, 2553263.0299566886 6676267.053717567, 2553258.8721902124 6676270.974617526, 2553213.62348164 6676312.414129091,
- 2553169.5132091264 6676352.803399596, 2553108.3923920225 6676400.944449359, 2553067.763423979 6676432.941793674, 2553014.4384190175 6676475.401539412, 2552967.5068049664 6676512.910148722, 2552964.231738913 6676515.460734155, 2552800.0082126497 6676643.68016422, 2552747.194678961 6676689.470674465, 2552732.5187532455 6676700.013094256, 2552601.0293884436 6676876.613629182,
- 2552588.5065917955 6676903.429784264, 2552580.1250625504 6676934.786981648, 2552578.9866264914 6676950.380560825, 2552592.647859198 6677083.961221446, 2552604.74167994 6677178.863004148, 2552602.341064772 6677277.905737318, 2552604.881922063 6677633.767417857, 2552605.1294081626 6677756.13550487, 2552605.154156773 6677770.558815436, 2552599.9651982146 6677798.575246017,
+LINESTRING (2553675.4737914735 6675736.161862543, 2553667.5707353544 6675743.563561447, 2553636.0575053184 6675773.070334104, 2553569.1702620904 6675865.6115749935, 2553545.0156187536 6675913.912661488, 2553506.539779778 6675989.219946686, 2553485.651952958 6676036.060697992, 2553474.5315775424 6676055.495158763, 2553471.5039975885 6676060.786373249, 2553457.2570477794 6676073.959396839,
+ 2553438.2088676346 6676092.903745115, 2553403.569063205 6676127.341649609, 2553366.2564088977 6676164.4401647905, 2553330.758652656 6676200.098349375, 2553295.4341366836 6676235.586494929, 2553280.9561998476 6676250.11983075, 2553266.857741698 6676263.442888777, 2553263.0299566886 6676267.053717567, 2553258.8721902124 6676270.974617526, 2553213.62348164 6676312.414129091,
+ 2553169.5132091264 6676352.803399596, 2553108.3923920225 6676400.944449359, 2553067.763423979 6676432.941793674, 2553014.4384190175 6676475.401539412, 2552967.5068049664 6676512.910148722, 2552964.231738913 6676515.460734155, 2552800.0082126497 6676643.68016422, 2552747.194678961 6676689.470674465, 2552732.5187532455 6676700.013094256, 2552601.0293884436 6676876.613629182,
+ 2552588.5065917955 6676903.429784264, 2552580.1250625504 6676934.786981648, 2552578.9866264914 6676950.380560825, 2552592.647859198 6677083.961221446, 2552604.74167994 6677178.863004148, 2552602.341064772 6677277.905737318, 2552604.881922063 6677633.767417857, 2552605.1294081626 6677756.13550487, 2552605.154156773 6677770.558815436, 2552599.9651982146 6677798.575246017,
2552592.4416207816 6677831.402780885, 2552588.836573262 6677847.116387612, 2552561.2501226757 6677966.763850162)
-LINESTRING (2553644.7360178833 6677147.805875639, 2553666.4900460523 6677180.123293421, 2553675.4572924 6677195.976932289, 2553711.1447879854 6677259.091418888, 2553727.5943640824 6677300.7809878485, 2553750.1980945272 6677358.084140578, 2553789.837118172 6677473.050528687, 2553823.915954109 6677589.587277238, 2553855.2229457283 6677741.772208078, 2553875.120828149 6677877.7434174,
+LINESTRING (2553644.7360178833 6677147.805875639, 2553666.4900460523 6677180.123293421, 2553675.4572924 6677195.976932289, 2553711.1447879854 6677259.091418888, 2553727.5943640824 6677300.7809878485, 2553750.1980945272 6677358.084140578, 2553789.837118172 6677473.050528687, 2553823.915954109 6677589.587277238, 2553855.2229457283 6677741.772208078, 2553875.120828149 6677877.7434174,
2553886.628931788 6677968.024139435, 2553888.5098261456 6678057.214611226)
-LINESTRING (2554173.8860477777 6675504.448677671, 2554289.198071192 6675483.313826611, 2554368.5503643113 6675468.740481608, 2554388.472995342 6675467.460187743, 2554414.9292594064 6675465.779802047, 2554417.577360674 6675465.189666593, 2554451.491205877 6675457.627930956, 2554586.420627466 6675429.461465939, 2554623.0238216203 6675421.849718823, 2554651.063996723 6675416.008378066,
+LINESTRING (2554173.8860477777 6675504.448677671, 2554289.198071192 6675483.313826611, 2554368.5503643113 6675468.740481608, 2554388.472995342 6675467.460187743, 2554414.9292594064 6675465.779802047, 2554417.577360674 6675465.189666593, 2554451.491205877 6675457.627930956, 2554586.420627466 6675429.461465939, 2554623.0238216203 6675421.849718823, 2554651.063996723 6675416.008378066,
2554673.997708634 6675411.237282962, 2554938.444855763 6675356.194649086, 2555013.4413935267 6675337.160280149, 2555039.9719034205 6675335.669938073)
-LINESTRING (2553224.356128833 6671841.2578695165, 2553245.0954639926 6671840.097603202, 2553284.3385098777 6671818.292598323, 2553364.416762223 6671759.249046122, 2553385.3128385795 6671743.845510565, 2553534.835690517 6671645.212871524)
\ No newline at end of file
+LINESTRING (2553224.356128833 6671841.2578695165, 2553245.0954639926 6671840.097603202, 2553284.3385098777 6671818.292598323, 2553364.416762223 6671759.249046122, 2553385.3128385795 6671743.845510565, 2553534.835690517 6671645.212871524)
diff --git a/data/Manhattan/bus.wkt b/data/Manhattan/bus.wkt
index 08a4b117d..d490d506f 100644
--- a/data/Manhattan/bus.wkt
+++ b/data/Manhattan/bus.wkt
@@ -1,2 +1,2 @@
-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,
- 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)
\ No newline at end of file
+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,
+ 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)
diff --git a/data/Manhattan/roads.wkt b/data/Manhattan/roads.wkt
index 0cee4380e..dec41cf3c 100644
--- a/data/Manhattan/roads.wkt
+++ b/data/Manhattan/roads.wkt
@@ -2556,4 +2556,4 @@ LINESTRING (2553824.5457668966 6672320.971424899, 2554011.040566236 6672320.5578
LINESTRING (2553650.572917482 6673717.766253239, 2553835.051093514 6673718.179865022)
-LINESTRING (2548575.1428826493 6673019.575644961, 2548761.6376819885 6673019.162033177, 2548761.637681989 6673187.827794121, 2548577.7341701165 6673187.827794121, 2548575.1428826493 6673019.575644961)
\ No newline at end of file
+LINESTRING (2548575.1428826493 6673019.575644961, 2548761.6376819885 6673019.162033177, 2548761.637681989 6673187.827794121, 2548577.7341701165 6673187.827794121, 2548575.1428826493 6673019.575644961)
diff --git a/data/ParkPOIs.wkt b/data/ParkPOIs.wkt
index 32d6a09c0..ba940acd5 100644
--- a/data/ParkPOIs.wkt
+++ b/data/ParkPOIs.wkt
@@ -18,4 +18,4 @@ POINT (2552785.543273026 6673249.298489128)
POINT (2552729.0506920097 6673245.719605062)
-POINT (2552841.676618883 6673253.251878758)
\ No newline at end of file
+POINT (2552841.676618883 6673253.251878758)
diff --git a/data/WestPOIs.wkt b/data/WestPOIs.wkt
index 692cdf74e..1c5977d06 100644
--- a/data/WestPOIs.wkt
+++ b/data/WestPOIs.wkt
@@ -2,4 +2,4 @@ POINT (2550854.3137440286 6672591.750129179)
POINT (2551121.9534618445 6672693.903576347)
-POINT (2550700.913609861 6672866.723243455)
\ No newline at end of file
+POINT (2550700.913609861 6672866.723243455)
diff --git a/data/cluster/ferryroute.wkt b/data/cluster/ferryroute.wkt
index cae1f0c3b..f1d0375ac 100644
--- a/data/cluster/ferryroute.wkt
+++ b/data/cluster/ferryroute.wkt
@@ -1 +1 @@
-LINESTRING (100 -100, 600 -100, 350 -533, 100 -100)
\ No newline at end of file
+LINESTRING (100 -100, 600 -100, 350 -533, 100 -100)
diff --git a/data/cluster/origin.wkt b/data/cluster/origin.wkt
index a6612600b..d57e885f2 100644
--- a/data/cluster/origin.wkt
+++ b/data/cluster/origin.wkt
@@ -1 +1 @@
-LINESTRING (0 0, 100 -100)
\ No newline at end of file
+LINESTRING (0 0, 100 -100)
diff --git a/data/demo_bus.wkt b/data/demo_bus.wkt
index c306066a4..81aa07881 100644
--- a/data/demo_bus.wkt
+++ b/data/demo_bus.wkt
@@ -1,2 +1,2 @@
-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,
- 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)
\ No newline at end of file
+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,
+ 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)
diff --git a/data/main_roads.wkt b/data/main_roads.wkt
index c06fc8a9f..5cbc05e3c 100644
--- a/data/main_roads.wkt
+++ b/data/main_roads.wkt
@@ -1,21 +1,21 @@
-MULTILINESTRING ((2551018.1247934587 6672888.988353942, 2551072.6047335523 6672871.274288051, 2551102.270067377 6672869.903973524, 2551317.2612422374 6672889.818544494),
- (2551317.2612422374 6672889.818544494, 2551321.592248983 6672912.583769771, 2551325.197296503 6672931.528118047, 2551241.192264708 6672922.67608625, 2551065.2048991695 6672911.10342999, 2551041.9824534757 6672913.1939098155, 2551011.1951826657 6672922.7561046155, 2550961.2442381973 6672948.942115062, 2550937.0813453244 6672957.334041252, 2550914.815845883 6672972.847602062,
- 2550869.4433942605 6673004.914962448, 2550737.005332743 6673085.04335423, 2550585.098364711 6673131.2839677865),
- (2550585.098364711 6673131.2839677865, 2550450.465926442 6673161.500903447, 2550327.5230816184 6673173.463649243, 2550187.660437108 6673162.511135324, 2550186.3236131626 6673162.231226012),
- (2552554.469003542 6673143.706819191, 2552508.7708714856 6673110.496865532, 2552459.211603745 6673074.480929848, 2552330.7745675067 6672982.3197762, 2552261.900555275 6672932.613958296, 2552203.5997103774 6672890.538709792, 2552065.320976905 6672790.54575852, 2551986.7936374517 6672734.5429042475, 2551898.243110958 6672671.248376324, 2551824.970726356 6672617.436024834,
- 2551800.230365917 6672605.523290517),
- (2551800.230365917 6672605.523290517, 2551795.8003647313 6672629.388768334, 2551790.0999349 6672641.201479693, 2551733.574109715 6672719.2894031275, 2551619.8624964124 6672639.221025121, 2551531.089232429 6672581.677817292, 2551522.3364740345 6672575.816471944, 2551503.8905100655 6672563.463636612, 2551487.9111575577 6672562.0333083095),
- (2551006.2619597437 6672888.91833787, 2550832.7989524226 6672878.625975476, 2550815.9781471756 6672914.404187609, 2550792.821697775 6672954.823465002, 2550728.731047474 6673032.95139762, 2550585.098364711 6673131.2839677865),
- (2551800.230365917 6672605.523290517, 2551785.174961515 6672603.022716563, 2551761.795774624 6672609.224139969, 2551737.7731238743 6672604.973164247, 2551675.596366078 6672560.723007558, 2551609.583573736 6672512.792006007, 2551592.7710180255 6672511.671748877, 2551562.9076953214 6672521.093911535, 2551507.050082606 6672544.609308998, 2551487.9111575577 6672562.0333083095),
+MULTILINESTRING ((2551018.1247934587 6672888.988353942, 2551072.6047335523 6672871.274288051, 2551102.270067377 6672869.903973524, 2551317.2612422374 6672889.818544494),
+ (2551317.2612422374 6672889.818544494, 2551321.592248983 6672912.583769771, 2551325.197296503 6672931.528118047, 2551241.192264708 6672922.67608625, 2551065.2048991695 6672911.10342999, 2551041.9824534757 6672913.1939098155, 2551011.1951826657 6672922.7561046155, 2550961.2442381973 6672948.942115062, 2550937.0813453244 6672957.334041252, 2550914.815845883 6672972.847602062,
+ 2550869.4433942605 6673004.914962448, 2550737.005332743 6673085.04335423, 2550585.098364711 6673131.2839677865),
+ (2550585.098364711 6673131.2839677865, 2550450.465926442 6673161.500903447, 2550327.5230816184 6673173.463649243, 2550187.660437108 6673162.511135324, 2550186.3236131626 6673162.231226012),
+ (2552554.469003542 6673143.706819191, 2552508.7708714856 6673110.496865532, 2552459.211603745 6673074.480929848, 2552330.7745675067 6672982.3197762, 2552261.900555275 6672932.613958296, 2552203.5997103774 6672890.538709792, 2552065.320976905 6672790.54575852, 2551986.7936374517 6672734.5429042475, 2551898.243110958 6672671.248376324, 2551824.970726356 6672617.436024834,
+ 2551800.230365917 6672605.523290517),
+ (2551800.230365917 6672605.523290517, 2551795.8003647313 6672629.388768334, 2551790.0999349 6672641.201479693, 2551733.574109715 6672719.2894031275, 2551619.8624964124 6672639.221025121, 2551531.089232429 6672581.677817292, 2551522.3364740345 6672575.816471944, 2551503.8905100655 6672563.463636612, 2551487.9111575577 6672562.0333083095),
+ (2551006.2619597437 6672888.91833787, 2550832.7989524226 6672878.625975476, 2550815.9781471756 6672914.404187609, 2550792.821697775 6672954.823465002, 2550728.731047474 6673032.95139762, 2550585.098364711 6673131.2839677865),
+ (2551800.230365917 6672605.523290517, 2551785.174961515 6672603.022716563, 2551761.795774624 6672609.224139969, 2551737.7731238743 6672604.973164247, 2551675.596366078 6672560.723007558, 2551609.583573736 6672512.792006007, 2551592.7710180255 6672511.671748877, 2551562.9076953214 6672521.093911535, 2551507.050082606 6672544.609308998, 2551487.9111575577 6672562.0333083095),
(2551487.9111575577 6672562.0333083095, 2551420.1329643703 6672640.221254703, 2551414.6140243458 6672657.84529993, 2551395.013125245 6672698.214565843, 2551382.737814697 6672714.818376898, 2551364.7703238544 6672731.342169586, 2551332.7043748624 6672762.019210854, 2551326.104745535 6672791.0058641285, 2551317.2612422374 6672889.818544494))
-LINESTRING (2552559.517719977 6673146.45745054, 2552473.318311431 6673253.912114491, 2552440.104393391 6673297.548247428, 2552408.7574375407 6673338.7315830095, 2552398.0412894213 6673352.814815518, 2552387.0611561285 6673365.997841404, 2552275.9398973365 6673509.820852942, 2552256.454491749 6673534.296470803, 2552195.9111422114 6673612.1843483215, 2552172.432960881 6673639.590638857,
- 2552153.657015446 6673654.484057328, 2552149.2847610167 6673657.954853976, 2552146.0756912567 6673660.495437113, 2552144.1535492153 6673662.015786077, 2552140.721741965 6673665.156506963, 2552137.4466759115 6673668.147193412, 2552124.4206575276 6673683.880804731, 2552092.0164775327 6673747.715456628, 2552068.1670670523 6673793.766026565, 2552022.431635817 6673885.937182508,
+LINESTRING (2552559.517719977 6673146.45745054, 2552473.318311431 6673253.912114491, 2552440.104393391 6673297.548247428, 2552408.7574375407 6673338.7315830095, 2552398.0412894213 6673352.814815518, 2552387.0611561285 6673365.997841404, 2552275.9398973365 6673509.820852942, 2552256.454491749 6673534.296470803, 2552195.9111422114 6673612.1843483215, 2552172.432960881 6673639.590638857,
+ 2552153.657015446 6673654.484057328, 2552149.2847610167 6673657.954853976, 2552146.0756912567 6673660.495437113, 2552144.1535492153 6673662.015786077, 2552140.721741965 6673665.156506963, 2552137.4466759115 6673668.147193412, 2552124.4206575276 6673683.880804731, 2552092.0164775327 6673747.715456628, 2552068.1670670523 6673793.766026565, 2552022.431635817 6673885.937182508,
2551970.2203183044 6673991.151332197, 2551943.3598269443 6674056.316289438, 2551910.081196063 6674119.950895418, 2551906.723634643 6674125.11208006, 2551861.5739205102 6674198.388899207, 2551849.810081235 6674219.603768633, 2551800.86558024 6674295.731242088, 2551770.499035799 6674351.273990754, 2551761.5729668215 6674388.38925647)
-LINESTRING (2552565.003661855 6673149.448136989, 2552576.849996497 6673154.089202248, 2552643.456755479 6673204.110683623, 2552681.874847698 6673207.531468792, 2552788.4341127174 6673214.002954185, 2552892.741254229 6673220.99455896, 2552983.1231778613 6673226.425805588, 2552993.2701079515 6673230.756799676, 2553050.2414081157 6673236.108027938, 2553055.265375941 6673247.010530378,
- 2553055.669603237 6673293.861283979, 2553119.9004956614 6673301.242978292, 2553205.6544292276 6673309.334835607, 2553290.806146618 6673314.916116672, 2553304.1373978583 6673315.44623835, 2553311.495984558 6673318.586959236, 2553315.5877547404 6673324.248258668, 2553324.134274719 6673336.040965435, 2553344.139401116 6673364.037391424, 2553379.109187012 6673412.298468736,
- 2553382.615240092 6673431.512878998, 2553383.2587039513 6673452.957801227, 2553384.355892327 6673489.416169477, 2553390.7657823106 6673499.708531871, 2553398.388354183 6673503.7994708605, 2553399.287553679 6673503.929500706, 2553433.0446576863 6673508.920646318, 2553438.126372268 6673509.670818504, 2553443.909297466 6673513.061596786, 2553451.424625362 6673526.524686954,
- 2553479.8277800772 6673656.594541744, 2553493.3322715876 6673718.438736775, 2553545.51884049 6673950.411981339, 2553561.6796828043 6674022.26847448, 2553559.7905389094 6674043.833424259, 2553548.8516533 6674160.680243981, 2553547.647220948 6674163.500891401, 2553538.020011667 6674185.976050099, 2553503.4132053843 6674218.46350691, 2553481.741672582 6674232.366698094,
- 2553470.2088203332 6674233.837035579, 2553446.1614209735 6674233.516962113, 2553433.2838942492 6674233.7470149165, 2553381.4190572766 6674234.637219245, 2553366.974118587 6674236.167570504, 2553355.1937802387 6674240.948667904, 2553331.1958780987 6674260.173080462, 2553328.6632703445 6674268.35495844, 2553317.6418893686 6674303.933124657, 2553310.6380327456 6674361.746394473,
- 2553308.7473131865 6674388.38925647)
\ No newline at end of file
+LINESTRING (2552565.003661855 6673149.448136989, 2552576.849996497 6673154.089202248, 2552643.456755479 6673204.110683623, 2552681.874847698 6673207.531468792, 2552788.4341127174 6673214.002954185, 2552892.741254229 6673220.99455896, 2552983.1231778613 6673226.425805588, 2552993.2701079515 6673230.756799676, 2553050.2414081157 6673236.108027938, 2553055.265375941 6673247.010530378,
+ 2553055.669603237 6673293.861283979, 2553119.9004956614 6673301.242978292, 2553205.6544292276 6673309.334835607, 2553290.806146618 6673314.916116672, 2553304.1373978583 6673315.44623835, 2553311.495984558 6673318.586959236, 2553315.5877547404 6673324.248258668, 2553324.134274719 6673336.040965435, 2553344.139401116 6673364.037391424, 2553379.109187012 6673412.298468736,
+ 2553382.615240092 6673431.512878998, 2553383.2587039513 6673452.957801227, 2553384.355892327 6673489.416169477, 2553390.7657823106 6673499.708531871, 2553398.388354183 6673503.7994708605, 2553399.287553679 6673503.929500706, 2553433.0446576863 6673508.920646318, 2553438.126372268 6673509.670818504, 2553443.909297466 6673513.061596786, 2553451.424625362 6673526.524686954,
+ 2553479.8277800772 6673656.594541744, 2553493.3322715876 6673718.438736775, 2553545.51884049 6673950.411981339, 2553561.6796828043 6674022.26847448, 2553559.7905389094 6674043.833424259, 2553548.8516533 6674160.680243981, 2553547.647220948 6674163.500891401, 2553538.020011667 6674185.976050099, 2553503.4132053843 6674218.46350691, 2553481.741672582 6674232.366698094,
+ 2553470.2088203332 6674233.837035579, 2553446.1614209735 6674233.516962113, 2553433.2838942492 6674233.7470149165, 2553381.4190572766 6674234.637219245, 2553366.974118587 6674236.167570504, 2553355.1937802387 6674240.948667904, 2553331.1958780987 6674260.173080462, 2553328.6632703445 6674268.35495844, 2553317.6418893686 6674303.933124657, 2553310.6380327456 6674361.746394473,
+ 2553308.7473131865 6674388.38925647)
diff --git a/data/pedestrian_paths.wkt b/data/pedestrian_paths.wkt
index 9295e86c0..997c85e8e 100644
--- a/data/pedestrian_paths.wkt
+++ b/data/pedestrian_paths.wkt
@@ -28,4 +28,4 @@ LINESTRING (2553171.039373408 6672675.199283171, 2553072.3655058085 6672628.6252
LINESTRING (2552924.1307412153 6672763.979660833, 2552946.75055431 6672726.8954462055, 2552980.076970014 6672720.913781848, 2553015.3458680497 6672745.815491632)
-LINESTRING (2552990.331251769 6672620.934534737, 2552980.076970014 6672720.913781848)
\ No newline at end of file
+LINESTRING (2552990.331251769 6672620.934534737, 2552980.076970014 6672720.913781848)
diff --git a/data/roads.wkt b/data/roads.wkt
index f1da873fc..4aa7becb0 100644
--- a/data/roads.wkt
+++ b/data/roads.wkt
@@ -18,7 +18,7 @@ LINESTRING (2551086.298964406 6671839.64749989, 2551006.228961597 6671778.523470
LINESTRING (2551596.433812302 6671064.409560379, 2551481.427021744 6671124.963459249)
-LINESTRING (2551481.427021744 6671124.963459249, 2551445.178557666 6671054.67732655, 2551435.180119236 6671046.105359036, 2551419.3410088513 6671039.603866755, 2551404.846572942 6671040.844151436, 2551386.400608973 6671047.835756212, 2551312.4600119023 6671088.845169057, 2551297.338611207 6671100.237783992, 2551288.8415884483 6671108.17960687, 2551285.1210474153 6671126.433796734,
+LINESTRING (2551481.427021744 6671124.963459249, 2551445.178557666 6671054.67732655, 2551435.180119236 6671046.105359036, 2551419.3410088513 6671039.603866755, 2551404.846572942 6671040.844151436, 2551386.400608973 6671047.835756212, 2551312.4600119023 6671088.845169057, 2551297.338611207 6671100.237783992, 2551288.8415884483 6671108.17960687, 2551285.1210474153 6671126.433796734,
2551335.657708986 6671225.196465621, 2551491.2522199047 6671144.017832778)
LINESTRING (2551491.2522199047 6671144.017832778, 2551481.427021744 6671124.963459249)
@@ -27,7 +27,7 @@ LINESTRING (2551618.7735575736 6671352.915780894, 2551528.9278538246 6671397.786
LINESTRING (2551528.9278538246 6671397.786079925, 2551436.2773076114 6671444.056700369)
-LINESTRING (2551906.43490086 6671776.923102828, 2551921.572800629 6671722.220547011, 2551916.697324463 6671708.97750735, 2551897.690392002 6671693.523960315, 2551873.7749852287 6671666.857839669, 2551855.8652411425 6671639.501560613, 2551795.7261189013 6671523.915030164, 2551805.782304088 6671476.494145701, 2551804.5366240526 6671466.011739685, 2551679.473648308 6671222.705893962,
+LINESTRING (2551906.43490086 6671776.923102828, 2551921.572800629 6671722.220547011, 2551916.697324463 6671708.97750735, 2551897.690392002 6671693.523960315, 2551873.7749852287 6671666.857839669, 2551855.8652411425 6671639.501560613, 2551795.7261189013 6671523.915030164, 2551805.782304088 6671476.494145701, 2551804.5366240526 6671466.011739685, 2551679.473648308 6671222.705893962,
2551671.422100529 6671215.784305258, 2551660.813196386 6671215.63427082, 2551571.1077347603 6671261.264744333, 2551561.926000459 6671263.085162171, 2551553.84970407 6671260.544579034, 2551547.093333547 6671252.882820439, 2551491.2522199047 6671144.017832778)
LINESTRING (2551626.5116229593 6671587.909718794, 2551528.9278538246 6671397.786079925)
@@ -198,7 +198,7 @@ LINESTRING (2552909.710551136 6672140.6265832875, 2552883.7245106613 6672239.799
LINESTRING (2552883.7245106613 6672239.799346303, 2552708.001130296 6672220.484913082)
-LINESTRING (2553258.6824508696 6671752.257441346, 2553307.899186575 6671743.005317716, 2553327.4588379925 6671743.275379703, 2553356.2414713944 6671753.047622715, 2553364.416762223 6671759.249046122, 2553372.229073439 6671765.190409836, 2553384.3393932534 6671781.114064775, 2553425.45508396 6671872.695085266, 2553439.4132999866 6671885.367994064, 2553475.3317825985 6671896.300503392,
+LINESTRING (2553258.6824508696 6671752.257441346, 2553307.899186575 6671743.005317716, 2553327.4588379925 6671743.275379703, 2553356.2414713944 6671753.047622715, 2553364.416762223 6671759.249046122, 2553372.229073439 6671765.190409836, 2553384.3393932534 6671781.114064775, 2553425.45508396 6671872.695085266, 2553439.4132999866 6671885.367994064, 2553475.3317825985 6671896.300503392,
2553498.7274685623 6671899.161159995, 2553558.3551195306 6671918.175524341, 2553586.8572686864 6671931.4285662975)
LINESTRING (2553477.5591574963 6672131.244429813, 2553501.581808246 6672095.446213087, 2553524.688760427 6672067.959904185, 2553578.236502878 6672029.551088251, 2553588.5484237014 6672013.887493004, 2553596.9794501667 6671997.5837508235, 2553598.4066200084 6671985.601000437, 2553597.391926999 6671967.896936842, 2553586.8572686864 6671931.4285662975)
@@ -1719,7 +1719,7 @@ LINESTRING (2551590.560142201 6673751.856407096, 2551590.659136641 6673766.41974
LINESTRING (2551840.6200973974 6673766.099676338, 2551813.8668500134 6673803.158182336)
-LINESTRING (2552118.0437656906 6673737.923209025, 2552177.8364073923 6673801.157723173, 2552199.0789642883 6673818.001589327, 2552221.748691026 6673826.953644082, 2552240.5658841445 6673806.108859601, 2552297.924912532 6673716.958396994, 2552318.0207838323 6673714.7078804355, 2552341.8371961657 6673705.855848638, 2552354.4919854 6673692.762843415, 2552359.6396962753 6673678.47956499,
+LINESTRING (2552118.0437656906 6673737.923209025, 2552177.8364073923 6673801.157723173, 2552199.0789642883 6673818.001589327, 2552221.748691026 6673826.953644082, 2552240.5658841445 6673806.108859601, 2552297.924912532 6673716.958396994, 2552318.0207838323 6673714.7078804355, 2552341.8371961657 6673705.855848638, 2552354.4919854 6673692.762843415, 2552359.6396962753 6673678.47956499,
2552359.0127314893 6673658.444966471)
LINESTRING (2552622.8329138323 6673749.445853804, 2552599.197991305 6673743.634519935)
@@ -1748,7 +1748,7 @@ LINESTRING (2550933.6990352944 6673730.841583586, 2550817.034087868 6673801.0276
LINESTRING (2550817.034087868 6673801.027693327, 2550802.3251640056 6673777.652328005)
-LINESTRING (2550933.6990352944 6673730.841583586, 2550952.3512376794 6673762.378822294, 2550956.591499522 6673790.235216142, 2550954.025893621 6673808.149327948, 2550946.8735453384 6673823.68289335, 2550935.695423166 6673836.845914644, 2550919.9223090746 6673848.198520395, 2550889.720755367 6673857.050552192, 2550856.8546013194 6673849.638850993, 2550839.654317386 6673838.396270496,
+LINESTRING (2550933.6990352944 6673730.841583586, 2550952.3512376794 6673762.378822294, 2550956.591499522 6673790.235216142, 2550954.025893621 6673808.149327948, 2550946.8735453384 6673823.68289335, 2550935.695423166 6673836.845914644, 2550919.9223090746 6673848.198520395, 2550889.720755367 6673857.050552192, 2550856.8546013194 6673849.638850993, 2550839.654317386 6673838.396270496,
2550818.6674961266 6673809.159559825, 2550817.034087868 6673801.027693327)
LINESTRING (2551219.034009243 6673822.6826637685, 2551179.254743475 6673814.2407261, 2551136.8603745867 6673805.238659865)
@@ -1801,7 +1801,7 @@ LINESTRING (2551458.163328367 6673872.90419106, 2551403.881377153 6673861.881661
LINESTRING (2551731.78396026 6673845.057799509, 2551679.712884871 6673895.7394324085)
-LINESTRING (2551010.510471123 6674129.593108585, 2551015.4271949716 6674107.267984324, 2551014.2392616924 6674078.951484869, 2551005.090525538 6674055.06600246, 2550970.731205355 6674013.506463345, 2550957.655689751 6673913.943610793, 2550959.4458392058 6673875.394762719, 2550972.37286315 6673819.982043899, 2550981.414355328 6673794.056093143, 2551025.4503820115 6673705.495765989,
+LINESTRING (2551010.510471123 6674129.593108585, 2551015.4271949716 6674107.267984324, 2551014.2392616924 6674078.951484869, 2551005.090525538 6674055.06600246, 2550970.731205355 6674013.506463345, 2550957.655689751 6673913.943610793, 2550959.4458392058 6673875.394762719, 2550972.37286315 6673819.982043899, 2550981.414355328 6673794.056093143, 2551025.4503820115 6673705.495765989,
2551039.1363633284 6673648.872769374)
LINESTRING (2551189.6904073483 6673933.678140438, 2551121.846217868 6673914.833815121)
@@ -1814,7 +1814,7 @@ LINESTRING (2551201.2315091337 6673936.978898058, 2551195.696070036 6673935.3985
LINESTRING (2551197.78320281 6673927.316680299, 2551221.475872094 6673934.808399865, 2551230.715353152 6673946.261028575)
-LINESTRING (2550674.9523179964 6674116.500103362, 2550664.4836559766 6674113.329375588, 2550650.0139686773 6674100.476425465, 2550640.1475228337 6674080.841918779, 2550633.943871266 6674042.0630179, 2550645.8562022015 6673991.161334492, 2550645.410727222 6673981.349082297, 2550637.8129039593 6673962.314713359, 2550616.265114207 6673944.200555637, 2550609.1292649973 6673933.918195537,
+LINESTRING (2550674.9523179964 6674116.500103362, 2550664.4836559766 6674113.329375588, 2550650.0139686773 6674100.476425465, 2550640.1475228337 6674080.841918779, 2550633.943871266 6674042.0630179, 2550645.8562022015 6673991.161334492, 2550645.410727222 6673981.349082297, 2550637.8129039593 6673962.314713359, 2550616.265114207 6673944.200555637, 2550609.1292649973 6673933.918195537,
2550602.87611621 6673919.264832167, 2550599.832037183 6673900.880612458, 2550603.0493564797 6673873.6943724295, 2550611.1504014786 6673856.980536122)
LINESTRING (2551121.846217868 6673914.833815121, 2551116.9047454093 6673924.63606502, 2551105.1574052074 6673931.647674387, 2551100.4386702385 6673938.219182739, 2551075.632313506 6674031.200524644, 2551082.7021664227 6674042.903210748, 2551160.1818147204 6674064.618194965)
@@ -1897,7 +1897,7 @@ LINESTRING (2552017.9191392646 6673946.871168619, 2552033.906741309 6673956.7334
LINESTRING (2552103.912309394 6674035.331472816, 2552084.14641956 6674019.7879051175)
-LINESTRING (2552540.7087763953 6673856.620453472, 2552537.656447832 6673859.791181246, 2552526.197841413 6673969.586382417, 2552522.6257920396 6673981.93921775, 2552497.6379455007 6674020.528075008, 2552484.6531748 6674074.850543585, 2552475.850919185 6674149.257622159, 2552457.3059607767 6674203.500072369, 2552433.3163081734 6674251.000975199, 2552457.9659237093 6674315.865863565,
+LINESTRING (2552540.7087763953 6673856.620453472, 2552537.656447832 6673859.791181246, 2552526.197841413 6673969.586382417, 2552522.6257920396 6673981.93921775, 2552497.6379455007 6674020.528075008, 2552484.6531748 6674074.850543585, 2552475.850919185 6674149.257622159, 2552457.3059607767 6674203.500072369, 2552433.3163081734 6674251.000975199, 2552457.9659237093 6674315.865863565,
2552469.9772490845 6674314.32551001, 2552538.7948838905 6674256.922334322, 2552572.4117457746 6674236.2575911665, 2552769.740662649 6674190.066989088, 2552873.2723477148 6674175.9337451, 2552913.356846339 6674178.394309871)
LINESTRING (2552103.912309394 6674035.331472816, 2552113.457023308 6674034.611307517, 2552123.8679385716 6674040.122572511, 2552211.725503986 6674130.563331279, 2552231.623386407 6674164.851201337, 2552240.7556234878 6674189.7869248055)
@@ -2146,4 +2146,4 @@ LINESTRING (2552908.753604884 6674299.502107611, 2552904.4841809357 6674388.3892
LINESTRING (2552915.658467067 6674300.512339488, 2552992.4286552123 6674304.88334276, 2553005.4134259126 6674311.614887844, 2553009.026722969 6674320.076830104, 2553005.1839963407 6674388.38925647)
-LINESTRING (2552733.706686524 6674363.156718183, 2552732.181598501 6674388.38925647)
\ No newline at end of file
+LINESTRING (2552733.706686524 6674363.156718183, 2552732.181598501 6674388.38925647)
diff --git a/data/shops.wkt b/data/shops.wkt
index 0db258f86..306639b4b 100644
--- a/data/shops.wkt
+++ b/data/shops.wkt
@@ -68,4 +68,4 @@ POINT (2552844.716030899 6673485.8301613815)
POINT (2552847.2814310095 6673449.964078932)
-POINT (2552800.516540576 6673446.05062009)
\ No newline at end of file
+POINT (2552800.516540576 6673446.05062009)
diff --git a/data/throwboxes.wkt b/data/throwboxes.wkt
index 781180028..bcba36407 100644
--- a/data/throwboxes.wkt
+++ b/data/throwboxes.wkt
@@ -8,4 +8,4 @@ LINESTRING (2552017.9191392646 6673946.871168619)
LINESTRING (2551949.8274636846 6673239.518810811)
-LINESTRING (2552473.318311431 6673253.912114491)
\ No newline at end of file
+LINESTRING (2552473.318311431 6673253.912114491)
diff --git a/data/tram10.wkt b/data/tram10.wkt
index abbf36bb5..19ad6c594 100644
--- a/data/tram10.wkt
+++ b/data/tram10.wkt
@@ -1 +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)
\ No newline at end of file
+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)
diff --git a/data/tram3.wkt b/data/tram3.wkt
index a43536365..d8a2186f1 100644
--- a/data/tram3.wkt
+++ b/data/tram3.wkt
@@ -1,2 +1,2 @@
-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,
- 2552483.811722061 6672500.92928317, 2552341.7794494093 6672696.104081427, 2552261.900555275 6672932.613958296, 2552508.7708714856 6673110.496865532)
\ No newline at end of file
+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,
+ 2552483.811722061 6672500.92928317, 2552341.7794494093 6672696.104081427, 2552261.900555275 6672932.613958296, 2552508.7708714856 6673110.496865532)
diff --git a/data/tram4.wkt b/data/tram4.wkt
index 57a9effea..68659f84f 100644
--- a/data/tram4.wkt
+++ b/data/tram4.wkt
@@ -1,2 +1,2 @@
-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,
- 2551761.5729668215 6674388.38925647)
\ No newline at end of file
+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,
+ 2551761.5729668215 6674388.38925647)
diff --git a/default_settings.txt b/default_settings.txt
index 3af13ebe9..fc266f1ba 100644
--- a/default_settings.txt
+++ b/default_settings.txt
@@ -1 +1,183 @@
-#
# Default settings for the simulation
#
## Scenario settings
Scenario.name = default_scenario
Scenario.simulateConnections = true
Scenario.updateInterval = 0.1
# 43200s == 12h
Scenario.endTime = 10000000
Scenario.endTime = 43200
## Interface-specific settings:
# type : which interface class the interface belongs to
# For different types, the sub-parameters are interface-specific
# For SimpleBroadcastInterface, the parameters are:
# transmitSpeed : transmit speed of the interface (bytes per second)
# transmitRange : range of the interface (meters)
# "Bluetooth" interface for all nodes
btInterface.type = SimpleBroadcastInterface
# Transmit speed of 2 Mbps = 250kBps
btInterface.transmitSpeed = 250k
btInterface.transmitRange = 10
# High speed, long range, interface for group 4
highspeedInterface.type = SimpleBroadcastInterface
highspeedInterface.transmitSpeed = 10M
highspeedInterface.transmitRange = 10
# Define 6 different node groups
Scenario.nrofHostGroups = 6
## Group-specific settings:
# groupID : Group's identifier. Used as the prefix of host names
# nrofHosts: number of hosts in the group
# movementModel: movement model of the hosts (valid class name from movement package)
# waitTime: minimum and maximum wait times (seconds) after reaching destination
# speed: minimum and maximum speeds (m/s) when moving on a path
# bufferSize: size of the message buffer (bytes)
# router: router used to route messages (valid class name from routing package)
# activeTimes: Time intervals when the nodes in the group are active (start1, end1, start2, end2, ...)
# msgTtl : TTL (minutes) of the messages created by this host group, default=infinite
## Group and movement model specific settings
# pois: Points Of Interest indexes and probabilities (poiIndex1, poiProb1, poiIndex2, poiProb2, ... )
# for ShortestPathMapBasedMovement
# okMaps : which map nodes are OK for the group (map file indexes), default=all
# for all MapBasedMovent models
# routeFile: route's file path - for MapRouteMovement
# routeType: route's type - for MapRouteMovement
# Common settings for all groups
Group.movementModel = ShortestPathMapBasedMovement
Group.router = EpidemicRouter
Group.bufferSize = 5M
Group.waitTime = 0, 120
# All nodes have the bluetooth interface
Group.nrofInterfaces = 1
Group.interface1 = btInterface
# Walking speeds
Group.speed = 0.5, 1.5
# Message TTL of 300 minutes (5 hours)
Group.msgTtl = 300
Group.nrofHosts = 40
# group1 (pedestrians) specific settings
Group1.groupID = p
# group2 specific settings
Group2.groupID = c
# cars can drive only on roads
Group2.okMaps = 1
# 10-50 km/h
Group2.speed = 2.7, 13.9
# another group of pedestrians
Group3.groupID = w
# The Tram groups
Group4.groupID = t
Group4.bufferSize = 50M
Group4.movementModel = MapRouteMovement
Group4.routeFile = data/tram3.wkt
Group4.routeType = 1
Group4.waitTime = 10, 30
Group4.speed = 7, 10
Group4.nrofHosts = 2
Group4.nrofInterfaces = 2
Group4.interface1 = btInterface
Group4.interface2 = highspeedInterface
Group5.groupID = t
Group5.bufferSize = 50M
Group5.movementModel = MapRouteMovement
Group5.routeFile = data/tram4.wkt
Group5.routeType = 2
Group5.waitTime = 10, 30
Group5.speed = 7, 10
Group5.nrofHosts = 2
Group6.groupID = t
Group6.bufferSize = 50M
Group6.movementModel = MapRouteMovement
Group6.routeFile = data/tram10.wkt
Group6.routeType = 2
Group6.waitTime = 10, 30
Group6.speed = 7, 10
Group6.nrofHosts = 2
## Message creation parameters
# How many event generators
Events.nrof = 1
# Class of the first event generator
Events1.class = MessageEventGenerator
# (following settings are specific for the MessageEventGenerator class)
# Creation interval in seconds (one new message every 25 to 35 seconds)
Events1.interval = 25,35
# Message sizes (500kB - 1MB)
Events1.size = 500k,1M
# range of message source/destination addresses
Events1.hosts = 0,125
# Message ID prefix
Events1.prefix = M
## Movement model settings
# seed for movement models' pseudo random number generator (default = 0)
MovementModel.rngSeed = 1
# World's size for Movement Models without implicit size (width, height; meters)
MovementModel.worldSize = 4500, 3400
# How long time to move hosts in the world before real simulation
MovementModel.warmup = 1000
## Map based movement -movement model specific settings
MapBasedMovement.nrofMapFiles = 4
MapBasedMovement.mapFile1 = data/roads.wkt
MapBasedMovement.mapFile2 = data/main_roads.wkt
MapBasedMovement.mapFile3 = data/pedestrian_paths.wkt
MapBasedMovement.mapFile4 = data/shops.wkt
## Reports - all report names have to be valid report classes
# how many reports to load
Report.nrofReports = 2
# length of the warm up period (simulated seconds)
Report.warmup = 0
# default directory of reports (can be overridden per Report with output setting)
Report.reportDir = reports/
# Report classes to load
Report.report1 = ContactTimesReport
Report.report2 = ConnectivityONEReport
## Default settings for some routers settings
ProphetRouter.secondsInTimeUnit = 30
SprayAndWaitRouter.nrofCopies = 6
SprayAndWaitRouter.binaryMode = true
## Optimization settings -- these affect the speed of the simulation
## see World class for details.
Optimization.cellSizeMult = 5
Optimization.randomizeUpdateOrder = true
## GUI settings
# GUI underlay image settings
GUI.UnderlayImage.fileName = data/helsinki_underlay.png
# Image offset in pixels (x, y)
GUI.UnderlayImage.offset = 64, 20
# Scaling factor for the image
GUI.UnderlayImage.scale = 4.75
# Image rotation (radians)
GUI.UnderlayImage.rotate = -0.015
# how many events to show in the log panel (default = 30)
GUI.EventLogPanel.nrofEvents = 100
# Regular Expression log filter (see Pattern-class from the Java API for RE-matching details)
#GUI.EventLogPanel.REfilter = .*p[1-9]<->p[1-9]$
\ No newline at end of file
+#
+# Default settings for the simulation
+#
+
+## Scenario settings
+Scenario.name = default_scenario
+Scenario.simulateConnections = true
+Scenario.updateInterval = 0.1
+# 43200s == 12h
+Scenario.endTime = 10000000
+Scenario.endTime = 43200
+
+## Interface-specific settings:
+# type : which interface class the interface belongs to
+# For different types, the sub-parameters are interface-specific
+# For SimpleBroadcastInterface, the parameters are:
+# transmitSpeed : transmit speed of the interface (bytes per second)
+# transmitRange : range of the interface (meters)
+
+# "Bluetooth" interface for all nodes
+btInterface.type = SimpleBroadcastInterface
+# Transmit speed of 2 Mbps = 250kBps
+btInterface.transmitSpeed = 250k
+btInterface.transmitRange = 10
+
+# High speed, long range, interface for group 4
+highspeedInterface.type = SimpleBroadcastInterface
+highspeedInterface.transmitSpeed = 10M
+highspeedInterface.transmitRange = 10
+
+# Define 6 different node groups
+Scenario.nrofHostGroups = 6
+
+## Group-specific settings:
+# groupID : Group's identifier. Used as the prefix of host names
+# nrofHosts: number of hosts in the group
+# movementModel: movement model of the hosts (valid class name from movement package)
+# waitTime: minimum and maximum wait times (seconds) after reaching destination
+# speed: minimum and maximum speeds (m/s) when moving on a path
+# bufferSize: size of the message buffer (bytes)
+# router: router used to route messages (valid class name from routing package)
+# activeTimes: Time intervals when the nodes in the group are active (start1, end1, start2, end2, ...)
+# msgTtl : TTL (minutes) of the messages created by this host group, default=infinite
+
+## Group and movement model specific settings
+# pois: Points Of Interest indexes and probabilities (poiIndex1, poiProb1, poiIndex2, poiProb2, ... )
+# for ShortestPathMapBasedMovement
+# okMaps : which map nodes are OK for the group (map file indexes), default=all
+# for all MapBasedMovent models
+# routeFile: route's file path - for MapRouteMovement
+# routeType: route's type - for MapRouteMovement
+
+
+# Common settings for all groups
+Group.movementModel = ShortestPathMapBasedMovement
+Group.router = EpidemicRouter
+Group.bufferSize = 5M
+Group.waitTime = 0, 120
+# All nodes have the bluetooth interface
+Group.nrofInterfaces = 1
+Group.interface1 = btInterface
+# Walking speeds
+Group.speed = 0.5, 1.5
+# Message TTL of 300 minutes (5 hours)
+Group.msgTtl = 300
+
+Group.nrofHosts = 40
+
+# group1 (pedestrians) specific settings
+Group1.groupID = p
+
+# group2 specific settings
+Group2.groupID = c
+# cars can drive only on roads
+Group2.okMaps = 1
+# 10-50 km/h
+Group2.speed = 2.7, 13.9
+
+# another group of pedestrians
+Group3.groupID = w
+
+# The Tram groups
+Group4.groupID = t
+Group4.bufferSize = 50M
+Group4.movementModel = MapRouteMovement
+Group4.routeFile = data/tram3.wkt
+Group4.routeType = 1
+Group4.waitTime = 10, 30
+Group4.speed = 7, 10
+Group4.nrofHosts = 2
+Group4.nrofInterfaces = 2
+Group4.interface1 = btInterface
+Group4.interface2 = highspeedInterface
+
+Group5.groupID = t
+Group5.bufferSize = 50M
+Group5.movementModel = MapRouteMovement
+Group5.routeFile = data/tram4.wkt
+Group5.routeType = 2
+Group5.waitTime = 10, 30
+Group5.speed = 7, 10
+Group5.nrofHosts = 2
+
+Group6.groupID = t
+Group6.bufferSize = 50M
+Group6.movementModel = MapRouteMovement
+Group6.routeFile = data/tram10.wkt
+Group6.routeType = 2
+Group6.waitTime = 10, 30
+Group6.speed = 7, 10
+Group6.nrofHosts = 2
+
+
+## Message creation parameters
+# How many event generators
+Events.nrof = 1
+# Class of the first event generator
+Events1.class = MessageEventGenerator
+# (following settings are specific for the MessageEventGenerator class)
+# Creation interval in seconds (one new message every 25 to 35 seconds)
+Events1.interval = 25,35
+# Message sizes (500kB - 1MB)
+Events1.size = 500k,1M
+# range of message source/destination addresses
+Events1.hosts = 0,125
+# Message ID prefix
+Events1.prefix = M
+
+
+## Movement model settings
+# seed for movement models' pseudo random number generator (default = 0)
+MovementModel.rngSeed = 1
+# World's size for Movement Models without implicit size (width, height; meters)
+MovementModel.worldSize = 4500, 3400
+# How long time to move hosts in the world before real simulation
+MovementModel.warmup = 1000
+
+## Map based movement -movement model specific settings
+MapBasedMovement.nrofMapFiles = 4
+
+MapBasedMovement.mapFile1 = data/roads.wkt
+MapBasedMovement.mapFile2 = data/main_roads.wkt
+MapBasedMovement.mapFile3 = data/pedestrian_paths.wkt
+MapBasedMovement.mapFile4 = data/shops.wkt
+
+## Reports - all report names have to be valid report classes
+
+# how many reports to load
+Report.nrofReports = 2
+# length of the warm up period (simulated seconds)
+Report.warmup = 0
+# default directory of reports (can be overridden per Report with output setting)
+Report.reportDir = reports/
+# Report classes to load
+Report.report1 = ContactTimesReport
+Report.report2 = ConnectivityONEReport
+
+## Default settings for some routers settings
+ProphetRouter.secondsInTimeUnit = 30
+SprayAndWaitRouter.nrofCopies = 6
+SprayAndWaitRouter.binaryMode = true
+
+## Optimization settings -- these affect the speed of the simulation
+## see World class for details.
+Optimization.cellSizeMult = 5
+Optimization.randomizeUpdateOrder = true
+
+
+## GUI settings
+
+# GUI underlay image settings
+GUI.UnderlayImage.fileName = data/helsinki_underlay.png
+# Image offset in pixels (x, y)
+GUI.UnderlayImage.offset = 64, 20
+# Scaling factor for the image
+GUI.UnderlayImage.scale = 4.75
+# Image rotation (radians)
+GUI.UnderlayImage.rotate = -0.015
+
+# how many events to show in the log panel (default = 30)
+GUI.EventLogPanel.nrofEvents = 100
+# Regular Expression log filter (see Pattern-class from the Java API for RE-matching details)
+#GUI.EventLogPanel.REfilter = .*p[1-9]<->p[1-9]$
diff --git a/example_settings/cluster_settings.txt b/example_settings/cluster_settings.txt
index 19d63d6e0..8d3d22f72 100644
--- a/example_settings/cluster_settings.txt
+++ b/example_settings/cluster_settings.txt
@@ -59,7 +59,7 @@ MapBasedMovement.mapFile1 = data/cluster/ferryroute.wkt
MapBasedMovement.mapFile2 = data/cluster/origin.wkt
-## Message creation parameters
+## Message creation parameters
# How many event generators
Events.nrof = 1
# Class of the first event generator
@@ -113,4 +113,4 @@ GUI.UnderlayImage.rotate = -0.015
# how many events to show in the log panel (default = 30)
GUI.EventLogPanel.nrofEvents = 30
# Regular Expression log filter (see Pattern-class from the Java API for RE-matching details)
-#GUI.EventLogPanel.REfilter = .*p[1-9]<->p[1-9]$
\ No newline at end of file
+#GUI.EventLogPanel.REfilter = .*p[1-9]<->p[1-9]$
diff --git a/example_settings/epidemic_settings.txt b/example_settings/epidemic_settings.txt
index d96abb044..64fcce0dd 100644
--- a/example_settings/epidemic_settings.txt
+++ b/example_settings/epidemic_settings.txt
@@ -1,2 +1,2 @@
-Scenario.name = Epidemic
-Group.router = EpidemicRouter
\ No newline at end of file
+Scenario.name = Epidemic
+Group.router = EpidemicRouter
diff --git a/example_settings/ping_app_settings.txt b/example_settings/ping_app_settings.txt
index 30019c37b..39acdba32 100644
--- a/example_settings/ping_app_settings.txt
+++ b/example_settings/ping_app_settings.txt
@@ -1,19 +1,19 @@
-# This configuration file adds Ping application for all the nodes and
-# a report module that counts the number of pings & pongs sent & received
-
-# Define new application
-pingApp.type = PingApplication
-pingApp.interval = 500
-pingApp.destinationRange = 0,125
-pingApp.pingSize = 5
-pingApp.pongSize = 5
-pingApp.passive = false
-
-# Set Ping app for all nodes
-Group.nrofApplications = 1
-Group.application1 = pingApp
-
-# Add report for Ping app
-Report.nrofReports = 2
-Report.report2 = PingAppReporter
-
+# This configuration file adds Ping application for all the nodes and
+# a report module that counts the number of pings & pongs sent & received
+
+# Define new application
+pingApp.type = PingApplication
+pingApp.interval = 500
+pingApp.destinationRange = 0,125
+pingApp.pingSize = 5
+pingApp.pongSize = 5
+pingApp.passive = false
+
+# Set Ping app for all nodes
+Group.nrofApplications = 1
+Group.application1 = pingApp
+
+# Add report for Ping app
+Report.nrofReports = 2
+Report.report2 = PingAppReporter
+
diff --git a/example_settings/prophet_settings.txt b/example_settings/prophet_settings.txt
index 8ecd25aa2..3ded6df0c 100644
--- a/example_settings/prophet_settings.txt
+++ b/example_settings/prophet_settings.txt
@@ -1,18 +1,18 @@
-## Test scenario using Prophet router and Points of Interest (POIs)
-
-Scenario.name = PRoPHET-%%ProphetRouter.secondsInTimeUnit%%siu
-Group.router = ProphetRouter
-
-ProphetRouter.secondsInTimeUnit = 30
-
-# Define POI data files
-PointsOfInterest.poiFile1 = data/ParkPOIs.wkt
-PointsOfInterest.poiFile2 = data/CentralPOIs.wkt
-PointsOfInterest.poiFile3 = data/WestPOIs.wkt
-PointsOfInterest.poiFile4 = data/shops.wkt
-
-# Define probabilities for different groups selecting POIs from different POI files
-Group1.pois = 1,0.3, 2,0.1, 3,0.1, 4, 0.1
-Group2.pois = 2,0.3, 3,0.1
-Group3.pois = 3,0.3, 2,0.1, 1,0.1, 4, 0.1
-Group4.pois = 4,0.3, 2,0.1, 3,0.1, 1, 0.1
+## Test scenario using Prophet router and Points of Interest (POIs)
+
+Scenario.name = PRoPHET-%%ProphetRouter.secondsInTimeUnit%%siu
+Group.router = ProphetRouter
+
+ProphetRouter.secondsInTimeUnit = 30
+
+# Define POI data files
+PointsOfInterest.poiFile1 = data/ParkPOIs.wkt
+PointsOfInterest.poiFile2 = data/CentralPOIs.wkt
+PointsOfInterest.poiFile3 = data/WestPOIs.wkt
+PointsOfInterest.poiFile4 = data/shops.wkt
+
+# Define probabilities for different groups selecting POIs from different POI files
+Group1.pois = 1,0.3, 2,0.1, 3,0.1, 4, 0.1
+Group2.pois = 2,0.3, 3,0.1
+Group3.pois = 3,0.3, 2,0.1, 1,0.1, 4, 0.1
+Group4.pois = 4,0.3, 2,0.1, 3,0.1, 1, 0.1
diff --git a/example_settings/snw_settings.txt b/example_settings/snw_settings.txt
index d231f36fe..a62007917 100644
--- a/example_settings/snw_settings.txt
+++ b/example_settings/snw_settings.txt
@@ -1,4 +1,4 @@
-Scenario.name = SprayAndWait
-Group.router = SprayAndWaitRouter
-SprayAndWaitRouter.nrofCopies = 10
-SprayAndWaitRouter.binaryMode = true
+Scenario.name = SprayAndWait
+Group.router = SprayAndWaitRouter
+SprayAndWaitRouter.nrofCopies = 10
+SprayAndWaitRouter.binaryMode = true
diff --git a/example_settings/wlan-interface.txt b/example_settings/wlan-interface.txt
index bc4fcd4b0..45f30959c 100644
--- a/example_settings/wlan-interface.txt
+++ b/example_settings/wlan-interface.txt
@@ -11,4 +11,4 @@ wlanInterface.transmitRange = 91
# dummy speed
wlanInterface.transmitSpeed = 0
-Group.interface1 = wlanInterface
\ No newline at end of file
+Group.interface1 = wlanInterface
diff --git a/gui/DTNSimGUI.java b/gui/DTNSimGUI.java
index d1d78a3cb..985f00615 100644
--- a/gui/DTNSimGUI.java
+++ b/gui/DTNSimGUI.java
@@ -1,336 +1,336 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
- */
-package gui;
-
-import gui.playfield.PlayField;
-
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseWheelListener;
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
-import java.lang.reflect.InvocationTargetException;
-
-import javax.swing.JOptionPane;
-import javax.swing.JScrollPane;
-import javax.swing.SwingUtilities;
-
-import movement.Path;
-import ui.DTNSimUI;
-import core.Coord;
-import core.DTNHost;
-import core.SimClock;
-
-/**
- * Graphical User Interface for simulator
- */
-public class DTNSimGUI extends DTNSimUI {
- private MainWindow main;
- private PlayField field;
- private GUIControls guiControls;
- private EventLogPanel eventLogPanel;
- private InfoPanel infoPanel;
-
- private void startGUI() {
- try {
- SwingUtilities.invokeAndWait(new Runnable() {
- public void run() {
- try {
- initGUI();
- } catch (AssertionError e) {
- processAssertionError(e);
- }
- }
- });
- } catch (InterruptedException e) {
- e.printStackTrace();
- System.exit(-1);
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- System.exit(-1);
- }
- }
-
- /**
- * Initializes the GUI
- */
- private void initGUI() {
- this.field = new PlayField(world, this);
-
- this.field.addMouseListener(new PlayfieldMouseHandler());
- this.field.addMouseWheelListener(new PlayfieldMouseHandler());
-
- this.guiControls = new GUIControls(this,this.field);
- this.eventLogPanel = new EventLogPanel(this);
- this.infoPanel = new InfoPanel(this);
- this.main = new MainWindow(this.scen.getName(), world, field,
- guiControls, infoPanel, eventLogPanel, this);
-
- scen.addMessageListener(eventLogPanel);
- scen.addConnectionListener(eventLogPanel);
-
- if (scen.getMap() != null ) {
- field.setMap(scen.getMap());
- }
-
- // if user closes the main window, call closeSim()
- this.main.addWindowListener(new WindowAdapter() {
- private boolean closeAgain = false;
- public void windowClosing(WindowEvent e) {
- closeSim();
- if (closeAgain) {
- // if method is called again, force closing
- System.err.println("Forced close. "+
- "Some reports may have not been finalized.");
- System.exit(-1);
- }
- closeAgain = true;
- }
- });
-
- this.main.setVisible(true);
- }
-
- @Override
- protected void runSim() {
- double simTime = SimClock.getTime();
- double endTime = scen.getEndTime();
-
- startGUI();
-
- // Startup DTN2Manager
- // XXX: Would be nice if this wasn't needed..
- // DTN2Manager.setup(world);
-
- while (simTime < endTime && !simCancelled){
- if (guiControls.isPaused()) {
- wait(10); // release CPU resources when paused
- }
- else {
- try {
- world.update();
- } catch (AssertionError e) {
- // handles both assertion errors and SimErrors
- processAssertionError(e);
- }
- simTime = SimClock.getTime();
- }
- this.update(false);
- }
-
- simDone = true;
- done();
- this.update(true); // force final GUI update
-
- if (!simCancelled) { // NOT cancelled -> leave the GUI running
- JOptionPane.showMessageDialog(getParentFrame(),
- "Simulation done");
- }
- else { // was cancelled -> exit immediately
- System.exit(0);
- }
- }
-
- /**
- * Processes assertion errors by showing a warning dialog to the user
- * and pausing the simulation (if it's running)
- * @param e The error that was thrown
- */
- private void processAssertionError(AssertionError e) {
- String title = e.getClass().getSimpleName() + " (simulation paused)";
- String msg = e.getMessage();
- String txt = (msg != null ? msg : "") + " at simtime " +
- SimClock.getIntTime() + "\n\ncaught at:\n" +
- e.getStackTrace()[0].toString() +
- "\nNote that the simulation might be in inconsistent state, "+
- "continue only with caution.\n\n Show rest of the stack trace?";
- // rest of the update cycle that caused the exception is skipped
- // so the user is warned about the consequences
-
-
- if (guiControls != null) {
- guiControls.setPaused(true);
- }
-
- int selection = JOptionPane.showOptionDialog(getParentFrame(), txt,
- title, JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE,
- null, null, null);
-
- if (selection == 0) {
- txt = "";
- for (StackTraceElement trace : e.getStackTrace()) {
- txt += trace.toString()+"\n";
- }
- JOptionPane.showMessageDialog(getParentFrame(), txt,
- "stack trace", JOptionPane.INFORMATION_MESSAGE);
- }
- }
-
-
-
- /**
- * Closes the program if simulation is done or cancels it.
- */
- public void closeSim() {
- if (simDone) {
- System.exit(0);
- }
- this.world.cancelSim();
- this.simCancelled = true;
- }
-
- /**
- * Updates the GUI
- */
- public void update(boolean forcedUpdate) {
- double guiUpdateInterval = guiControls.getUpdateInterval();
-
- // update only if long enough simTime has passed (and not forced)
- if (!forcedUpdate && guiUpdateInterval > (SimClock.getTime()
- - this.lastUpdate)) {
- return;
- }
-
- try {
- // run update in EDT, TODO: optimize threading
- SwingUtilities.invokeAndWait(new Runnable() {
- public void run() {
- updateView();
- }
- });
- } catch (InterruptedException e) {
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- }
-
- // wait a while if we don't want to run simulation at full speed
- if (guiUpdateInterval < 0) {
- wait(100*(int)(-guiUpdateInterval));
- }
-
- }
-
- /**
- * Updates playfield and sim time field
- *
- */
- private void updateView() {
- double simTime = SimClock.getTime();
- this.lastUpdate = simTime;
- guiControls.setSimTime(simTime); //update time to control panel
-
- this.field.updateField();
- }
-
- /**
- * Sets the pause of the simulation on/off
- * @param paused True if pause should be set on
- */
- public void setPaused(boolean paused) {
- this.guiControls.setPaused(paused);
- }
-
- /**
- * Sets a node's graphical presentation in the center of the playfield view
- * @param host The node to center
- */
- public void setFocus(DTNHost host) {
- centerViewAt(host.getLocation());
- infoPanel.showInfo(host);
- showPath(host.getPath()); // show path on the playfield
- }
-
- /**
- * Shows a path on the playfield
- * @param path The path to show
- */
- public void showPath(Path path) {
- field.addPath(path);
- }
-
- /**
- * Returns the world coordinates that are currently in the center
- * of the viewport
- * @return The coordinates
- */
- public Coord getCenterViewCoord() {
- JScrollPane sp = main.getPlayFieldScroll();
- double midX, midY;
-
- midX = sp.getHorizontalScrollBar().getValue() +
- sp.getViewport().getWidth()/2;
- midY = sp.getVerticalScrollBar().getValue() +
- sp.getViewport().getHeight()/2;
-
- return this.field.getWorldPosition(new Coord(midX, midY));
- }
-
- /**
- * Sets certain location to be in the center of the playfield view
- * @param loc The location to center
- */
- public void centerViewAt(Coord loc) {
- JScrollPane sp = main.getPlayFieldScroll();
- Coord gLoc = this.field.getGraphicsPosition(loc);
- int midX, midY;
-
- updateView(); // update graphics to match the values
-
- midX = (int)gLoc.getX() - sp.getViewport().getWidth()/2;
- midY = (int)gLoc.getY() - sp.getViewport().getHeight()/2;
-
- sp.getHorizontalScrollBar().setValue(midX);
- sp.getVerticalScrollBar().setValue(midY);
- }
-
- /**
- * Returns the info panel of the GUI
- * @return the info panel of the GUI
- */
- public InfoPanel getInfoPanel() {
- return this.infoPanel;
- }
-
- /**
- * Returns the parent frame (window) of the gui.
- * @return The parent frame
- */
- public MainWindow getParentFrame() {
- return this.main;
- }
-
- /**
- * Suspend thread for ms milliseconds
- * @param ms The nrof milliseconds to wait
- */
- private void wait(int ms) {
- try {
- Thread.sleep(ms);
- } catch (InterruptedException e) {
- // nothing to do here
- }
- }
-
- /**
- * Handler for playfield's mouse clicks.
- */
- private class PlayfieldMouseHandler extends MouseAdapter implements
- MouseWheelListener {
- /**
- * If mouse button is clicked, centers view at that location.
- */
- public void mouseClicked(MouseEvent e) {
-
- java.awt.Point p = e.getPoint();
- centerViewAt(field.getWorldPosition(new Coord(p.x, p.y)));
- }
-
- public void mouseWheelMoved(java.awt.event.MouseWheelEvent e) {
- guiControls.changeZoom(e.getWheelRotation());
- }
- }
-
-}
+ * Released under GPLv3. See LICENSE.txt for details.
+ */
+package gui;
+
+import gui.playfield.PlayField;
+
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseWheelListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.swing.JOptionPane;
+import javax.swing.JScrollPane;
+import javax.swing.SwingUtilities;
+
+import movement.Path;
+import ui.DTNSimUI;
+import core.Coord;
+import core.DTNHost;
+import core.SimClock;
+
+/**
+ * Graphical User Interface for simulator
+ */
+public class DTNSimGUI extends DTNSimUI {
+ private MainWindow main;
+ private PlayField field;
+ private GUIControls guiControls;
+ private EventLogPanel eventLogPanel;
+ private InfoPanel infoPanel;
+
+ private void startGUI() {
+ try {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ try {
+ initGUI();
+ } catch (AssertionError e) {
+ processAssertionError(e);
+ }
+ }
+ });
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ System.exit(-1);
+ } catch (InvocationTargetException e) {
+ e.printStackTrace();
+ System.exit(-1);
+ }
+ }
+
+ /**
+ * Initializes the GUI
+ */
+ private void initGUI() {
+ this.field = new PlayField(world, this);
+
+ this.field.addMouseListener(new PlayfieldMouseHandler());
+ this.field.addMouseWheelListener(new PlayfieldMouseHandler());
+
+ this.guiControls = new GUIControls(this,this.field);
+ this.eventLogPanel = new EventLogPanel(this);
+ this.infoPanel = new InfoPanel(this);
+ this.main = new MainWindow(this.scen.getName(), world, field,
+ guiControls, infoPanel, eventLogPanel, this);
+
+ scen.addMessageListener(eventLogPanel);
+ scen.addConnectionListener(eventLogPanel);
+
+ if (scen.getMap() != null ) {
+ field.setMap(scen.getMap());
+ }
+
+ // if user closes the main window, call closeSim()
+ this.main.addWindowListener(new WindowAdapter() {
+ private boolean closeAgain = false;
+ public void windowClosing(WindowEvent e) {
+ closeSim();
+ if (closeAgain) {
+ // if method is called again, force closing
+ System.err.println("Forced close. "+
+ "Some reports may have not been finalized.");
+ System.exit(-1);
+ }
+ closeAgain = true;
+ }
+ });
+
+ this.main.setVisible(true);
+ }
+
+ @Override
+ protected void runSim() {
+ double simTime = SimClock.getTime();
+ double endTime = scen.getEndTime();
+
+ startGUI();
+
+ // Startup DTN2Manager
+ // XXX: Would be nice if this wasn't needed..
+ // DTN2Manager.setup(world);
+
+ while (simTime < endTime && !simCancelled){
+ if (guiControls.isPaused()) {
+ wait(10); // release CPU resources when paused
+ }
+ else {
+ try {
+ world.update();
+ } catch (AssertionError e) {
+ // handles both assertion errors and SimErrors
+ processAssertionError(e);
+ }
+ simTime = SimClock.getTime();
+ }
+ this.update(false);
+ }
+
+ simDone = true;
+ done();
+ this.update(true); // force final GUI update
+
+ if (!simCancelled) { // NOT cancelled -> leave the GUI running
+ JOptionPane.showMessageDialog(getParentFrame(),
+ "Simulation done");
+ }
+ else { // was cancelled -> exit immediately
+ System.exit(0);
+ }
+ }
+
+ /**
+ * Processes assertion errors by showing a warning dialog to the user
+ * and pausing the simulation (if it's running)
+ * @param e The error that was thrown
+ */
+ private void processAssertionError(AssertionError e) {
+ String title = e.getClass().getSimpleName() + " (simulation paused)";
+ String msg = e.getMessage();
+ String txt = (msg != null ? msg : "") + " at simtime " +
+ SimClock.getIntTime() + "\n\ncaught at:\n" +
+ e.getStackTrace()[0].toString() +
+ "\nNote that the simulation might be in inconsistent state, "+
+ "continue only with caution.\n\n Show rest of the stack trace?";
+ // rest of the update cycle that caused the exception is skipped
+ // so the user is warned about the consequences
+
+
+ if (guiControls != null) {
+ guiControls.setPaused(true);
+ }
+
+ int selection = JOptionPane.showOptionDialog(getParentFrame(), txt,
+ title, JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE,
+ null, null, null);
+
+ if (selection == 0) {
+ txt = "";
+ for (StackTraceElement trace : e.getStackTrace()) {
+ txt += trace.toString()+"\n";
+ }
+ JOptionPane.showMessageDialog(getParentFrame(), txt,
+ "stack trace", JOptionPane.INFORMATION_MESSAGE);
+ }
+ }
+
+
+
+ /**
+ * Closes the program if simulation is done or cancels it.
+ */
+ public void closeSim() {
+ if (simDone) {
+ System.exit(0);
+ }
+ this.world.cancelSim();
+ this.simCancelled = true;
+ }
+
+ /**
+ * Updates the GUI
+ */
+ public void update(boolean forcedUpdate) {
+ double guiUpdateInterval = guiControls.getUpdateInterval();
+
+ // update only if long enough simTime has passed (and not forced)
+ if (!forcedUpdate && guiUpdateInterval > (SimClock.getTime()
+ - this.lastUpdate)) {
+ return;
+ }
+
+ try {
+ // run update in EDT, TODO: optimize threading
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ updateView();
+ }
+ });
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ } catch (InvocationTargetException e) {
+ e.printStackTrace();
+ }
+
+ // wait a while if we don't want to run simulation at full speed
+ if (guiUpdateInterval < 0) {
+ wait(100*(int)(-guiUpdateInterval));
+ }
+
+ }
+
+ /**
+ * Updates playfield and sim time field
+ *
+ */
+ private void updateView() {
+ double simTime = SimClock.getTime();
+ this.lastUpdate = simTime;
+ guiControls.setSimTime(simTime); //update time to control panel
+
+ this.field.updateField();
+ }
+
+ /**
+ * Sets the pause of the simulation on/off
+ * @param paused True if pause should be set on
+ */
+ public void setPaused(boolean paused) {
+ this.guiControls.setPaused(paused);
+ }
+
+ /**
+ * Sets a node's graphical presentation in the center of the playfield view
+ * @param host The node to center
+ */
+ public void setFocus(DTNHost host) {
+ centerViewAt(host.getLocation());
+ infoPanel.showInfo(host);
+ showPath(host.getPath()); // show path on the playfield
+ }
+
+ /**
+ * Shows a path on the playfield
+ * @param path The path to show
+ */
+ public void showPath(Path path) {
+ field.addPath(path);
+ }
+
+ /**
+ * Returns the world coordinates that are currently in the center
+ * of the viewport
+ * @return The coordinates
+ */
+ public Coord getCenterViewCoord() {
+ JScrollPane sp = main.getPlayFieldScroll();
+ double midX, midY;
+
+ midX = sp.getHorizontalScrollBar().getValue() +
+ sp.getViewport().getWidth()/2;
+ midY = sp.getVerticalScrollBar().getValue() +
+ sp.getViewport().getHeight()/2;
+
+ return this.field.getWorldPosition(new Coord(midX, midY));
+ }
+
+ /**
+ * Sets certain location to be in the center of the playfield view
+ * @param loc The location to center
+ */
+ public void centerViewAt(Coord loc) {
+ JScrollPane sp = main.getPlayFieldScroll();
+ Coord gLoc = this.field.getGraphicsPosition(loc);
+ int midX, midY;
+
+ updateView(); // update graphics to match the values
+
+ midX = (int)gLoc.getX() - sp.getViewport().getWidth()/2;
+ midY = (int)gLoc.getY() - sp.getViewport().getHeight()/2;
+
+ sp.getHorizontalScrollBar().setValue(midX);
+ sp.getVerticalScrollBar().setValue(midY);
+ }
+
+ /**
+ * Returns the info panel of the GUI
+ * @return the info panel of the GUI
+ */
+ public InfoPanel getInfoPanel() {
+ return this.infoPanel;
+ }
+
+ /**
+ * Returns the parent frame (window) of the gui.
+ * @return The parent frame
+ */
+ public MainWindow getParentFrame() {
+ return this.main;
+ }
+
+ /**
+ * Suspend thread for ms milliseconds
+ * @param ms The nrof milliseconds to wait
+ */
+ private void wait(int ms) {
+ try {
+ Thread.sleep(ms);
+ } catch (InterruptedException e) {
+ // nothing to do here
+ }
+ }
+
+ /**
+ * Handler for playfield's mouse clicks.
+ */
+ private class PlayfieldMouseHandler extends MouseAdapter implements
+ MouseWheelListener {
+ /**
+ * If mouse button is clicked, centers view at that location.
+ */
+ public void mouseClicked(MouseEvent e) {
+
+ java.awt.Point p = e.getPoint();
+ centerViewAt(field.getWorldPosition(new Coord(p.x, p.y)));
+ }
+
+ public void mouseWheelMoved(java.awt.event.MouseWheelEvent e) {
+ guiControls.changeZoom(e.getWheelRotation());
+ }
+ }
+
+}
diff --git a/gui/EventLogControl.java b/gui/EventLogControl.java
index f5ffa4145..42914026c 100644
--- a/gui/EventLogControl.java
+++ b/gui/EventLogControl.java
@@ -1,64 +1,64 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package gui;
-
+package gui;
+
import javax.swing.JCheckBox;
-
-/**
- * Class capsulates the references to the controls one can add to
- * the EventLogControlPanel
- *
- */
-public class EventLogControl {
- private JCheckBox show;
- private JCheckBox pause;
-
- /**
- * Constructor.
- * @param show The checkbox that controls showing this type of event
- * @param pause The checkbox that controls pausing on this type of event
- */
- public EventLogControl(JCheckBox show, JCheckBox pause) {
- this.show = show;
- this.pause = pause;
- }
-
- /**
- * Returns true if this event type should be shown
- * @return true if this event type should be shown
- */
- public boolean showEvent() {
- return this.show.isSelected();
- }
-
- /**
- * Returns true if this event type should cause pause
- * @return true if this event type should cause pause
- */
-
- public boolean pauseOnEvent() {
- return this.pause.isSelected();
- }
-
- /**
- * Sets ought this event type should be shown (return true for
- * {@link #showEvent()} )
- * @param show If true, events are set to be shown
- */
- public void setShowEvent(boolean show) {
- this.show.setSelected(show);
- }
-
- /**
- * Sets ought this event type cause pause (return true for
- * {@link #pauseOnEvent()} )
- * @param pause If true, events cause pause
- */
- public void setPauseOnEvent(boolean pause) {
- this.pause.setSelected(pause);
- }
-
-
-}
+
+/**
+ * Class capsulates the references to the controls one can add to
+ * the EventLogControlPanel
+ *
+ */
+public class EventLogControl {
+ private JCheckBox show;
+ private JCheckBox pause;
+
+ /**
+ * Constructor.
+ * @param show The checkbox that controls showing this type of event
+ * @param pause The checkbox that controls pausing on this type of event
+ */
+ public EventLogControl(JCheckBox show, JCheckBox pause) {
+ this.show = show;
+ this.pause = pause;
+ }
+
+ /**
+ * Returns true if this event type should be shown
+ * @return true if this event type should be shown
+ */
+ public boolean showEvent() {
+ return this.show.isSelected();
+ }
+
+ /**
+ * Returns true if this event type should cause pause
+ * @return true if this event type should cause pause
+ */
+
+ public boolean pauseOnEvent() {
+ return this.pause.isSelected();
+ }
+
+ /**
+ * Sets ought this event type should be shown (return true for
+ * {@link #showEvent()} )
+ * @param show If true, events are set to be shown
+ */
+ public void setShowEvent(boolean show) {
+ this.show.setSelected(show);
+ }
+
+ /**
+ * Sets ought this event type cause pause (return true for
+ * {@link #pauseOnEvent()} )
+ * @param pause If true, events cause pause
+ */
+ public void setPauseOnEvent(boolean pause) {
+ this.pause.setSelected(pause);
+ }
+
+
+}
diff --git a/gui/EventLogControlPanel.java b/gui/EventLogControlPanel.java
index 43968b78c..70940632e 100644
--- a/gui/EventLogControlPanel.java
+++ b/gui/EventLogControlPanel.java
@@ -1,9 +1,9 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package gui;
-
+package gui;
+
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
@@ -16,144 +16,144 @@
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
-
-/**
- * Control panel for event log
- *
- */
-public class EventLogControlPanel extends JPanel implements ActionListener {
- private static final String TITLE_TEXT = "Event log controls";
- private static final String SHOW_TEXT = "show";
- private static final String PAUSE_TEXT = "pause";
- private static final int PADDING = 5;
- private Font smallFont = new Font("sans",Font.PLAIN,11);
- private Font headingFont = new Font("sans",Font.BOLD,11);
- private Vector logControls;
-
- private JCheckBox showAllCheck;
- private JCheckBox pauseAllCheck;
-
- private GridBagLayout layout;
- private GridBagConstraints c;
-
- /**
- * Constructor. Creates a new control panel.
- */
- public EventLogControlPanel() {
- layout = new GridBagLayout();
- c = new GridBagConstraints();
- logControls = new Vector();
-
- c.ipadx = PADDING;
-
- setLayout(layout);
- this.setBorder(BorderFactory.createTitledBorder(
- getBorder(), TITLE_TEXT));
-
- c.fill = GridBagConstraints.BOTH;
- addLabel(" ");
- addLabel(SHOW_TEXT + "");
- c.gridwidth = GridBagConstraints.REMAINDER; //end row
- addLabel(PAUSE_TEXT);
-
- // create "show/pause on all selections
- c.gridwidth = 1;
- addLabel("all");
- showAllCheck = addCheckBox(true,false);
- pauseAllCheck = addCheckBox(false,true);
- showAllCheck.addActionListener(this);
- pauseAllCheck.addActionListener(this);
-
- this.setMinimumSize(new Dimension(0,0));
- }
-
- /**
- * Adds a new filter&pause control
- * @param name Name of the control
- * @param showOn Is "show" initially selected
- * @param pauseOn Is "pause" initially selected
- * @return Event log control object that can be queried for status
- */
- public EventLogControl addControl(String name, boolean showOn,
- boolean pauseOn) {
- JCheckBox filterCheck;
- JCheckBox pauseCheck;
- EventLogControl control;
-
- c.gridwidth = 1; // one component/cell
- addLabel(name);
- filterCheck = addCheckBox(showOn, false);
- pauseCheck = addCheckBox(pauseOn, true);
-
- control = new EventLogControl(filterCheck, pauseCheck);
- this.logControls.add(control);
- return control;
- }
-
- /**
- * Creates and adds a new checkbox to this panel
- * @param selected Is the checkbox initially selected
- * @param endOfRow Is the box last in the row in the layout
- * @return The created checkbox
- */
- private JCheckBox addCheckBox(boolean selected, boolean endOfRow) {
- JCheckBox box = new JCheckBox();
- box.setSelected(selected);
-
- if (endOfRow) {
- c.gridwidth = GridBagConstraints.REMAINDER; // use rest of the line
- }
- else {
- c.gridwidth = 1; // default
- }
-
- layout.setConstraints(box, c);
- add(box);
-
- return box;
- }
-
- /**
- * Adds a new filter&pause control with initially "show" checked
- * but "pause" unchecked
- * @param name Name of the control
- * @return Event log control object that can be queried for status
- * @see #addControl(String name, boolean showOn, boolean pauseOn)
- */
- public EventLogControl addControl(String name) {
- return addControl(name, true, false);
- }
-
- /**
- * Adds a new heading in the control panel. Subsequent addControl
- * controls will be under this heading
- * @param name The heading text
- */
- public void addHeading(String name) {
- c.gridwidth = GridBagConstraints.REMAINDER;
- addLabel(name).setFont(this.headingFont);
- }
-
- private JLabel addLabel(String txt) {
- JLabel label = new JLabel(txt);
- label.setFont(this.smallFont);
- layout.setConstraints(label, c);
- add(label);
- return label;
- }
-
- public void actionPerformed(ActionEvent e) {
- if (e.getSource() == this.showAllCheck) {
- for (EventLogControl elc : logControls) {
- elc.setShowEvent(this.showAllCheck.isSelected());
- }
- }
- else if (e.getSource() == this.pauseAllCheck) {
- for (EventLogControl elc : logControls) {
- elc.setPauseOnEvent(this.pauseAllCheck.isSelected());
- }
- }
-
-
- }
-}
+
+/**
+ * Control panel for event log
+ *
+ */
+public class EventLogControlPanel extends JPanel implements ActionListener {
+ private static final String TITLE_TEXT = "Event log controls";
+ private static final String SHOW_TEXT = "show";
+ private static final String PAUSE_TEXT = "pause";
+ private static final int PADDING = 5;
+ private Font smallFont = new Font("sans",Font.PLAIN,11);
+ private Font headingFont = new Font("sans",Font.BOLD,11);
+ private Vector logControls;
+
+ private JCheckBox showAllCheck;
+ private JCheckBox pauseAllCheck;
+
+ private GridBagLayout layout;
+ private GridBagConstraints c;
+
+ /**
+ * Constructor. Creates a new control panel.
+ */
+ public EventLogControlPanel() {
+ layout = new GridBagLayout();
+ c = new GridBagConstraints();
+ logControls = new Vector();
+
+ c.ipadx = PADDING;
+
+ setLayout(layout);
+ this.setBorder(BorderFactory.createTitledBorder(
+ getBorder(), TITLE_TEXT));
+
+ c.fill = GridBagConstraints.BOTH;
+ addLabel(" ");
+ addLabel(SHOW_TEXT + "");
+ c.gridwidth = GridBagConstraints.REMAINDER; //end row
+ addLabel(PAUSE_TEXT);
+
+ // create "show/pause on all selections
+ c.gridwidth = 1;
+ addLabel("all");
+ showAllCheck = addCheckBox(true,false);
+ pauseAllCheck = addCheckBox(false,true);
+ showAllCheck.addActionListener(this);
+ pauseAllCheck.addActionListener(this);
+
+ this.setMinimumSize(new Dimension(0,0));
+ }
+
+ /**
+ * Adds a new filter&pause control
+ * @param name Name of the control
+ * @param showOn Is "show" initially selected
+ * @param pauseOn Is "pause" initially selected
+ * @return Event log control object that can be queried for status
+ */
+ public EventLogControl addControl(String name, boolean showOn,
+ boolean pauseOn) {
+ JCheckBox filterCheck;
+ JCheckBox pauseCheck;
+ EventLogControl control;
+
+ c.gridwidth = 1; // one component/cell
+ addLabel(name);
+ filterCheck = addCheckBox(showOn, false);
+ pauseCheck = addCheckBox(pauseOn, true);
+
+ control = new EventLogControl(filterCheck, pauseCheck);
+ this.logControls.add(control);
+ return control;
+ }
+
+ /**
+ * Creates and adds a new checkbox to this panel
+ * @param selected Is the checkbox initially selected
+ * @param endOfRow Is the box last in the row in the layout
+ * @return The created checkbox
+ */
+ private JCheckBox addCheckBox(boolean selected, boolean endOfRow) {
+ JCheckBox box = new JCheckBox();
+ box.setSelected(selected);
+
+ if (endOfRow) {
+ c.gridwidth = GridBagConstraints.REMAINDER; // use rest of the line
+ }
+ else {
+ c.gridwidth = 1; // default
+ }
+
+ layout.setConstraints(box, c);
+ add(box);
+
+ return box;
+ }
+
+ /**
+ * Adds a new filter&pause control with initially "show" checked
+ * but "pause" unchecked
+ * @param name Name of the control
+ * @return Event log control object that can be queried for status
+ * @see #addControl(String name, boolean showOn, boolean pauseOn)
+ */
+ public EventLogControl addControl(String name) {
+ return addControl(name, true, false);
+ }
+
+ /**
+ * Adds a new heading in the control panel. Subsequent addControl
+ * controls will be under this heading
+ * @param name The heading text
+ */
+ public void addHeading(String name) {
+ c.gridwidth = GridBagConstraints.REMAINDER;
+ addLabel(name).setFont(this.headingFont);
+ }
+
+ private JLabel addLabel(String txt) {
+ JLabel label = new JLabel(txt);
+ label.setFont(this.smallFont);
+ layout.setConstraints(label, c);
+ add(label);
+ return label;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource() == this.showAllCheck) {
+ for (EventLogControl elc : logControls) {
+ elc.setShowEvent(this.showAllCheck.isSelected());
+ }
+ }
+ else if (e.getSource() == this.pauseAllCheck) {
+ for (EventLogControl elc : logControls) {
+ elc.setPauseOnEvent(this.pauseAllCheck.isSelected());
+ }
+ }
+
+
+ }
+}
diff --git a/gui/EventLogPanel.java b/gui/EventLogPanel.java
index 2ada1ed67..f94c7faf2 100644
--- a/gui/EventLogPanel.java
+++ b/gui/EventLogPanel.java
@@ -1,9 +1,9 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package gui;
-
+package gui;
+
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
@@ -25,308 +25,308 @@
import core.MessageListener;
import core.Settings;
import core.SimClock;
-
-/**
- * Event log panel where log entries are displayed.
- */
-public class EventLogPanel extends JPanel
- implements ConnectionListener, MessageListener, ActionListener {
+
+/**
+ * Event log panel where log entries are displayed.
+ */
+public class EventLogPanel extends JPanel
+ implements ConnectionListener, MessageListener, ActionListener {
/** Event log panel settings namespace ({@value}) */
public static final String EL_PANEL_NS = "GUI.EventLogPanel";
-
+
/** Number of events -setting id ({@value}). Defines the number of
* events to show in the panel. */
public static final String NROF_EVENTS_S = "nrofEvents";
-
+
/** Regular expression filter -setting id ({@value}). Defines the regular
* expression against which the event texts are matched; only matching
* events are not shown */
public static final String EVENTS_RE_S = "REfilter";
-
- private static final String PANEL_TITLE = "Event log";
- /** format of a single log entry */
- private static final String ENTRY_FORMAT = "% 9.1f: %s ";
- private static final int FONT_SIZE = 12;
- private static final String FONT_TYPE = "monospaced";
- private static final Color LOG_BUTTON_BG = Color.WHITE;
+
+ private static final String PANEL_TITLE = "Event log";
+ /** format of a single log entry */
+ private static final String ENTRY_FORMAT = "% 9.1f: %s ";
+ private static final int FONT_SIZE = 12;
+ private static final String FONT_TYPE = "monospaced";
+ private static final Color LOG_BUTTON_BG = Color.WHITE;
private static final String HOST_DELIM = "<->";
- private static final Color HIGHLIGHT_BG_COLOR = Color.GREEN;
-
- // constants used for button property
- private static final String HOST_PROP = "host";
- private static final String MSG_PROP = "message";
-
- /** How often the log is updated (milliseconds) */
- public static final int LOG_UP_INTERVAL = 500;
-
- /** Regular expression to filter log entries (changed trough Settings) */
+ private static final Color HIGHLIGHT_BG_COLOR = Color.GREEN;
+
+ // constants used for button property
+ private static final String HOST_PROP = "host";
+ private static final String MSG_PROP = "message";
+
+ /** How often the log is updated (milliseconds) */
+ public static final int LOG_UP_INTERVAL = 500;
+
+ /** Regular expression to filter log entries (changed trough Settings) */
private String regExp = null;
- public static final int DEFAULT_MAX_NROF_EVENTS = 30;
- /** how many events to show in log (changed trough Settings) */
- private int maxNrofEvents;
-
- private Font font; // font used in log entries
- private DTNSimGUI gui;
- private Vector eventPanes;
- private GridLayout layout;
-
- private EventLogControlPanel controls;
- private EventLogControl conUpCheck;
- private EventLogControl conDownCheck;
- private EventLogControl msgCreateCheck;
- private EventLogControl msgTransferStartCheck;
- private EventLogControl msgRelayCheck;
- private EventLogControl msgRemoveCheck;
- private EventLogControl msgDeliveredCheck;
- private EventLogControl msgDropCheck;
- private EventLogControl msgAbortCheck;
-
- /**
- * Creates a new log panel
- * @param gui The where this log belongs to (for callbacks)
- */
- public EventLogPanel(DTNSimGUI gui) {
- this.gui = gui;
- String title = PANEL_TITLE;
- Settings s = new Settings(EL_PANEL_NS);
-
+ public static final int DEFAULT_MAX_NROF_EVENTS = 30;
+ /** how many events to show in log (changed trough Settings) */
+ private int maxNrofEvents;
+
+ private Font font; // font used in log entries
+ private DTNSimGUI gui;
+ private Vector eventPanes;
+ private GridLayout layout;
+
+ private EventLogControlPanel controls;
+ private EventLogControl conUpCheck;
+ private EventLogControl conDownCheck;
+ private EventLogControl msgCreateCheck;
+ private EventLogControl msgTransferStartCheck;
+ private EventLogControl msgRelayCheck;
+ private EventLogControl msgRemoveCheck;
+ private EventLogControl msgDeliveredCheck;
+ private EventLogControl msgDropCheck;
+ private EventLogControl msgAbortCheck;
+
+ /**
+ * Creates a new log panel
+ * @param gui The where this log belongs to (for callbacks)
+ */
+ public EventLogPanel(DTNSimGUI gui) {
+ this.gui = gui;
+ String title = PANEL_TITLE;
+ Settings s = new Settings(EL_PANEL_NS);
+
this.maxNrofEvents = s.getInt(NROF_EVENTS_S,
DEFAULT_MAX_NROF_EVENTS);
- this.regExp = s.getSetting(EVENTS_RE_S, null);
-
- layout = new GridLayout(maxNrofEvents,1);
-
- this.setLayout(layout);
- if (this.regExp != null) {
- title += " - RE-filter: " + regExp;
- }
- this.setBorder(BorderFactory.createTitledBorder(
- getBorder(), title));
-
- this.eventPanes = new Vector(maxNrofEvents);
- this.font = new Font(FONT_TYPE,Font.PLAIN, FONT_SIZE);
- this.controls = createControls();
-
- // set log view to update every LOG_UP_INTERVAL milliseconds
- // also ensures that the update is done in Swing's EDT
- ActionListener taskPerformer = new ActionListener() {
- public void actionPerformed(ActionEvent evt) {
- updateLogView();
- }
- };
- Timer t = new Timer(LOG_UP_INTERVAL, taskPerformer);
- t.start();
- }
-
- /**
- * Creates a control panel for the log
- * @return The created EventLogControls
- */
- private EventLogControlPanel createControls() {
- EventLogControlPanel c = new EventLogControlPanel();
- c.addHeading("connections");
- conUpCheck = c.addControl("up");
- conDownCheck = c.addControl("down");
- c.addHeading("messages");
- msgCreateCheck = c.addControl("created");
- msgTransferStartCheck = c.addControl("started relay");
- msgRelayCheck = c.addControl("relayed");
- msgDeliveredCheck = c.addControl("delivered");
- msgRemoveCheck = c.addControl("removed");
- msgDropCheck = c.addControl("dropped");
- msgAbortCheck = c.addControl("aborted");
- return c;
- }
-
- /**
- * Returns the control panel that this log uses
- * @return The control panel
- */
- public EventLogControlPanel getControls() {
- return this.controls;
- }
-
- /**
- * Adds a new event to the event log panel
- * @param description Textual description of the event
- * @param host1 Host that caused the event or null if there was not any
- * @param host2 Another host that was involved in the event (or null)
+ this.regExp = s.getSetting(EVENTS_RE_S, null);
+
+ layout = new GridLayout(maxNrofEvents,1);
+
+ this.setLayout(layout);
+ if (this.regExp != null) {
+ title += " - RE-filter: " + regExp;
+ }
+ this.setBorder(BorderFactory.createTitledBorder(
+ getBorder(), title));
+
+ this.eventPanes = new Vector(maxNrofEvents);
+ this.font = new Font(FONT_TYPE,Font.PLAIN, FONT_SIZE);
+ this.controls = createControls();
+
+ // set log view to update every LOG_UP_INTERVAL milliseconds
+ // also ensures that the update is done in Swing's EDT
+ ActionListener taskPerformer = new ActionListener() {
+ public void actionPerformed(ActionEvent evt) {
+ updateLogView();
+ }
+ };
+ Timer t = new Timer(LOG_UP_INTERVAL, taskPerformer);
+ t.start();
+ }
+
+ /**
+ * Creates a control panel for the log
+ * @return The created EventLogControls
+ */
+ private EventLogControlPanel createControls() {
+ EventLogControlPanel c = new EventLogControlPanel();
+ c.addHeading("connections");
+ conUpCheck = c.addControl("up");
+ conDownCheck = c.addControl("down");
+ c.addHeading("messages");
+ msgCreateCheck = c.addControl("created");
+ msgTransferStartCheck = c.addControl("started relay");
+ msgRelayCheck = c.addControl("relayed");
+ msgDeliveredCheck = c.addControl("delivered");
+ msgRemoveCheck = c.addControl("removed");
+ msgDropCheck = c.addControl("dropped");
+ msgAbortCheck = c.addControl("aborted");
+ return c;
+ }
+
+ /**
+ * Returns the control panel that this log uses
+ * @return The control panel
+ */
+ public EventLogControlPanel getControls() {
+ return this.controls;
+ }
+
+ /**
+ * Adds a new event to the event log panel
+ * @param description Textual description of the event
+ * @param host1 Host that caused the event or null if there was not any
+ * @param host2 Another host that was involved in the event (or null)
* @param message Message that was involved in the event (or null)
- * @param highlight If true, the log entry is highlighted
- */
- private void addEvent(String description, DTNHost host1,
- DTNHost host2, Message message, boolean highlight) {
- JPanel eventPane = new JPanel();
- eventPane.setLayout(new BoxLayout(eventPane,BoxLayout.LINE_AXIS));
-
- String text = String.format(ENTRY_FORMAT,
- SimClock.getTime(),description);
- JLabel label = new JLabel(text);
- label.setFont(font);
- eventPane.add(label);
-
- if (host1 != null) {
- addInfoButton(eventPane,host1,HOST_PROP);
- }
- if (host2 != null) {
- JLabel betweenLabel = new JLabel(HOST_DELIM);
- betweenLabel.setFont(font);
- eventPane.add(betweenLabel);
- addInfoButton(eventPane,host2,HOST_PROP);
- }
- if (message != null) {
- addInfoButton(eventPane, message, MSG_PROP);
- }
+ * @param highlight If true, the log entry is highlighted
+ */
+ private void addEvent(String description, DTNHost host1,
+ DTNHost host2, Message message, boolean highlight) {
+ JPanel eventPane = new JPanel();
+ eventPane.setLayout(new BoxLayout(eventPane,BoxLayout.LINE_AXIS));
+
+ String text = String.format(ENTRY_FORMAT,
+ SimClock.getTime(),description);
+ JLabel label = new JLabel(text);
+ label.setFont(font);
+ eventPane.add(label);
+
+ if (host1 != null) {
+ addInfoButton(eventPane,host1,HOST_PROP);
+ }
+ if (host2 != null) {
+ JLabel betweenLabel = new JLabel(HOST_DELIM);
+ betweenLabel.setFont(font);
+ eventPane.add(betweenLabel);
+ addInfoButton(eventPane,host2,HOST_PROP);
+ }
+ if (message != null) {
+ addInfoButton(eventPane, message, MSG_PROP);
+ }
if (highlight) {
eventPane.setBackground(HIGHLIGHT_BG_COLOR);
}
-
- eventPanes.add(eventPane);
-
- // if the log is full, remove oldest entries first
- if (this.eventPanes.size() > maxNrofEvents) {
- eventPanes.remove(0);
- }
- }
-
- /**
- * Updates the log view
- */
- private void updateLogView() {
- //TODO Optimization: Check if update is really necessary
- this.removeAll();
- for (int i=0; i< this.eventPanes.size(); i++) {
- this.add(eventPanes.get(i));
- }
- revalidate();
- }
-
-
- /**
- * Adds a new button to a log entry panel and attaches a client
- * property into it
- * @param panel Panel where to add the button
- * @param o Client property object to add
- * @param clientProp Client property key to use for the object
- */
- private void addInfoButton(JPanel panel, Object o, String clientProp) {
- JButton hButton;
- hButton = new JButton(o.toString());
- hButton.putClientProperty(clientProp, o);
- hButton.addActionListener(this);
- hButton.setFont(font);
- hButton.setMargin(new Insets(0,0,0,0));
- hButton.setBackground(LOG_BUTTON_BG);
- panel.add(hButton);
- }
-
- /**
- * Processes a log event
- * @param check EventLogControls used to check if this entry type should
- * be shown and/or paused upon
- * @param name Text description of the event
- * @param host1 First host involved in the event (if any, can be null)
- * @param host2 Second host involved in the event (if any, can be null)
- * @param message The message involved in the event (if any, can be null)
- */
- private void processEvent(EventLogControl check, final String name,
- final DTNHost host1, final DTNHost host2, final Message message) {
- String descString; // String format description of the event
-
- if (!check.showEvent()) {
- return; // if event's "show" is not checked, won't pause either
- }
-
- descString = name + " " +
- (host1!=null ? host1 : "") +
- (host2!= null ? (HOST_DELIM + host2) : "") +
- (message!=null ? " " + message : "");
-
- if (regExp != null && !descString.matches(regExp)){
- return; // description doesn't match defined regular expression
- }
-
- if (check.pauseOnEvent()) {
- gui.setPaused(true);
- if (host1 != null) {
- gui.setFocus(host1);
- }
- }
-
- addEvent(name, host1, host2, message, check.pauseOnEvent());
- }
-
- // Implementations of ConnectionListener and MessageListener interfaces
- public void hostsConnected(DTNHost host1, DTNHost host2) {
- processEvent(conUpCheck, "Connection UP", host1, host2, null);
- }
-
- public void hostsDisconnected(DTNHost host1, DTNHost host2) {
- processEvent(conDownCheck, "Connection DOWN", host1, host2, null);
- }
-
- public void messageDeleted(Message m, DTNHost where, boolean dropped) {
- if (!dropped) {
- processEvent(msgRemoveCheck, "Message removed", where, null, m);
- }
- else {
- processEvent(msgDropCheck, "Message dropped", where, null, m);
- }
- }
-
- public void messageTransferred(Message m, DTNHost from, DTNHost to,
- boolean firstDelivery) {
- if (firstDelivery) {
- processEvent(msgDeliveredCheck, "Message delivered", from, to, m);
- }
- else if (to == m.getTo()) {
- processEvent(msgDeliveredCheck, "Message delivered again",
- from, to, m);
- }
- else {
- processEvent(msgRelayCheck, "Message relayed", from, to, m);
- }
- }
-
- public void newMessage(Message m) {
- processEvent(msgCreateCheck, "Message created", m.getFrom(), null, m);
- }
-
- public void messageTransferAborted(Message m, DTNHost from, DTNHost to) {
- processEvent(msgAbortCheck, "Message relay aborted", from, to, m);
- }
-
- public void messageTransferStarted(Message m, DTNHost from, DTNHost to) {
- processEvent(msgTransferStartCheck,"Message relay started", from,
- to,m);
-
- }
-
- // end of message interface implementations
-
-
- /**
- * Action listener for log entry (host & message) buttons
- */
- public void actionPerformed(ActionEvent e) {
- JButton source = (JButton)e.getSource();
-
- if (source.getClientProperty(HOST_PROP) != null) {
- // button was a host button -> focus it on GUI
- gui.setFocus((DTNHost)source.getClientProperty(HOST_PROP));
- }
- else if (source.getClientProperty(MSG_PROP) != null) {
- // was a message button -> show information about the message
- Message m = (Message)source.getClientProperty(MSG_PROP);
- gui.getInfoPanel().showInfo(m);
- }
- }
-
- public String toString() {
- return this.getClass().getSimpleName() + " with " +
- this.eventPanes.size() + " events";
- }
-
-}
+
+ eventPanes.add(eventPane);
+
+ // if the log is full, remove oldest entries first
+ if (this.eventPanes.size() > maxNrofEvents) {
+ eventPanes.remove(0);
+ }
+ }
+
+ /**
+ * Updates the log view
+ */
+ private void updateLogView() {
+ //TODO Optimization: Check if update is really necessary
+ this.removeAll();
+ for (int i=0; i< this.eventPanes.size(); i++) {
+ this.add(eventPanes.get(i));
+ }
+ revalidate();
+ }
+
+
+ /**
+ * Adds a new button to a log entry panel and attaches a client
+ * property into it
+ * @param panel Panel where to add the button
+ * @param o Client property object to add
+ * @param clientProp Client property key to use for the object
+ */
+ private void addInfoButton(JPanel panel, Object o, String clientProp) {
+ JButton hButton;
+ hButton = new JButton(o.toString());
+ hButton.putClientProperty(clientProp, o);
+ hButton.addActionListener(this);
+ hButton.setFont(font);
+ hButton.setMargin(new Insets(0,0,0,0));
+ hButton.setBackground(LOG_BUTTON_BG);
+ panel.add(hButton);
+ }
+
+ /**
+ * Processes a log event
+ * @param check EventLogControls used to check if this entry type should
+ * be shown and/or paused upon
+ * @param name Text description of the event
+ * @param host1 First host involved in the event (if any, can be null)
+ * @param host2 Second host involved in the event (if any, can be null)
+ * @param message The message involved in the event (if any, can be null)
+ */
+ private void processEvent(EventLogControl check, final String name,
+ final DTNHost host1, final DTNHost host2, final Message message) {
+ String descString; // String format description of the event
+
+ if (!check.showEvent()) {
+ return; // if event's "show" is not checked, won't pause either
+ }
+
+ descString = name + " " +
+ (host1!=null ? host1 : "") +
+ (host2!= null ? (HOST_DELIM + host2) : "") +
+ (message!=null ? " " + message : "");
+
+ if (regExp != null && !descString.matches(regExp)){
+ return; // description doesn't match defined regular expression
+ }
+
+ if (check.pauseOnEvent()) {
+ gui.setPaused(true);
+ if (host1 != null) {
+ gui.setFocus(host1);
+ }
+ }
+
+ addEvent(name, host1, host2, message, check.pauseOnEvent());
+ }
+
+ // Implementations of ConnectionListener and MessageListener interfaces
+ public void hostsConnected(DTNHost host1, DTNHost host2) {
+ processEvent(conUpCheck, "Connection UP", host1, host2, null);
+ }
+
+ public void hostsDisconnected(DTNHost host1, DTNHost host2) {
+ processEvent(conDownCheck, "Connection DOWN", host1, host2, null);
+ }
+
+ public void messageDeleted(Message m, DTNHost where, boolean dropped) {
+ if (!dropped) {
+ processEvent(msgRemoveCheck, "Message removed", where, null, m);
+ }
+ else {
+ processEvent(msgDropCheck, "Message dropped", where, null, m);
+ }
+ }
+
+ public void messageTransferred(Message m, DTNHost from, DTNHost to,
+ boolean firstDelivery) {
+ if (firstDelivery) {
+ processEvent(msgDeliveredCheck, "Message delivered", from, to, m);
+ }
+ else if (to == m.getTo()) {
+ processEvent(msgDeliveredCheck, "Message delivered again",
+ from, to, m);
+ }
+ else {
+ processEvent(msgRelayCheck, "Message relayed", from, to, m);
+ }
+ }
+
+ public void newMessage(Message m) {
+ processEvent(msgCreateCheck, "Message created", m.getFrom(), null, m);
+ }
+
+ public void messageTransferAborted(Message m, DTNHost from, DTNHost to) {
+ processEvent(msgAbortCheck, "Message relay aborted", from, to, m);
+ }
+
+ public void messageTransferStarted(Message m, DTNHost from, DTNHost to) {
+ processEvent(msgTransferStartCheck,"Message relay started", from,
+ to,m);
+
+ }
+
+ // end of message interface implementations
+
+
+ /**
+ * Action listener for log entry (host & message) buttons
+ */
+ public void actionPerformed(ActionEvent e) {
+ JButton source = (JButton)e.getSource();
+
+ if (source.getClientProperty(HOST_PROP) != null) {
+ // button was a host button -> focus it on GUI
+ gui.setFocus((DTNHost)source.getClientProperty(HOST_PROP));
+ }
+ else if (source.getClientProperty(MSG_PROP) != null) {
+ // was a message button -> show information about the message
+ Message m = (Message)source.getClientProperty(MSG_PROP);
+ gui.getInfoPanel().showInfo(m);
+ }
+ }
+
+ public String toString() {
+ return this.getClass().getSimpleName() + " with " +
+ this.eventPanes.size() + " events";
+ }
+
+}
diff --git a/gui/GUIControls.java b/gui/GUIControls.java
index d10dccad9..27fb470a9 100644
--- a/gui/GUIControls.java
+++ b/gui/GUIControls.java
@@ -1,9 +1,9 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package gui;
-
+package gui;
+
import gui.playfield.PlayField;
import java.awt.FlowLayout;
@@ -30,266 +30,266 @@
import core.Coord;
import core.SimClock;
-
-/**
- * GUI's control panel
- *
- */
-public class GUIControls extends JPanel implements ActionListener, ChangeListener {
- private static final String PATH_GRAPHICS = "buttonGraphics/";
- private static final String ICON_PAUSE = "Pause16.gif";
- private static final String ICON_PLAY = "Play16.gif";
- private static final String ICON_ZOOM = "Zoom24.gif";
- private static final String ICON_STEP = "StepForward16.gif";
- private static final String ICON_FFW = "FastForward16.gif";
-
- private static final String TEXT_PAUSE = "pause simulation";
- private static final String TEXT_PLAY = "play simulation";
- private static final String TEXT_PLAY_UNTIL = "play simulation until sim time...";
- private static final String TEXT_STEP = "step forward one interval";
- private static final String TEXT_FFW = "enable/disable fast forward";
- private static final String TEXT_UP_CHOOSER = "GUI update:";
- private static final String TEXT_SCREEN_SHOT = "screen shot";
- private static final String TEXT_SIMTIME = "Simulation time - "+
- "click to force update, right click to change format";
- private static final String TEXT_SEPS = "simulated seconds per second";
-
- // "simulated events per second" averaging time (milliseconds)
- private static final int EPS_AVG_TIME = 2000;
- private static final String SCREENSHOT_FILE_TYPE = "png";
- private static final String SCREENSHOT_FILE = "screenshot";
-
- private JTextField simTimeField;
- private JLabel sepsField; // simulated events per second field
- private JButton playButton;
- private JButton playUntilButton;
- private boolean paused;
- private JButton stepButton;
- private boolean step;
- private JButton ffwButton;
- private boolean isFfw;
- private int oldSpeedIndex; // what speed was selected before FFW
-
- private JButton screenShotButton;
- private JComboBox guiUpdateChooser;
-
- /**
- * GUI update speeds. Negative values -> how many 1/10 seconds to wait
- * between updates. Positive values -> show every Nth update
- */
- public static final String[] UP_SPEEDS = {"-10", "-1", "0.1", "1", "10",
- "100", "1000", "10000", "100000"};
-
+
+/**
+ * GUI's control panel
+ *
+ */
+public class GUIControls extends JPanel implements ActionListener, ChangeListener {
+ private static final String PATH_GRAPHICS = "buttonGraphics/";
+ private static final String ICON_PAUSE = "Pause16.gif";
+ private static final String ICON_PLAY = "Play16.gif";
+ private static final String ICON_ZOOM = "Zoom24.gif";
+ private static final String ICON_STEP = "StepForward16.gif";
+ private static final String ICON_FFW = "FastForward16.gif";
+
+ private static final String TEXT_PAUSE = "pause simulation";
+ private static final String TEXT_PLAY = "play simulation";
+ private static final String TEXT_PLAY_UNTIL = "play simulation until sim time...";
+ private static final String TEXT_STEP = "step forward one interval";
+ private static final String TEXT_FFW = "enable/disable fast forward";
+ private static final String TEXT_UP_CHOOSER = "GUI update:";
+ private static final String TEXT_SCREEN_SHOT = "screen shot";
+ private static final String TEXT_SIMTIME = "Simulation time - "+
+ "click to force update, right click to change format";
+ private static final String TEXT_SEPS = "simulated seconds per second";
+
+ // "simulated events per second" averaging time (milliseconds)
+ private static final int EPS_AVG_TIME = 2000;
+ private static final String SCREENSHOT_FILE_TYPE = "png";
+ private static final String SCREENSHOT_FILE = "screenshot";
+
+ private JTextField simTimeField;
+ private JLabel sepsField; // simulated events per second field
+ private JButton playButton;
+ private JButton playUntilButton;
+ private boolean paused;
+ private JButton stepButton;
+ private boolean step;
+ private JButton ffwButton;
+ private boolean isFfw;
+ private int oldSpeedIndex; // what speed was selected before FFW
+
+ private JButton screenShotButton;
+ private JComboBox guiUpdateChooser;
+
+ /**
+ * GUI update speeds. Negative values -> how many 1/10 seconds to wait
+ * between updates. Positive values -> show every Nth update
+ */
+ public static final String[] UP_SPEEDS = {"-10", "-1", "0.1", "1", "10",
+ "100", "1000", "10000", "100000"};
+
/** Smallest value for the zoom level */
public static final double ZOOM_MIN = 0.001;
/** Highest value for the zoom level */
public static final double ZOOM_MAX = 10;
-
- /** index of initial update speed setting */
- public static final int INITIAL_SPEED_SELECTION = 3;
- /** index of FFW speed setting */
- public static final int FFW_SPEED_INDEX = 7;
-
- private double guiUpdateInterval;
- private javax.swing.JSpinner zoomSelector;
-
- private PlayField pf;
- private DTNSimGUI gui;
-
- private long lastUpdate;
- private double lastSimTime;
- private double playUntilTime;
-
+
+ /** index of initial update speed setting */
+ public static final int INITIAL_SPEED_SELECTION = 3;
+ /** index of FFW speed setting */
+ public static final int FFW_SPEED_INDEX = 7;
+
+ private double guiUpdateInterval;
+ private javax.swing.JSpinner zoomSelector;
+
+ private PlayField pf;
+ private DTNSimGUI gui;
+
+ private long lastUpdate;
+ private double lastSimTime;
+ private double playUntilTime;
+
private boolean useHourDisplay = false;
-
+
public GUIControls(DTNSimGUI gui, PlayField pf) {
- /* TODO: read values for paused, isFfw etc from a file */
- this.pf = pf;
- this.gui = gui;
- this.lastUpdate = System.currentTimeMillis();
- this.lastSimTime = 0;
- this.paused = true;
- this.isFfw = false;
- this.playUntilTime = Double.MAX_VALUE;
- initPanel();
- }
-
- /**
- * Creates panel's components and initializes them
- */
- private void initPanel() {
- this.setLayout(new FlowLayout());
- this.simTimeField = new JTextField("0.0");
- this.simTimeField.setColumns(6);
- this.simTimeField.setEditable(false);
- this.simTimeField.setToolTipText(TEXT_SIMTIME);
- this.simTimeField.addMouseListener(new MouseAdapter(){
+ /* TODO: read values for paused, isFfw etc from a file */
+ this.pf = pf;
+ this.gui = gui;
+ this.lastUpdate = System.currentTimeMillis();
+ this.lastSimTime = 0;
+ this.paused = true;
+ this.isFfw = false;
+ this.playUntilTime = Double.MAX_VALUE;
+ initPanel();
+ }
+
+ /**
+ * Creates panel's components and initializes them
+ */
+ private void initPanel() {
+ this.setLayout(new FlowLayout());
+ this.simTimeField = new JTextField("0.0");
+ this.simTimeField.setColumns(6);
+ this.simTimeField.setEditable(false);
+ this.simTimeField.setToolTipText(TEXT_SIMTIME);
+ this.simTimeField.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e) {
- if (e.getButton() == MouseEvent.BUTTON3) {
+ if (e.getButton() == MouseEvent.BUTTON3) {
useHourDisplay = !useHourDisplay;
- }
- setSimTime(SimClock.getTime());
- }
- });
-
- this.sepsField = new JLabel("0.00");
- this.sepsField.setToolTipText(TEXT_SEPS);
-
- this.screenShotButton = new JButton(TEXT_SCREEN_SHOT);
- this.guiUpdateChooser = new JComboBox(UP_SPEEDS);
-
- this.zoomSelector = new JSpinner(new SpinnerNumberModel(1.0, ZOOM_MIN,
- ZOOM_MAX, 0.001));
-
- this.add(simTimeField);
+ }
+ setSimTime(SimClock.getTime());
+ }
+ });
+
+ this.sepsField = new JLabel("0.00");
+ this.sepsField.setToolTipText(TEXT_SEPS);
+
+ this.screenShotButton = new JButton(TEXT_SCREEN_SHOT);
+ this.guiUpdateChooser = new JComboBox(UP_SPEEDS);
+
+ this.zoomSelector = new JSpinner(new SpinnerNumberModel(1.0, ZOOM_MIN,
+ ZOOM_MAX, 0.001));
+
+ this.add(simTimeField);
this.add(sepsField);
-
- playButton = addButton(paused ? ICON_PLAY : ICON_PAUSE,
- paused ? TEXT_PLAY : TEXT_PAUSE);
- stepButton = addButton(ICON_STEP, TEXT_STEP);
- ffwButton = addButton(ICON_FFW, TEXT_FFW);
- playUntilButton = addButton(ICON_PLAY, TEXT_PLAY_UNTIL);
- playUntilButton.setText("...");
-
- this.add(new JLabel(TEXT_UP_CHOOSER));
- this.add(this.guiUpdateChooser);
- this.guiUpdateChooser.setSelectedIndex(INITIAL_SPEED_SELECTION);
- this.updateUpdateInterval();
-
- this.add(new JLabel(createImageIcon(ICON_ZOOM)));
- this.updateZoomScale(false);
-
- this.add(this.zoomSelector);
- this.add(this.screenShotButton);
-
- guiUpdateChooser.addActionListener(this);
- zoomSelector.addChangeListener(this);
- this.screenShotButton.addActionListener(this);
- }
-
-
- private ImageIcon createImageIcon(String path) {
- java.net.URL imgURL = getClass().getResource(PATH_GRAPHICS+path);
- return new ImageIcon(imgURL);
- }
-
-
- private JButton addButton(String iconPath, String tooltip) {
- JButton button = new JButton(createImageIcon(iconPath));
- button.setToolTipText(tooltip);
- button.addActionListener(this);
- this.add(button);
- return button;
- }
-
- /**
- * Sets the simulation time that control panel shows
- * @param time The time to show
- */
- public void setSimTime(double time) {
- long timeSinceUpdate = System.currentTimeMillis() - this.lastUpdate;
-
- if (timeSinceUpdate > EPS_AVG_TIME) {
- double val = ((time - this.lastSimTime) * 1000)/timeSinceUpdate;
- String sepsValue = String.format("%.2f 1/s", val);
-
- this.sepsField.setText(sepsValue);
- this.lastSimTime = time;
- this.lastUpdate = System.currentTimeMillis();
- }
-
+
+ playButton = addButton(paused ? ICON_PLAY : ICON_PAUSE,
+ paused ? TEXT_PLAY : TEXT_PAUSE);
+ stepButton = addButton(ICON_STEP, TEXT_STEP);
+ ffwButton = addButton(ICON_FFW, TEXT_FFW);
+ playUntilButton = addButton(ICON_PLAY, TEXT_PLAY_UNTIL);
+ playUntilButton.setText("...");
+
+ this.add(new JLabel(TEXT_UP_CHOOSER));
+ this.add(this.guiUpdateChooser);
+ this.guiUpdateChooser.setSelectedIndex(INITIAL_SPEED_SELECTION);
+ this.updateUpdateInterval();
+
+ this.add(new JLabel(createImageIcon(ICON_ZOOM)));
+ this.updateZoomScale(false);
+
+ this.add(this.zoomSelector);
+ this.add(this.screenShotButton);
+
+ guiUpdateChooser.addActionListener(this);
+ zoomSelector.addChangeListener(this);
+ this.screenShotButton.addActionListener(this);
+ }
+
+
+ private ImageIcon createImageIcon(String path) {
+ java.net.URL imgURL = getClass().getResource(PATH_GRAPHICS+path);
+ return new ImageIcon(imgURL);
+ }
+
+
+ private JButton addButton(String iconPath, String tooltip) {
+ JButton button = new JButton(createImageIcon(iconPath));
+ button.setToolTipText(tooltip);
+ button.addActionListener(this);
+ this.add(button);
+ return button;
+ }
+
+ /**
+ * Sets the simulation time that control panel shows
+ * @param time The time to show
+ */
+ public void setSimTime(double time) {
+ long timeSinceUpdate = System.currentTimeMillis() - this.lastUpdate;
+
+ if (timeSinceUpdate > EPS_AVG_TIME) {
+ double val = ((time - this.lastSimTime) * 1000)/timeSinceUpdate;
+ String sepsValue = String.format("%.2f 1/s", val);
+
+ this.sepsField.setText(sepsValue);
+ this.lastSimTime = time;
+ this.lastUpdate = System.currentTimeMillis();
+ }
+
if (this.useHourDisplay) {
int hours = (int)(time / 3600);
int mins = (int)((time - hours * 3600) / 60);
double secs = time % 60;
this.simTimeField.setText(String.format("%02d:%02d:%02.1f",
hours, mins, secs));
- } else {
+ } else {
this.simTimeField.setText(String.format("%.1f", time));
- }
- }
-
- /**
- * Sets simulation to pause or play.
- * @param paused If true, simulation is put to pause
- */
- public void setPaused(boolean paused) {
- if (!paused) {
- this.playButton.setIcon(createImageIcon(ICON_PAUSE));
- this.playButton.setToolTipText(TEXT_PAUSE);
- this.paused = false;
- if (SimClock.getTime() >= this.playUntilTime) {
- // playUntilTime passed -> disable it
- this.playUntilTime = Double.MAX_VALUE;
- }
- }
- else {
- this.playButton.setIcon(createImageIcon(ICON_PLAY));
- this.playButton.setToolTipText(TEXT_PLAY);
- this.paused = true;
- this.setSimTime(SimClock.getTime());
- this.pf.updateField();
- }
- }
-
- private void switchFfw() {
- if (isFfw) {
- this.isFfw = false; // set to normal play
- this.ffwButton.setIcon(createImageIcon(ICON_FFW));
- this.guiUpdateChooser.setSelectedIndex(oldSpeedIndex);
- this.ffwButton.setSelected(false);
- }
- else {
- this.oldSpeedIndex = this.guiUpdateChooser.getSelectedIndex();
- this.guiUpdateChooser.setSelectedIndex(FFW_SPEED_INDEX);
- this.isFfw = true; // set to FFW
- this.ffwButton.setIcon(createImageIcon(ICON_PLAY));
- }
- }
-
- /**
- * Has user requested the simulation to be paused
- * @return True if pause is requested
- */
- public boolean isPaused() {
- if (step) { // if we want to step, return false once and reset stepping
- step = false;
- return false;
- }
- if (SimClock.getTime() >= this.playUntilTime) {
- this.setPaused(true);
- }
- return this.paused;
- }
-
- /**
- * Is fast forward turned on
- * @return True if FFW is on, false if not
- */
- public boolean isFfw() {
- return this.isFfw;
- }
-
- /**
- * Returns the selected update interval of GUI
- * @return The update interval (seconds)
- */
- public double getUpdateInterval() {
- return this.guiUpdateInterval;
- }
-
- /**
- * Changes the zoom level
- * @param delta How much to change the current level (can be negative or
- * positive)
- */
- public void changeZoom(int delta) {
- SpinnerNumberModel model =
+ }
+ }
+
+ /**
+ * Sets simulation to pause or play.
+ * @param paused If true, simulation is put to pause
+ */
+ public void setPaused(boolean paused) {
+ if (!paused) {
+ this.playButton.setIcon(createImageIcon(ICON_PAUSE));
+ this.playButton.setToolTipText(TEXT_PAUSE);
+ this.paused = false;
+ if (SimClock.getTime() >= this.playUntilTime) {
+ // playUntilTime passed -> disable it
+ this.playUntilTime = Double.MAX_VALUE;
+ }
+ }
+ else {
+ this.playButton.setIcon(createImageIcon(ICON_PLAY));
+ this.playButton.setToolTipText(TEXT_PLAY);
+ this.paused = true;
+ this.setSimTime(SimClock.getTime());
+ this.pf.updateField();
+ }
+ }
+
+ private void switchFfw() {
+ if (isFfw) {
+ this.isFfw = false; // set to normal play
+ this.ffwButton.setIcon(createImageIcon(ICON_FFW));
+ this.guiUpdateChooser.setSelectedIndex(oldSpeedIndex);
+ this.ffwButton.setSelected(false);
+ }
+ else {
+ this.oldSpeedIndex = this.guiUpdateChooser.getSelectedIndex();
+ this.guiUpdateChooser.setSelectedIndex(FFW_SPEED_INDEX);
+ this.isFfw = true; // set to FFW
+ this.ffwButton.setIcon(createImageIcon(ICON_PLAY));
+ }
+ }
+
+ /**
+ * Has user requested the simulation to be paused
+ * @return True if pause is requested
+ */
+ public boolean isPaused() {
+ if (step) { // if we want to step, return false once and reset stepping
+ step = false;
+ return false;
+ }
+ if (SimClock.getTime() >= this.playUntilTime) {
+ this.setPaused(true);
+ }
+ return this.paused;
+ }
+
+ /**
+ * Is fast forward turned on
+ * @return True if FFW is on, false if not
+ */
+ public boolean isFfw() {
+ return this.isFfw;
+ }
+
+ /**
+ * Returns the selected update interval of GUI
+ * @return The update interval (seconds)
+ */
+ public double getUpdateInterval() {
+ return this.guiUpdateInterval;
+ }
+
+ /**
+ * Changes the zoom level
+ * @param delta How much to change the current level (can be negative or
+ * positive)
+ */
+ public void changeZoom(int delta) {
+ SpinnerNumberModel model =
(SpinnerNumberModel)this.zoomSelector.getModel();
double curZoom = model.getNumber().doubleValue();
Number newValue = new Double(curZoom + model.getStepSize().
- doubleValue() * delta * curZoom * 100);
-
+ doubleValue() * delta * curZoom * 100);
+
if (newValue.doubleValue() < ZOOM_MIN) {
newValue = ZOOM_MIN;
} else if (newValue.doubleValue() > ZOOM_MAX) {
@@ -297,100 +297,100 @@ public void changeZoom(int delta) {
}
model.setValue(newValue);
- this.updateZoomScale(true);
- }
-
-
- public void actionPerformed(ActionEvent e) {
- if (e.getSource() == this.playButton) {
- setPaused(!this.paused); // switch pause/play
- }
- else if (e.getSource() == this.stepButton) {
- setPaused(true);
- this.step = true;
- }
- else if (e.getSource() == this.ffwButton) {
- switchFfw();
- }
- else if (e.getSource() == this.playUntilButton) {
- setPlayUntil();
- }
- else if (e.getSource() == this.guiUpdateChooser) {
- updateUpdateInterval();
- }
- else if (e.getSource() == this.screenShotButton) {
- takeScreenShot();
- }
+ this.updateZoomScale(true);
+ }
+
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource() == this.playButton) {
+ setPaused(!this.paused); // switch pause/play
+ }
+ else if (e.getSource() == this.stepButton) {
+ setPaused(true);
+ this.step = true;
+ }
+ else if (e.getSource() == this.ffwButton) {
+ switchFfw();
+ }
+ else if (e.getSource() == this.playUntilButton) {
+ setPlayUntil();
+ }
+ else if (e.getSource() == this.guiUpdateChooser) {
+ updateUpdateInterval();
+ }
+ else if (e.getSource() == this.screenShotButton) {
+ takeScreenShot();
+ }
}
-
-
+
+
public void stateChanged(ChangeEvent e) {
updateZoomScale(true);
- }
-
-
- private void setPlayUntil() {
- setPaused(true);
- String value = JOptionPane.showInputDialog(TEXT_PLAY_UNTIL);
- if (value == null) {
- return;
- }
- try {
- this.playUntilTime = Double.parseDouble(value);
- setPaused(false);
- } catch (NumberFormatException e) {
- JOptionPane.showMessageDialog(gui.getParentFrame(),
- "Invalid number '" + value+"'",
- "error",JOptionPane.ERROR_MESSAGE);
- }
- }
-
-
- private void updateUpdateInterval() {
- String selString = (String)this.guiUpdateChooser.getSelectedItem();
- this.guiUpdateInterval = Double.parseDouble(selString);
- }
-
- /**
- * Updates zoom scale to the one selected by zoom chooser
- * @param centerView If true, the center of the viewport should remain
- * the same
- */
- private void updateZoomScale(boolean centerView) {
+ }
+
+
+ private void setPlayUntil() {
+ setPaused(true);
+ String value = JOptionPane.showInputDialog(TEXT_PLAY_UNTIL);
+ if (value == null) {
+ return;
+ }
+ try {
+ this.playUntilTime = Double.parseDouble(value);
+ setPaused(false);
+ } catch (NumberFormatException e) {
+ JOptionPane.showMessageDialog(gui.getParentFrame(),
+ "Invalid number '" + value+"'",
+ "error",JOptionPane.ERROR_MESSAGE);
+ }
+ }
+
+
+ private void updateUpdateInterval() {
+ String selString = (String)this.guiUpdateChooser.getSelectedItem();
+ this.guiUpdateInterval = Double.parseDouble(selString);
+ }
+
+ /**
+ * Updates zoom scale to the one selected by zoom chooser
+ * @param centerView If true, the center of the viewport should remain
+ * the same
+ */
+ private void updateZoomScale(boolean centerView) {
double scale = ((SpinnerNumberModel)zoomSelector.getModel()).
- getNumber().doubleValue();
-
- if (centerView) {
- Coord center = gui.getCenterViewCoord();
- this.pf.setScale(scale);
- gui.centerViewAt(center);
- }
- else {
- this.pf.setScale(scale);
- }
- }
-
- private void takeScreenShot() {
- try {
- JFileChooser fc = new JFileChooser();
- fc.setSelectedFile(new File(SCREENSHOT_FILE +
- "." + SCREENSHOT_FILE_TYPE));
- int retVal = fc.showSaveDialog(this);
- if (retVal == JFileChooser.APPROVE_OPTION) {
- File file = fc.getSelectedFile();
- BufferedImage i = new BufferedImage(this.pf.getWidth(),
- this.pf.getHeight(), BufferedImage.TYPE_INT_RGB);
- Graphics2D g2 = i.createGraphics();
-
- this.pf.paint(g2); // paint playfield to buffered image
- ImageIO.write(i, SCREENSHOT_FILE_TYPE, file);
- }
- }
- catch (Exception e) {
- JOptionPane.showMessageDialog(gui.getParentFrame(),
- "screenshot failed (problems with output file?)",
- "Exception", JOptionPane.ERROR_MESSAGE);
- }
- }
-
-}
+ getNumber().doubleValue();
+
+ if (centerView) {
+ Coord center = gui.getCenterViewCoord();
+ this.pf.setScale(scale);
+ gui.centerViewAt(center);
+ }
+ else {
+ this.pf.setScale(scale);
+ }
+ }
+
+ private void takeScreenShot() {
+ try {
+ JFileChooser fc = new JFileChooser();
+ fc.setSelectedFile(new File(SCREENSHOT_FILE +
+ "." + SCREENSHOT_FILE_TYPE));
+ int retVal = fc.showSaveDialog(this);
+ if (retVal == JFileChooser.APPROVE_OPTION) {
+ File file = fc.getSelectedFile();
+ BufferedImage i = new BufferedImage(this.pf.getWidth(),
+ this.pf.getHeight(), BufferedImage.TYPE_INT_RGB);
+ Graphics2D g2 = i.createGraphics();
+
+ this.pf.paint(g2); // paint playfield to buffered image
+ ImageIO.write(i, SCREENSHOT_FILE_TYPE, file);
+ }
+ }
+ catch (Exception e) {
+ JOptionPane.showMessageDialog(gui.getParentFrame(),
+ "screenshot failed (problems with output file?)",
+ "Exception", JOptionPane.ERROR_MESSAGE);
+ }
+ }
+
+}
diff --git a/gui/InfoPanel.java b/gui/InfoPanel.java
index c34c7a8d7..e262ba1f3 100644
--- a/gui/InfoPanel.java
+++ b/gui/InfoPanel.java
@@ -1,9 +1,9 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package gui;
-
+package gui;
+
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collections;
@@ -17,118 +17,118 @@
import movement.Path;
import core.DTNHost;
import core.Message;
-
-/**
- * Information panel that shows data of selected messages and nodes.
- */
-public class InfoPanel extends JPanel implements ActionListener{
- private JComboBox msgChooser;
- private JLabel info;
- private JButton infoButton;
- private JButton routingInfoButton;
- private Message selectedMessage;
- private DTNHost selectedHost;
- private DTNSimGUI gui;
-
- public InfoPanel(DTNSimGUI gui) {
- this.gui = gui;
- reset();
- }
-
- private void reset() {
- this.removeAll();
- this.repaint();
- this.info = null;
- this.infoButton = null;
- this.selectedMessage = null;
- }
-
- /**
- * Show information about a host
- * @param host Host to show the information of
- */
- public void showInfo(DTNHost host) {
- Vector messages =
- new Vector(host.getMessageCollection());
- Collections.sort(messages);
- reset();
- this.selectedHost = host;
- String text = (host.isMovementActive() ? "" : "INACTIVE ") + host +
- " at " + host.getLocation();
-
- msgChooser = new JComboBox(messages);
- msgChooser.insertItemAt(messages.size() + " messages", 0);
- msgChooser.setSelectedIndex(0);
- msgChooser.addActionListener(this);
-
- routingInfoButton = new JButton("routing info");
- routingInfoButton.addActionListener(this);
-
- this.add(new JLabel(text));
- this.add(msgChooser);
- this.add(routingInfoButton);
- this.revalidate();
- }
-
- /**
- * Show information about a message
- * @param message Message to show the information of
- */
- public void showInfo(Message message) {
- reset();
- this.add(new JLabel(message.toString()));
- setMessageInfo(message);
- this.revalidate();
- }
-
- private void setMessageInfo(Message m) {
- int ttl = m.getTtl();
- String txt = " [" + m.getFrom() + "->" + m.getTo() + "] " +
- "size:" + m.getSize() + ", UI:" + m.getUniqueId() +
- ", received @ " + String.format("%.2f", m.getReceiveTime());
- if (ttl != Integer.MAX_VALUE) {
- txt += " TTL: " + ttl;
- }
-
- String butTxt = "path: " + (m.getHops().size()-1) + " hops";
-
- if (this.info == null) {
- this.info = new JLabel(txt);
- this.infoButton = new JButton(butTxt);
- this.add(info);
- this.add(infoButton);
- infoButton.addActionListener(this);
- }
- else {
- this.info.setText(txt);
- this.infoButton.setText(butTxt);
- }
-
- this.selectedMessage = m;
- infoButton.setToolTipText("path:" + m.getHops());
-
- this.revalidate();
- }
-
- public void actionPerformed(ActionEvent e) {
- if (e.getSource() == msgChooser) {
- if (msgChooser.getSelectedIndex() == 0) { // title text selected
- return;
- }
- Message m = (Message)msgChooser.getSelectedItem();
- setMessageInfo(m);
- }
- else if (e.getSource() == this.infoButton) {
- Path p = new Path();
- for (DTNHost h : this.selectedMessage.getHops()) {
- p.addWaypoint(h.getLocation());
- }
-
- this.gui.showPath(p);
- }
- else if (e.getSource() == this.routingInfoButton) {
- new RoutingInfoWindow(this.selectedHost);
- }
- }
-
-}
\ No newline at end of file
+
+/**
+ * Information panel that shows data of selected messages and nodes.
+ */
+public class InfoPanel extends JPanel implements ActionListener{
+ private JComboBox msgChooser;
+ private JLabel info;
+ private JButton infoButton;
+ private JButton routingInfoButton;
+ private Message selectedMessage;
+ private DTNHost selectedHost;
+ private DTNSimGUI gui;
+
+ public InfoPanel(DTNSimGUI gui) {
+ this.gui = gui;
+ reset();
+ }
+
+ private void reset() {
+ this.removeAll();
+ this.repaint();
+ this.info = null;
+ this.infoButton = null;
+ this.selectedMessage = null;
+ }
+
+ /**
+ * Show information about a host
+ * @param host Host to show the information of
+ */
+ public void showInfo(DTNHost host) {
+ Vector messages =
+ new Vector(host.getMessageCollection());
+ Collections.sort(messages);
+ reset();
+ this.selectedHost = host;
+ String text = (host.isMovementActive() ? "" : "INACTIVE ") + host +
+ " at " + host.getLocation();
+
+ msgChooser = new JComboBox(messages);
+ msgChooser.insertItemAt(messages.size() + " messages", 0);
+ msgChooser.setSelectedIndex(0);
+ msgChooser.addActionListener(this);
+
+ routingInfoButton = new JButton("routing info");
+ routingInfoButton.addActionListener(this);
+
+ this.add(new JLabel(text));
+ this.add(msgChooser);
+ this.add(routingInfoButton);
+ this.revalidate();
+ }
+
+ /**
+ * Show information about a message
+ * @param message Message to show the information of
+ */
+ public void showInfo(Message message) {
+ reset();
+ this.add(new JLabel(message.toString()));
+ setMessageInfo(message);
+ this.revalidate();
+ }
+
+ private void setMessageInfo(Message m) {
+ int ttl = m.getTtl();
+ String txt = " [" + m.getFrom() + "->" + m.getTo() + "] " +
+ "size:" + m.getSize() + ", UI:" + m.getUniqueId() +
+ ", received @ " + String.format("%.2f", m.getReceiveTime());
+ if (ttl != Integer.MAX_VALUE) {
+ txt += " TTL: " + ttl;
+ }
+
+ String butTxt = "path: " + (m.getHops().size()-1) + " hops";
+
+ if (this.info == null) {
+ this.info = new JLabel(txt);
+ this.infoButton = new JButton(butTxt);
+ this.add(info);
+ this.add(infoButton);
+ infoButton.addActionListener(this);
+ }
+ else {
+ this.info.setText(txt);
+ this.infoButton.setText(butTxt);
+ }
+
+ this.selectedMessage = m;
+ infoButton.setToolTipText("path:" + m.getHops());
+
+ this.revalidate();
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource() == msgChooser) {
+ if (msgChooser.getSelectedIndex() == 0) { // title text selected
+ return;
+ }
+ Message m = (Message)msgChooser.getSelectedItem();
+ setMessageInfo(m);
+ }
+ else if (e.getSource() == this.infoButton) {
+ Path p = new Path();
+ for (DTNHost h : this.selectedMessage.getHops()) {
+ p.addWaypoint(h.getLocation());
+ }
+
+ this.gui.showPath(p);
+ }
+ else if (e.getSource() == this.routingInfoButton) {
+ new RoutingInfoWindow(this.selectedHost);
+ }
+ }
+
+}
diff --git a/gui/MainWindow.java b/gui/MainWindow.java
index 6e55fea10..d03cd9f53 100644
--- a/gui/MainWindow.java
+++ b/gui/MainWindow.java
@@ -1,9 +1,9 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package gui;
-
+package gui;
+
import gui.playfield.PlayField;
import java.awt.BorderLayout;
@@ -17,96 +17,96 @@
import core.Settings;
import core.World;
-
-/**
- * Main window for the program. Takes care of layouting the main components
- * in the window.
- */
+
+/**
+ * Main window for the program. Takes care of layouting the main components
+ * in the window.
+ */
public class MainWindow extends JFrame {
/** The namespace for general GUI settings */
public static final String GUI_NS = "GUI";
-
+
/** Main window settings namespace ({@value}) */
public static final String GUI_WIN_NS = GUI_NS + ".window";
-
- /** Window width -setting id ({@value}). Defines the width of the GUI
+
+ /** Window width -setting id ({@value}). Defines the width of the GUI
* window. Default {@link #WIN_DEFAULT_WIDTH} */
public static final String WIN_WIDTH_S = "width";
- /** Window height -setting id ({@value}). Defines the height of the GUI
+ /** Window height -setting id ({@value}). Defines the height of the GUI
* window. Default {@link #WIN_DEFAULT_HEIGHT} */
public static final String WIN_HEIGHT_S = "height";
-
+
/** Default width for the GUI window */
- public static final int WIN_DEFAULT_WIDTH = 900;
+ public static final int WIN_DEFAULT_WIDTH = 900;
/** Default height for the GUI window */
- public static final int WIN_DEFAULT_HEIGHT = 700;
-
- public static final String WINDOW_TITLE = "ONE";
- /** log panel's initial weight in the split panel */
- private static final double SPLIT_PANE_LOG_WEIGHT = 0.2;
-
- private JScrollPane playFieldScroll;
-
- public MainWindow(String scenName, World world, PlayField field,
- GUIControls guiControls, InfoPanel infoPanel,
- EventLogPanel elp, DTNSimGUI gui) {
- super(WINDOW_TITLE + " - " + scenName);
- JFrame.setDefaultLookAndFeelDecorated(true);
- setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
-
- JPanel leftPane = new JPanel();
- leftPane.setLayout(new BoxLayout(leftPane,BoxLayout.Y_AXIS));
- JScrollPane hostListScroll;
- JSplitPane fieldLogSplit;
- JSplitPane logControlSplit;
- JSplitPane mainSplit;
+ public static final int WIN_DEFAULT_HEIGHT = 700;
+
+ public static final String WINDOW_TITLE = "ONE";
+ /** log panel's initial weight in the split panel */
+ private static final double SPLIT_PANE_LOG_WEIGHT = 0.2;
+
+ private JScrollPane playFieldScroll;
+
+ public MainWindow(String scenName, World world, PlayField field,
+ GUIControls guiControls, InfoPanel infoPanel,
+ EventLogPanel elp, DTNSimGUI gui) {
+ super(WINDOW_TITLE + " - " + scenName);
+ JFrame.setDefaultLookAndFeelDecorated(true);
+ setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+
+ JPanel leftPane = new JPanel();
+ leftPane.setLayout(new BoxLayout(leftPane,BoxLayout.Y_AXIS));
+ JScrollPane hostListScroll;
+ JSplitPane fieldLogSplit;
+ JSplitPane logControlSplit;
+ JSplitPane mainSplit;
Settings s = new Settings(GUI_WIN_NS);
NodeChooser chooser = new NodeChooser(world.getHosts(),gui);
-
- setLayout(new BorderLayout());
- setJMenuBar(new SimMenuBar(field, chooser));
-
+
+ setLayout(new BorderLayout());
+ setJMenuBar(new SimMenuBar(field, chooser));
+
playFieldScroll = new JScrollPane(field);
- playFieldScroll.setMaximumSize(new Dimension(Integer.MAX_VALUE,
- Integer.MAX_VALUE));
-
- hostListScroll = new JScrollPane(chooser);
- hostListScroll.setHorizontalScrollBarPolicy(
- JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
-
- logControlSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
- new JScrollPane(elp.getControls()),new JScrollPane(elp));
- logControlSplit.setResizeWeight(0.1);
- logControlSplit.setOneTouchExpandable(true);
-
- fieldLogSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
- leftPane, logControlSplit);
- fieldLogSplit.setResizeWeight(1-SPLIT_PANE_LOG_WEIGHT);
- fieldLogSplit.setOneTouchExpandable(true);
-
+ playFieldScroll.setMaximumSize(new Dimension(Integer.MAX_VALUE,
+ Integer.MAX_VALUE));
+
+ hostListScroll = new JScrollPane(chooser);
+ hostListScroll.setHorizontalScrollBarPolicy(
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+
+ logControlSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
+ new JScrollPane(elp.getControls()),new JScrollPane(elp));
+ logControlSplit.setResizeWeight(0.1);
+ logControlSplit.setOneTouchExpandable(true);
+
+ fieldLogSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
+ leftPane, logControlSplit);
+ fieldLogSplit.setResizeWeight(1-SPLIT_PANE_LOG_WEIGHT);
+ fieldLogSplit.setOneTouchExpandable(true);
+
setPreferredSize(new Dimension(
- s.getInt(WIN_WIDTH_S, WIN_DEFAULT_WIDTH),
- s.getInt(WIN_HEIGHT_S, WIN_DEFAULT_HEIGHT)));
-
- leftPane.add(guiControls);
- leftPane.add(playFieldScroll);
- leftPane.add(infoPanel);
-
- mainSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
- fieldLogSplit, hostListScroll);
- mainSplit.setOneTouchExpandable(true);
- mainSplit.setResizeWeight(0.8);
- this.getContentPane().add(mainSplit);
-
- pack();
- }
-
- /**
- * Returns a reference of the play field scroll panel
- * @return a reference of the play field scroll panel
- */
- public JScrollPane getPlayFieldScroll() {
- return this.playFieldScroll;
- }
-
-}
+ s.getInt(WIN_WIDTH_S, WIN_DEFAULT_WIDTH),
+ s.getInt(WIN_HEIGHT_S, WIN_DEFAULT_HEIGHT)));
+
+ leftPane.add(guiControls);
+ leftPane.add(playFieldScroll);
+ leftPane.add(infoPanel);
+
+ mainSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
+ fieldLogSplit, hostListScroll);
+ mainSplit.setOneTouchExpandable(true);
+ mainSplit.setResizeWeight(0.8);
+ this.getContentPane().add(mainSplit);
+
+ pack();
+ }
+
+ /**
+ * Returns a reference of the play field scroll panel
+ * @return a reference of the play field scroll panel
+ */
+ public JScrollPane getPlayFieldScroll() {
+ return this.playFieldScroll;
+ }
+
+}
diff --git a/gui/NodeChooser.java b/gui/NodeChooser.java
index 7e8afdb0d..65457b268 100644
--- a/gui/NodeChooser.java
+++ b/gui/NodeChooser.java
@@ -1,9 +1,9 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package gui;
-
+package gui;
+
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
@@ -24,40 +24,40 @@
import gui.playfield.NodeGraphic;
import core.DTNHost;
import core.Settings;
-
-/**
- * Node chooser panel
- */
-public class NodeChooser extends JPanel implements ActionListener {
- private DTNSimGUI gui;
- /** the maximum number of allNodes to show in the list per page */
+
+/**
+ * Node chooser panel
+ */
+public class NodeChooser extends JPanel implements ActionListener {
+ private DTNSimGUI gui;
+ /** the maximum number of allNodes to show in the list per page */
public static final int MAX_NODE_COUNT = 500;
private Timer refreshTimer;
/** how often auto refresh is performed */
private static final int AUTO_REFRESH_DELAY = 100;
-
+
/** Default message node filters -setting id ({@value}). Comma separate
* list of message IDs from which the default filter set is created. */
public static final String NODE_MESSAGE_FILTERS_S = "nodeMessageFilters";
-
- private static final String HOST_KEY = "host";
+
+ private static final String HOST_KEY = "host";
private List allNodes;
private List shownNodes;
-
- private JComboBox groupChooser;
- private JPanel nodesPanel;
+
+ private JComboBox groupChooser;
+ private JPanel nodesPanel;
private JPanel chooserPanel;
- private Vector filters;
+ private Vector filters;
+
-
public NodeChooser(List nodes, DTNSimGUI gui) {
- Settings s = new Settings(MainWindow.GUI_NS);
+ Settings s = new Settings(MainWindow.GUI_NS);
// create a replicate to not interfere with original's ordering
- this.allNodes = new ArrayList(nodes);
- this.shownNodes = allNodes;
+ this.allNodes = new ArrayList(nodes);
+ this.shownNodes = allNodes;
this.gui = gui;
this.filters = new Vector();
-
+
if (s.contains(NODE_MESSAGE_FILTERS_S)) {
String[] filterIds = s.getCsvSetting(NODE_MESSAGE_FILTERS_S);
for (String id : filterIds) {
@@ -66,12 +66,12 @@ public NodeChooser(List nodes, DTNSimGUI gui) {
this.refreshTimer.start();
}
}
-
- Collections.sort(this.allNodes);
-
- init();
+
+ Collections.sort(this.allNodes);
+
+ init();
}
-
+
/**
* Adds a new node filter to the node chooser
* @param f The filter to add
@@ -84,7 +84,7 @@ public void addFilter(NodeFilter f) {
this.refreshTimer.start();
}
}
-
+
/**
* Clears all node filters
*/
@@ -95,24 +95,24 @@ public void clearFilters() {
this.refreshTimer.stop();
}
this.refreshTimer = null;
-
+
NodeGraphic.setHighlightedNodes(null);
updateList();
}
-
+
private void updateList() {
setNodes(0);
if (this.groupChooser != null) {
this.groupChooser.setSelectedIndex(0);
}
}
-
-
+
+
private void updateShownNodes() {
List oldShownNodes = shownNodes;
Listnodes = new Vector();
-
- for (DTNHost node : allNodes) {
+
+ for (DTNHost node : allNodes) {
for (NodeFilter f : this.filters) {
if (f.filterNode(node)) {
nodes.add(node);
@@ -120,7 +120,7 @@ private void updateShownNodes() {
}
}
}
-
+
if (nodes.size() == oldShownNodes.size() &&
oldShownNodes.containsAll(nodes)) {
return; /* nothing to update */
@@ -129,84 +129,84 @@ private void updateShownNodes() {
updateList();
NodeGraphic.setHighlightedNodes(nodes);
}
-
- }
-
- /**
- * Initializes the node chooser panels
- */
- private void init() {
- nodesPanel = new JPanel();
- chooserPanel = new JPanel();
-
- this.setLayout(new GridBagLayout());
- GridBagConstraints c = new GridBagConstraints();
- c.anchor = GridBagConstraints.FIRST_LINE_START;
-
- nodesPanel.setLayout(new BoxLayout(nodesPanel,BoxLayout.Y_AXIS));
- nodesPanel.setBorder(BorderFactory.createTitledBorder(getBorder(),
- "Nodes"));
-
- if (shownNodes.size() > MAX_NODE_COUNT) {
+
+ }
+
+ /**
+ * Initializes the node chooser panels
+ */
+ private void init() {
+ nodesPanel = new JPanel();
+ chooserPanel = new JPanel();
+
+ this.setLayout(new GridBagLayout());
+ GridBagConstraints c = new GridBagConstraints();
+ c.anchor = GridBagConstraints.FIRST_LINE_START;
+
+ nodesPanel.setLayout(new BoxLayout(nodesPanel,BoxLayout.Y_AXIS));
+ nodesPanel.setBorder(BorderFactory.createTitledBorder(getBorder(),
+ "Nodes"));
+
+ if (shownNodes.size() > MAX_NODE_COUNT) {
String[] groupNames = new String[(shownNodes.size()-1)
- / MAX_NODE_COUNT+1];
- int last = 0;
- for (int i=0, n=shownNodes.size();
- i <= (n-1) / MAX_NODE_COUNT; i++) {
- int next = MAX_NODE_COUNT * (i+1) - 1;
- if (next > n) {
- next = n-1;
- }
- groupNames[i] = (last + "..." + next);
- last = next + 1;
- }
- groupChooser = new JComboBox(groupNames);
- groupChooser.addActionListener(this);
- chooserPanel.add(groupChooser);
- }
-
- setNodes(0);
- c.gridy = 0;
- this.add(chooserPanel, c);
- c.gridy = 1;
- this.add(nodesPanel, c);
- }
-
- /**
- * Sets the right set of allNodes to display
- * @param offset Index of the first node to show
- */
- private void setNodes(int offset) {
- nodesPanel.removeAll();
-
- for (int i=offset; i< shownNodes.size() &&
- i < offset + MAX_NODE_COUNT; i++) {
- DTNHost h = shownNodes.get(i);
- JButton jb = new JButton(h.toString());
- jb.putClientProperty(HOST_KEY, h);
- jb.addActionListener(this);
- nodesPanel.add(jb);
- }
-
- revalidate();
- repaint();
- }
-
- /**
- * Action listener method for buttons and node set chooser
- */
- public void actionPerformed(ActionEvent e) {
- if (e.getSource() instanceof JButton) {
- JButton source = (JButton)e.getSource();
- DTNHost host = (DTNHost)source.getClientProperty(HOST_KEY);
- gui.setFocus(host);
- }
- else if (e.getSource() == this.groupChooser) {
- setNodes(groupChooser.getSelectedIndex() * MAX_NODE_COUNT);
+ / MAX_NODE_COUNT+1];
+ int last = 0;
+ for (int i=0, n=shownNodes.size();
+ i <= (n-1) / MAX_NODE_COUNT; i++) {
+ int next = MAX_NODE_COUNT * (i+1) - 1;
+ if (next > n) {
+ next = n-1;
+ }
+ groupNames[i] = (last + "..." + next);
+ last = next + 1;
+ }
+ groupChooser = new JComboBox(groupNames);
+ groupChooser.addActionListener(this);
+ chooserPanel.add(groupChooser);
+ }
+
+ setNodes(0);
+ c.gridy = 0;
+ this.add(chooserPanel, c);
+ c.gridy = 1;
+ this.add(nodesPanel, c);
+ }
+
+ /**
+ * Sets the right set of allNodes to display
+ * @param offset Index of the first node to show
+ */
+ private void setNodes(int offset) {
+ nodesPanel.removeAll();
+
+ for (int i=offset; i< shownNodes.size() &&
+ i < offset + MAX_NODE_COUNT; i++) {
+ DTNHost h = shownNodes.get(i);
+ JButton jb = new JButton(h.toString());
+ jb.putClientProperty(HOST_KEY, h);
+ jb.addActionListener(this);
+ nodesPanel.add(jb);
+ }
+
+ revalidate();
+ repaint();
+ }
+
+ /**
+ * Action listener method for buttons and node set chooser
+ */
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource() instanceof JButton) {
+ JButton source = (JButton)e.getSource();
+ DTNHost host = (DTNHost)source.getClientProperty(HOST_KEY);
+ gui.setFocus(host);
+ }
+ else if (e.getSource() == this.groupChooser) {
+ setNodes(groupChooser.getSelectedIndex() * MAX_NODE_COUNT);
}
else if (e.getSource() == this.refreshTimer) {
updateShownNodes();
- }
- }
-
-}
+ }
+ }
+
+}
diff --git a/gui/RoutingInfoWindow.java b/gui/RoutingInfoWindow.java
index 74366ac9a..307b278a8 100644
--- a/gui/RoutingInfoWindow.java
+++ b/gui/RoutingInfoWindow.java
@@ -1,9 +1,9 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package gui;
-
+package gui;
+
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
@@ -22,52 +22,52 @@
import routing.util.RoutingInfo;
import core.DTNHost;
import core.SimClock;
-
-/**
- * A window for displaying routing information
- */
-public class RoutingInfoWindow extends JFrame implements ActionListener {
- private DTNHost host;
+
+/**
+ * A window for displaying routing information
+ */
+public class RoutingInfoWindow extends JFrame implements ActionListener {
+ private DTNHost host;
private JButton refreshButton;
- private JCheckBox autoRefresh;
+ private JCheckBox autoRefresh;
private JScrollPane treePane;
private JTree tree;
- private Timer refreshTimer;
+ private Timer refreshTimer;
/** how often auto refresh is performed */
private static final int AUTO_REFRESH_DELAY = 1000;
-
- public RoutingInfoWindow(DTNHost host) {
- Container cp = this.getContentPane();
+
+ public RoutingInfoWindow(DTNHost host) {
+ Container cp = this.getContentPane();
JPanel refreshPanel = new JPanel();
- this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
- this.host = host;
+ this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+ this.host = host;
this.setLayout(new BorderLayout());
- refreshPanel.setLayout(new BorderLayout());
+ refreshPanel.setLayout(new BorderLayout());
this.autoRefresh = new JCheckBox("Auto refresh");
- this.autoRefresh.addActionListener(this);
- this.treePane = new JScrollPane();
- updateTree();
-
+ this.autoRefresh.addActionListener(this);
+ this.treePane = new JScrollPane();
+ updateTree();
+
cp.add(treePane, BorderLayout.CENTER);
- cp.add(refreshPanel, BorderLayout.SOUTH);
-
- this.refreshButton = new JButton("refresh");
- this.refreshButton.addActionListener(this);
+ cp.add(refreshPanel, BorderLayout.SOUTH);
+
+ this.refreshButton = new JButton("refresh");
+ this.refreshButton.addActionListener(this);
refreshPanel.add(refreshButton, BorderLayout.EAST);
- refreshPanel.add(autoRefresh, BorderLayout.WEST);
-
- this.pack();
- this.setVisible(true);
- }
-
-
- private void updateTree() {
- super.setTitle("Routing Info of " + host + " at " +
- SimClock.getFormattedTime(2));
- RoutingInfo ri = host.getRoutingInfo();
- DefaultMutableTreeNode top = new DefaultMutableTreeNode(ri);
+ refreshPanel.add(autoRefresh, BorderLayout.WEST);
+
+ this.pack();
+ this.setVisible(true);
+ }
+
+
+ private void updateTree() {
+ super.setTitle("Routing Info of " + host + " at " +
+ SimClock.getFormattedTime(2));
+ RoutingInfo ri = host.getRoutingInfo();
+ DefaultMutableTreeNode top = new DefaultMutableTreeNode(ri);
Vector expanded = new Vector();
-
+
addChildren(top, ri);
if (this.tree != null) { /* store expanded state */
@@ -77,34 +77,34 @@ private void updateTree() {
}
}
}
-
+
this.tree = new JTree(top);
-
+
for (int i=0; i < this.tree.getRowCount(); i++) { /* restore expanded */
- if (expanded.size() > 0 && expanded.firstElement() == i) {
+ if (expanded.size() > 0 && expanded.firstElement() == i) {
this.tree.expandRow(i);
expanded.remove(0);
- }
- }
-
- this.treePane.setViewportView(this.tree);
- this.treePane.revalidate();
- }
-
-
- private void addChildren(DefaultMutableTreeNode node, RoutingInfo info) {
- for (RoutingInfo ri : info.getMoreInfo()) {
- DefaultMutableTreeNode child = new DefaultMutableTreeNode(ri);
- node.add(child);
- // recursively add children of this info
- addChildren(child, ri);
- }
- }
-
+ }
+ }
+
+ this.treePane.setViewportView(this.tree);
+ this.treePane.revalidate();
+ }
+
+
+ private void addChildren(DefaultMutableTreeNode node, RoutingInfo info) {
+ for (RoutingInfo ri : info.getMoreInfo()) {
+ DefaultMutableTreeNode child = new DefaultMutableTreeNode(ri);
+ node.add(child);
+ // recursively add children of this info
+ addChildren(child, ri);
+ }
+ }
+
public void actionPerformed(ActionEvent e) {
- Object s = e.getSource();
- if (s == this.refreshButton || s == this.refreshTimer) {
- updateTree();
+ Object s = e.getSource();
+ if (s == this.refreshButton || s == this.refreshTimer) {
+ updateTree();
}
if (e.getSource() == this.autoRefresh) {
if (this.autoRefresh.isSelected()) {
@@ -113,7 +113,7 @@ public void actionPerformed(ActionEvent e) {
} else {
this.refreshTimer.stop();
}
- }
+ }
}
-
-}
\ No newline at end of file
+
+}
diff --git a/gui/SimMenuBar.java b/gui/SimMenuBar.java
index dff5a5250..44d528885 100644
--- a/gui/SimMenuBar.java
+++ b/gui/SimMenuBar.java
@@ -1,6 +1,6 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
package gui;
@@ -34,7 +34,7 @@ public class SimMenuBar extends JMenuBar implements ActionListener {
/** title of the about window */
public static final String ABOUT_TITLE = "about ONE";
/** GPLv3 license text for about window */
- public static final String ABOUT_TEXT =
+ public static final String ABOUT_TEXT =
"Copyright (C) 2007-2011 Aalto University, Comnet\n\n"+
"This program is free software: you can redistribute it and/or modify\n"+
"it under the terms of the GNU General Public License as published by\n"+
@@ -47,7 +47,7 @@ public class SimMenuBar extends JMenuBar implements ActionListener {
"You should have received a copy of the GNU General Public License\n"+
"along with this program. If not, see .\n\n"+
"Map data copyright: Maanmittauslaitos, 2007";
-
+
private JCheckBoxMenuItem enableBgImage;
private JCheckBoxMenuItem showNodeName;
private JCheckBoxMenuItem showNodeCoverage;
@@ -57,11 +57,11 @@ public class SimMenuBar extends JMenuBar implements ActionListener {
private JCheckBoxMenuItem enableMapGraphic;
private JCheckBoxMenuItem autoClearOverlay;
private JCheckBoxMenuItem focusOnClick;
-
+
private JMenuItem clearOverlay;
private JMenuItem addNodeMessageFilter;
private JMenuItem clearNodeFilters;
-
+
private JMenuItem about;
private PlayField field;
private NodeChooser chooser;
@@ -78,7 +78,7 @@ public class SimMenuBar extends JMenuBar implements ActionListener {
public static final String FOCUS_ON_CLICK_S = "focusOnClick";
/** The namespace where underlay image -related settings are found */
public static final String UNDERLAY_NS = "GUI.UnderlayImage";
-
+
public SimMenuBar(PlayField field, NodeChooser nodeChooser) {
this.field = field;
this.chooser = nodeChooser;
@@ -91,18 +91,18 @@ private void init() {
JMenu help = new JMenu("Help");
JMenu nodeFilters = new JMenu("Add node filter");
Settings settings = new Settings(UNDERLAY_NS);
-
+
if (settings.contains("fileName")) {
- // create underlay image menu item only if filename is specified
+ // create underlay image menu item only if filename is specified
enableBgImage = createCheckItem(pfMenu,"Show underlay image",
false, null);
}
-
+
settings.setNameSpace(gui.MainWindow.GUI_NS);
-
+
showNodeName = createCheckItem(pfMenu, "Show node name strings",
- true, SHOW_NODE_NAMESTR_S);
- showNodeCoverage = createCheckItem(pfMenu,
+ true, SHOW_NODE_NAMESTR_S);
+ showNodeCoverage = createCheckItem(pfMenu,
"Show node radio coverages", true, SHOW_RADIO_COVERAGES_S);
showNodeConnections = createCheckItem(pfMenu,
"Show node connections", true, SHOW_CONNECTIONS_S);
@@ -116,58 +116,58 @@ private void init() {
autoClearOverlay = createCheckItem(pfMenu, "Autoclear overlay",
true, null);
clearOverlay = createMenuItem(pfToolsMenu, "Clear overlays");
-
-
+
+
pfToolsMenu.addSeparator();
addNodeMessageFilter = createMenuItem(nodeFilters, "message filter");
pfToolsMenu.add(nodeFilters);
clearNodeFilters = createMenuItem(pfToolsMenu, "Clear node filters");
updatePlayfieldSettings();
-
+
about = createMenuItem(help,"about");
this.add(pfMenu);
this.add(pfToolsMenu);
this.add(Box.createHorizontalGlue());
this.add(help);
}
-
+
private JMenuItem createMenuItem(Container c, String txt) {
JMenuItem i = new JMenuItem(txt);
i.addActionListener(this);
c.add(i);
return i;
}
-
+
/**
* Creates a new check box menu item to the given container
* @param c The container
* @param txt Text for the menu item
* @param selected Is the check box selected (by default)
- * @param setting Name of the setting where the check-box-selected
- * true/false value is read from (if not found, the "selected" parameter
- * value is used). If null, no setting is read and the default is
+ * @param setting Name of the setting where the check-box-selected
+ * true/false value is read from (if not found, the "selected" parameter
+ * value is used). If null, no setting is read and the default is
* used as such.
* @return The created check box menu item
*/
- private JCheckBoxMenuItem createCheckItem(Container c,String txt,
+ private JCheckBoxMenuItem createCheckItem(Container c,String txt,
boolean selected, String setting) {
Settings s = new Settings(gui.MainWindow.GUI_NS);
-
+
JCheckBoxMenuItem i = new JCheckBoxMenuItem(txt);
if (setting == null) {
i.setSelected(selected);
} else {
i.setSelected(s.getBoolean(setting, selected));
}
-
+
i.addActionListener(this);
c.add(i);
-
+
return i;
}
-
+
private void updatePlayfieldSettings() {
NodeGraphic.setDrawNodeName(showNodeName.isSelected());
NodeGraphic.setDrawCoverage(showNodeCoverage.isSelected());
@@ -177,18 +177,18 @@ private void updatePlayfieldSettings() {
field.setAutoClearOverlay(autoClearOverlay.isSelected());
field.setFocusOnClick(focusOnClick.isSelected());
}
-
+
private String getFilterString(String message) {
return (String)JOptionPane.showInputDialog(
this, message, "Filter input", JOptionPane.PLAIN_MESSAGE);
}
-
+
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source == enableBgImage) {
toggleUnderlayImage();
}
- else if (source == this.showNodeName ||
+ else if (source == this.showNodeName ||
source == this.showNodeCoverage ||
source == this.showNodeConnections ||
source == this.enableMapGraphic ||
@@ -209,11 +209,11 @@ else if (source == clearNodeFilters) {
chooser.clearFilters();
}
else if (source == this.about) {
- JOptionPane.showMessageDialog(this, ABOUT_TEXT, ABOUT_TITLE,
+ JOptionPane.showMessageDialog(this, ABOUT_TEXT, ABOUT_TITLE,
JOptionPane.INFORMATION_MESSAGE);
}
}
-
+
/**
* Toggles the showing of underlay image. Image is read from the file only
* when it is enabled to save some memory.
@@ -232,15 +232,15 @@ private void toggleUnderlayImage() {
rotate = settings.getDouble("rotate");
image = ImageIO.read(new File(imgFile));
} catch (IOException ex) {
- warn("Couldn't set underlay image " + imgFile + ". " +
- ex.getMessage());
- enableBgImage.setSelected(false);
- return;
+ warn("Couldn't set underlay image " + imgFile + ". " +
+ ex.getMessage());
+ enableBgImage.setSelected(false);
+ return;
}
catch (SettingsError er) {
- warn("Problem with the underlay image settings: " +
- er.getMessage());
- return;
+ warn("Problem with the underlay image settings: " +
+ er.getMessage());
+ return;
}
field.setUnderlayImage(image, offsets[0], offsets[1],
scale, rotate);
@@ -250,10 +250,10 @@ private void toggleUnderlayImage() {
field.setUnderlayImage(null, 0, 0, 0, 0);
}
}
-
+
private void warn(String txt) {
- JOptionPane.showMessageDialog(null, txt, "warning",
+ JOptionPane.showMessageDialog(null, txt, "warning",
JOptionPane.WARNING_MESSAGE);
}
-
-}
\ No newline at end of file
+
+}
diff --git a/gui/nodefilter/NodeFilter.java b/gui/nodefilter/NodeFilter.java
index 4b8f634f3..92a3d4b7f 100644
--- a/gui/nodefilter/NodeFilter.java
+++ b/gui/nodefilter/NodeFilter.java
@@ -1,26 +1,26 @@
-/*
- * Copyright 2011 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
- */
-
-package gui.nodefilter;
-
-import core.DTNHost;
-
-/**
- * Interface for node filtering classes
- */
-public interface NodeFilter {
-
- /**
- * Returns true if the given node should be included in the filtered set
- * @param node The node to check
- * @return true if the node should be included, false if not
- */
- public boolean filterNode(DTNHost node);
-
- /**
- * Returns a String presentations of the filter
- */
- public String toString();
-}
+/*
+ * Copyright 2011 Aalto University, ComNet
+ * Released under GPLv3. See LICENSE.txt for details.
+ */
+
+package gui.nodefilter;
+
+import core.DTNHost;
+
+/**
+ * Interface for node filtering classes
+ */
+public interface NodeFilter {
+
+ /**
+ * Returns true if the given node should be included in the filtered set
+ * @param node The node to check
+ * @return true if the node should be included, false if not
+ */
+ public boolean filterNode(DTNHost node);
+
+ /**
+ * Returns a String presentations of the filter
+ */
+ public String toString();
+}
diff --git a/gui/nodefilter/NodeMessageFilter.java b/gui/nodefilter/NodeMessageFilter.java
index a35ca3b86..520516acc 100644
--- a/gui/nodefilter/NodeMessageFilter.java
+++ b/gui/nodefilter/NodeMessageFilter.java
@@ -1,33 +1,33 @@
-/*
- * Copyright 2011 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
- */
-
-package gui.nodefilter;
-
-import core.DTNHost;
-
-/**
- * Node filter that filters nodes by the messages they have in their buffer
- */
-public class NodeMessageFilter implements NodeFilter {
- private String messageId;
-
- /**
- * Creates a new filter with the given message ID
- * @param messageId The message ID used for filtering
- */
- public NodeMessageFilter(String messageId) {
- this.messageId = messageId;
- }
-
- public boolean filterNode(DTNHost node) {
- return node.getRouter().hasMessage(messageId);
- }
-
- @Override
- public String toString() {
- return "Filters nodes with message ID " + messageId;
- }
-
-}
+/*
+ * Copyright 2011 Aalto University, ComNet
+ * Released under GPLv3. See LICENSE.txt for details.
+ */
+
+package gui.nodefilter;
+
+import core.DTNHost;
+
+/**
+ * Node filter that filters nodes by the messages they have in their buffer
+ */
+public class NodeMessageFilter implements NodeFilter {
+ private String messageId;
+
+ /**
+ * Creates a new filter with the given message ID
+ * @param messageId The message ID used for filtering
+ */
+ public NodeMessageFilter(String messageId) {
+ this.messageId = messageId;
+ }
+
+ public boolean filterNode(DTNHost node) {
+ return node.getRouter().hasMessage(messageId);
+ }
+
+ @Override
+ public String toString() {
+ return "Filters nodes with message ID " + messageId;
+ }
+
+}
diff --git a/gui/package.html b/gui/package.html
index 308cdd55a..3196fe0d1 100644
--- a/gui/package.html
+++ b/gui/package.html
@@ -1,8 +1,8 @@
-
-
-
-
-Contains the classes of Graphical User Interface.
-
-
-
\ No newline at end of file
+
+
+
+
+Contains the classes of Graphical User Interface.
+
+
+
diff --git a/gui/playfield/MapGraphic.java b/gui/playfield/MapGraphic.java
index 1ceb5a057..8e94f82cc 100644
--- a/gui/playfield/MapGraphic.java
+++ b/gui/playfield/MapGraphic.java
@@ -1,53 +1,53 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package gui.playfield;
-
+package gui.playfield;
+
import java.awt.Color;
import java.awt.Graphics2D;
import movement.map.MapNode;
import movement.map.SimMap;
import core.Coord;
-
-/**
- * PlayfieldGraphic for SimMap visualization
- *
- */
-public class MapGraphic extends PlayFieldGraphic {
- private SimMap simMap;
- private final Color PATH_COLOR = Color.LIGHT_GRAY;
- private final Color BG_COLOR = Color.WHITE;
-
- public MapGraphic(SimMap simMap) {
- this.simMap = simMap;
-
- }
-
- // TODO: draw only once and store to buffer
- @Override
- public void draw(Graphics2D g2) {
- Coord c,c2;
-
- if (simMap == null) {
- return;
- }
-
- g2.setColor(PATH_COLOR);
- g2.setBackground(BG_COLOR);
-
- // draws all edges between map nodes (bidirectional edges twice)
- for (MapNode n : simMap.getNodes()) {
- c = n.getLocation();
-
- // draw a line to adjacent nodes
- for (MapNode n2 : n.getNeighbors()) {
- c2 = n2.getLocation();
- g2.drawLine(scale(c2.getX()), scale(c2.getY()),
- scale(c.getX()), scale(c.getY()));
- }
- }
- }
-
-}
+
+/**
+ * PlayfieldGraphic for SimMap visualization
+ *
+ */
+public class MapGraphic extends PlayFieldGraphic {
+ private SimMap simMap;
+ private final Color PATH_COLOR = Color.LIGHT_GRAY;
+ private final Color BG_COLOR = Color.WHITE;
+
+ public MapGraphic(SimMap simMap) {
+ this.simMap = simMap;
+
+ }
+
+ // TODO: draw only once and store to buffer
+ @Override
+ public void draw(Graphics2D g2) {
+ Coord c,c2;
+
+ if (simMap == null) {
+ return;
+ }
+
+ g2.setColor(PATH_COLOR);
+ g2.setBackground(BG_COLOR);
+
+ // draws all edges between map nodes (bidirectional edges twice)
+ for (MapNode n : simMap.getNodes()) {
+ c = n.getLocation();
+
+ // draw a line to adjacent nodes
+ for (MapNode n2 : n.getNeighbors()) {
+ c2 = n2.getLocation();
+ g2.drawLine(scale(c2.getX()), scale(c2.getY()),
+ scale(c.getX()), scale(c.getY()));
+ }
+ }
+ }
+
+}
diff --git a/gui/playfield/MessageGraphic.java b/gui/playfield/MessageGraphic.java
index 14cd8ca7f..618c1fbac 100644
--- a/gui/playfield/MessageGraphic.java
+++ b/gui/playfield/MessageGraphic.java
@@ -1,43 +1,43 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package gui.playfield;
-
+package gui.playfield;
+
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Polygon;
import core.DTNHost;
-
-/**
- * Visualization of a message
- *
- */
-public class MessageGraphic extends PlayFieldGraphic {
- private Color msgColor = Color.RED;
-
- private DTNHost from;
- private DTNHost to;
-
- public MessageGraphic(DTNHost from, DTNHost to) {
- this.to = to;
- this.from = from;
- }
-
- @Override
- public void draw(Graphics2D g2) {
- g2.setColor(msgColor);
-
- int fromX = scale(from.getLocation().getX());
- int fromY = scale(from.getLocation().getY());
- int toX = scale(to.getLocation().getX());
- int toY = scale(to.getLocation().getY());
-
- // line from "from host" to "to host"
- Polygon p = new Polygon(new int[] {fromX, toX},
- new int[] {fromY,toY}, 2);
-
- g2.draw(p);
- }
-}
+
+/**
+ * Visualization of a message
+ *
+ */
+public class MessageGraphic extends PlayFieldGraphic {
+ private Color msgColor = Color.RED;
+
+ private DTNHost from;
+ private DTNHost to;
+
+ public MessageGraphic(DTNHost from, DTNHost to) {
+ this.to = to;
+ this.from = from;
+ }
+
+ @Override
+ public void draw(Graphics2D g2) {
+ g2.setColor(msgColor);
+
+ int fromX = scale(from.getLocation().getX());
+ int fromY = scale(from.getLocation().getY());
+ int toX = scale(to.getLocation().getX());
+ int toY = scale(to.getLocation().getY());
+
+ // line from "from host" to "to host"
+ Polygon p = new Polygon(new int[] {fromX, toX},
+ new int[] {fromY,toY}, 2);
+
+ g2.draw(p);
+ }
+}
diff --git a/gui/playfield/NodeGraphic.java b/gui/playfield/NodeGraphic.java
index dc746deff..8bac8a1f4 100644
--- a/gui/playfield/NodeGraphic.java
+++ b/gui/playfield/NodeGraphic.java
@@ -1,9 +1,9 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package gui.playfield;
-
+package gui.playfield;
+
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
@@ -14,41 +14,41 @@
import core.Coord;
import core.DTNHost;
import core.NetworkInterface;
-
-/**
- * Visualization of a DTN Node
- *
- */
-public class NodeGraphic extends PlayFieldGraphic {
- private static boolean drawCoverage;
- private static boolean drawNodeName;
+
+/**
+ * Visualization of a DTN Node
+ *
+ */
+public class NodeGraphic extends PlayFieldGraphic {
+ private static boolean drawCoverage;
+ private static boolean drawNodeName;
private static boolean drawConnections;
- private static boolean drawBuffer;
+ private static boolean drawBuffer;
private static List highlightedNodes;
-
- private static Color rangeColor = Color.GREEN;
- private static Color conColor = Color.BLACK;
- private static Color hostColor = Color.BLUE;
- private static Color hostNameColor = Color.BLUE;
- private static Color msgColor1 = Color.BLUE;
- private static Color msgColor2 = Color.GREEN;
+
+ private static Color rangeColor = Color.GREEN;
+ private static Color conColor = Color.BLACK;
+ private static Color hostColor = Color.BLUE;
+ private static Color hostNameColor = Color.BLUE;
+ private static Color msgColor1 = Color.BLUE;
+ private static Color msgColor2 = Color.GREEN;
private static Color msgColor3 = Color.RED;
-
- private static Color highlightedNodeColor = Color.MAGENTA;
-
- private DTNHost node;
-
- public NodeGraphic(DTNHost node) {
- this.node = node;
- }
-
- @Override
- public void draw(Graphics2D g2) {
+
+ private static Color highlightedNodeColor = Color.MAGENTA;
+
+ private DTNHost node;
+
+ public NodeGraphic(DTNHost node) {
+ this.node = node;
+ }
+
+ @Override
+ public void draw(Graphics2D g2) {
drawHost(g2);
- if (drawBuffer) {
+ if (drawBuffer) {
drawMessages(g2);
- }
- }
+ }
+ }
/**
* @return true if the node this graphic represents should be highlighted
@@ -60,16 +60,16 @@ private boolean isHighlighted() {
return highlightedNodes.contains(node);
}
}
-
- /**
- * Visualize node's location, radio ranges and connections
- * @param g2 The graphic context to draw to
- */
- private void drawHost(Graphics2D g2) {
- Coord loc = node.getLocation();
-
- if (drawCoverage && node.isRadioActive()) {
- ArrayList interfaces =
+
+ /**
+ * Visualize node's location, radio ranges and connections
+ * @param g2 The graphic context to draw to
+ */
+ private void drawHost(Graphics2D g2) {
+ Coord loc = node.getLocation();
+
+ if (drawCoverage && node.isRadioActive()) {
+ ArrayList interfaces =
new ArrayList();
interfaces.addAll(node.getInterfaces());
for (NetworkInterface ni : interfaces) {
@@ -77,132 +77,132 @@ private void drawHost(Graphics2D g2) {
Ellipse2D.Double coverage;
coverage = new Ellipse2D.Double(scale(loc.getX()-range),
- scale(loc.getY()-range), scale(range * 2),
- scale(range * 2));
+ scale(loc.getY()-range), scale(range * 2),
+ scale(range * 2));
// draw the "range" circle
g2.setColor(rangeColor);
g2.draw(coverage);
}
- }
-
- if (drawConnections) {
- g2.setColor(conColor);
- Coord c1 = node.getLocation();
- ArrayList conList = new ArrayList();
- // create a copy to prevent concurrent modification exceptions
- conList.addAll(node.getConnections());
+ }
+
+ if (drawConnections) {
+ g2.setColor(conColor);
+ Coord c1 = node.getLocation();
+ ArrayList conList = new ArrayList();
+ // create a copy to prevent concurrent modification exceptions
+ conList.addAll(node.getConnections());
for (Connection c : conList) {
DTNHost otherNode = c.getOtherNode(node);
Coord c2;
-
+
if (otherNode == null) {
continue; /* disconnected before drawn */
- }
- c2 = otherNode.getLocation();
- g2.drawLine(scale(c1.getX()), scale(c1.getY()),
- scale(c2.getX()), scale(c2.getY()));
- }
- }
+ }
+ c2 = otherNode.getLocation();
+ g2.drawLine(scale(c1.getX()), scale(c1.getY()),
+ scale(c2.getX()), scale(c2.getY()));
+ }
+ }
/* draw node rectangle */
- g2.setColor(hostColor);
- g2.drawRect(scale(loc.getX()-1),scale(loc.getY()-1),
+ g2.setColor(hostColor);
+ g2.drawRect(scale(loc.getX()-1),scale(loc.getY()-1),
scale(2),scale(2));
if (isHighlighted()) {
g2.setColor(highlightedNodeColor);
- g2.fillRect(scale(loc.getX()) - 3 ,scale(loc.getY()) - 3, 6, 6);
+ g2.fillRect(scale(loc.getX()) - 3 ,scale(loc.getY()) - 3, 6, 6);
}
-
- if (drawNodeName) {
- g2.setColor(hostNameColor);
- // Draw node's address next to it
- g2.drawString(node.toString(), scale(loc.getX()),
- scale(loc.getY()));
- }
- }
-
- /**
- * Sets whether radio coverage of nodes should be drawn
- * @param draw If true, radio coverage is drawn
- */
- public static void setDrawCoverage(boolean draw) {
- drawCoverage = draw;
- }
-
- /**
- * Sets whether node's name should be displayed
- * @param draw If true, node's name is displayed
- */
- public static void setDrawNodeName(boolean draw) {
- drawNodeName = draw;
- }
-
- /**
- * Sets whether node's connections to other nodes should be drawn
- * @param draw If true, node's connections to other nodes is drawn
- */
- public static void setDrawConnections(boolean draw) {
- drawConnections = draw;
+
+ if (drawNodeName) {
+ g2.setColor(hostNameColor);
+ // Draw node's address next to it
+ g2.drawString(node.toString(), scale(loc.getX()),
+ scale(loc.getY()));
+ }
+ }
+
+ /**
+ * Sets whether radio coverage of nodes should be drawn
+ * @param draw If true, radio coverage is drawn
+ */
+ public static void setDrawCoverage(boolean draw) {
+ drawCoverage = draw;
}
-
+
+ /**
+ * Sets whether node's name should be displayed
+ * @param draw If true, node's name is displayed
+ */
+ public static void setDrawNodeName(boolean draw) {
+ drawNodeName = draw;
+ }
+
+ /**
+ * Sets whether node's connections to other nodes should be drawn
+ * @param draw If true, node's connections to other nodes is drawn
+ */
+ public static void setDrawConnections(boolean draw) {
+ drawConnections = draw;
+ }
+
/**
* Sets whether node's message buffer is shown
- * @param draw If true, node's message buffer is drawn
+ * @param draw If true, node's message buffer is drawn
*/
public static void setDrawBuffer(boolean draw) {
drawBuffer = draw;
}
-
+
public static void setHighlightedNodes(List nodes) {
highlightedNodes = nodes;
- }
-
- /**
- * Visualize the messages this node is carrying
- * @param g2 The graphic context to draw to
- */
- private void drawMessages(Graphics2D g2) {
- int nrofMessages = node.getNrofMessages();
- Coord loc = node.getLocation();
-
- drawBar(g2,loc, nrofMessages % 10, 1);
- drawBar(g2,loc, nrofMessages / 10, 2);
- }
-
- /**
- * Draws a bar (stack of squares) next to a location
- * @param g2 The graphic context to draw to
- * @param loc The location where to draw
- * @param nrof How many squares in the stack
- * @param col Which column
- */
- private void drawBar(Graphics2D g2, Coord loc, int nrof, int col) {
- final int BAR_HEIGHT = 5;
- final int BAR_WIDTH = 5;
- final int BAR_DISPLACEMENT = 2;
-
- // draws a stack of squares next loc
- for (int i=1; i <= nrof; i++) {
- if (i%2 == 0) { // use different color for every other msg
- g2.setColor(msgColor1);
- }
- else {
- if (col > 1) {
- g2.setColor(msgColor3);
- }
- else {
- g2.setColor(msgColor2);
- }
- }
-
- g2.fillRect(scale(loc.getX()-BAR_DISPLACEMENT-(BAR_WIDTH*col)),
- scale(loc.getY()- BAR_DISPLACEMENT- i* BAR_HEIGHT),
- scale(BAR_WIDTH), scale(BAR_HEIGHT));
- }
-
- }
-
-}
+ }
+
+ /**
+ * Visualize the messages this node is carrying
+ * @param g2 The graphic context to draw to
+ */
+ private void drawMessages(Graphics2D g2) {
+ int nrofMessages = node.getNrofMessages();
+ Coord loc = node.getLocation();
+
+ drawBar(g2,loc, nrofMessages % 10, 1);
+ drawBar(g2,loc, nrofMessages / 10, 2);
+ }
+
+ /**
+ * Draws a bar (stack of squares) next to a location
+ * @param g2 The graphic context to draw to
+ * @param loc The location where to draw
+ * @param nrof How many squares in the stack
+ * @param col Which column
+ */
+ private void drawBar(Graphics2D g2, Coord loc, int nrof, int col) {
+ final int BAR_HEIGHT = 5;
+ final int BAR_WIDTH = 5;
+ final int BAR_DISPLACEMENT = 2;
+
+ // draws a stack of squares next loc
+ for (int i=1; i <= nrof; i++) {
+ if (i%2 == 0) { // use different color for every other msg
+ g2.setColor(msgColor1);
+ }
+ else {
+ if (col > 1) {
+ g2.setColor(msgColor3);
+ }
+ else {
+ g2.setColor(msgColor2);
+ }
+ }
+
+ g2.fillRect(scale(loc.getX()-BAR_DISPLACEMENT-(BAR_WIDTH*col)),
+ scale(loc.getY()- BAR_DISPLACEMENT- i* BAR_HEIGHT),
+ scale(BAR_WIDTH), scale(BAR_HEIGHT));
+ }
+
+ }
+
+}
diff --git a/gui/playfield/PathGraphic.java b/gui/playfield/PathGraphic.java
index a383971f5..89ef2b57c 100644
--- a/gui/playfield/PathGraphic.java
+++ b/gui/playfield/PathGraphic.java
@@ -1,54 +1,54 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package gui.playfield;
-
+package gui.playfield;
+
import java.awt.Color;
import java.awt.Graphics2D;
import java.util.List;
import movement.Path;
import core.Coord;
-
-/**
- * Visualization of a Path
- *
- */
-public class PathGraphic extends PlayFieldGraphic {
- private final static Color PATH_COLOR = Color.RED;
- private List coords;
-
- public PathGraphic(Path path) {
- if (path == null) {
- this.coords = null;
- }
- else {
- this.coords = path.getCoords();
- assert this.coords != null && this.coords.size() > 0 :
- "No coordinates in the path (" + path + ")";
- }
- }
-
- /**
- * Draws a line trough all path's coordinates.
- * @param g2 The graphics context to draw to
- */
- @Override
- public void draw(Graphics2D g2) {
- if (coords == null) {
- return;
- }
-
- g2.setColor(PATH_COLOR);
- Coord prev = coords.get(0);
-
- for (int i=1, n=coords.size(); i < n; i++) {
- Coord next = coords.get(i);
- g2.drawLine(scale(prev.getX()), scale(prev.getY()),
- scale(next.getX()), scale(next.getY()));
- prev = next;
- }
- }
-
-}
+
+/**
+ * Visualization of a Path
+ *
+ */
+public class PathGraphic extends PlayFieldGraphic {
+ private final static Color PATH_COLOR = Color.RED;
+ private List coords;
+
+ public PathGraphic(Path path) {
+ if (path == null) {
+ this.coords = null;
+ }
+ else {
+ this.coords = path.getCoords();
+ assert this.coords != null && this.coords.size() > 0 :
+ "No coordinates in the path (" + path + ")";
+ }
+ }
+
+ /**
+ * Draws a line trough all path's coordinates.
+ * @param g2 The graphics context to draw to
+ */
+ @Override
+ public void draw(Graphics2D g2) {
+ if (coords == null) {
+ return;
+ }
+
+ g2.setColor(PATH_COLOR);
+ Coord prev = coords.get(0);
+
+ for (int i=1, n=coords.size(); i < n; i++) {
+ Coord next = coords.get(i);
+ g2.drawLine(scale(prev.getX()), scale(prev.getY()),
+ scale(next.getX()), scale(next.getY()));
+ prev = next;
+ }
+ }
+
+}
diff --git a/gui/playfield/PlayField.java b/gui/playfield/PlayField.java
index a562041e4..5630ce079 100644
--- a/gui/playfield/PlayField.java
+++ b/gui/playfield/PlayField.java
@@ -1,9 +1,9 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package gui.playfield;
-
+package gui.playfield;
+
import gui.DTNSimGUI;
import java.awt.Color;
@@ -25,137 +25,137 @@
import core.Coord;
import core.DTNHost;
import core.World;
-
-/**
- * The canvas where node graphics and message visualizations are drawn.
- *
- */
+
+/**
+ * The canvas where node graphics and message visualizations are drawn.
+ *
+ */
public class PlayField extends JPanel {
public static final int PLAYFIELD_OFFSET = 10;
-
- private World w;
+
+ private World w;
private DTNSimGUI gui;
-
- private Color bgColor = Color.WHITE;
-
- private List overlayGraphics;
- private boolean autoClearOverlay; // automatically clear overlay graphics
- private MapGraphic mapGraphic;
- private boolean showMapGraphic;
+
+ private Color bgColor = Color.WHITE;
+
+ private List overlayGraphics;
+ private boolean autoClearOverlay; // automatically clear overlay graphics
+ private MapGraphic mapGraphic;
+ private boolean showMapGraphic;
private ScaleReferenceGraphic refGraphic;
- private boolean focusOnClick;
-
- private BufferedImage underlayImage;
- private AffineTransform imageTransform;
- private AffineTransform curTransform;
- private double underlayImgDx;
- private double underlayImgDy;
-
- /**
- * Creates a playfield
- * @param w The world that contains the actors to be drawn
- */
- public PlayField (World w, DTNSimGUI gui) {
+ private boolean focusOnClick;
+
+ private BufferedImage underlayImage;
+ private AffineTransform imageTransform;
+ private AffineTransform curTransform;
+ private double underlayImgDx;
+ private double underlayImgDy;
+
+ /**
+ * Creates a playfield
+ * @param w The world that contains the actors to be drawn
+ */
+ public PlayField (World w, DTNSimGUI gui) {
this.w = w;
this.gui = gui;
-
- this.refGraphic = new ScaleReferenceGraphic();
- updateFieldSize();
- this.setBackground(bgColor);
- this.overlayGraphics = Collections.synchronizedList(
- new ArrayList());
- this.mapGraphic = null;
- this.underlayImage = null;
- this.imageTransform = null;
+
+ this.refGraphic = new ScaleReferenceGraphic();
+ updateFieldSize();
+ this.setBackground(bgColor);
+ this.overlayGraphics = Collections.synchronizedList(
+ new ArrayList());
+ this.mapGraphic = null;
+ this.underlayImage = null;
+ this.imageTransform = null;
this.autoClearOverlay = true;
-
- this.addMouseListener(new MouseAdapter() {
+
+ this.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (focusOnClick) {
focusClosestNode(e.getX(), e.getY());
}
}
- });
- }
-
- /**
- * Schedule the play field to be drawn
- */
- public void updateField() {
- this.repaint();
- }
-
- /**
- * Sets an image to show under the host graphics
- * @param image The image to set or null to remove the image
- * @param dx X offset of the image
- * @param dy Y offset of the image
- * @param scale Image scaling factor
- * @param rotation Rotatation angle of the image (radians)
- */
- public void setUnderlayImage(BufferedImage image,
- double dx, double dy, double scale, double rotation) {
- if (image == null) {
- this.underlayImage = null;
- this.imageTransform = null;
- this.curTransform = null;
- return;
- }
- this.underlayImage = image;
- this.imageTransform = AffineTransform.getRotateInstance(rotation);
- this.imageTransform.scale(scale, scale);
- this.curTransform = new AffineTransform(imageTransform);
- this.underlayImgDx = dx;
- this.underlayImgDy = dy;
-
- curTransform.scale(PlayFieldGraphic.getScale(),
- PlayFieldGraphic.getScale());
- curTransform.translate(this.underlayImgDx, this.underlayImgDy);
-
- }
-
- /**
- * Sets the zooming/scaling factor
- * @param scale The new scale
- */
- public void setScale(double scale) {
- PlayFieldGraphic.setScale(scale);
- this.updateFieldSize();
- if (this.imageTransform != null) {
- this.curTransform = new AffineTransform(imageTransform);
- curTransform.scale(scale, scale);
- curTransform.translate(this.underlayImgDx, this.underlayImgDy);
- }
- }
-
- /**
- * Sets the source for the map graphics and enables map graphics showing
- * @param simMap The map to show
- */
- public void setMap(SimMap simMap) {
- this.mapGraphic = new MapGraphic(simMap);
- this.showMapGraphic = true;
- }
-
- /**
- * Enables/disables showing of map graphics
- * @param show True if the map graphics should be shown (false if not)
- */
- public void setShowMapGraphic(boolean show) {
- this.showMapGraphic = show;
- }
-
- /**
- * Enables or disables the automatic clearing of overlay graphics.
- * If enabled, overlay graphics are cleared every time a new graphics
- * object is set to be drawn.
- * @param clear Auto clear is enabled if this is true, disabled on false
- */
- public void setAutoClearOverlay(boolean clear) {
- this.autoClearOverlay = clear;
- }
-
+ });
+ }
+
+ /**
+ * Schedule the play field to be drawn
+ */
+ public void updateField() {
+ this.repaint();
+ }
+
+ /**
+ * Sets an image to show under the host graphics
+ * @param image The image to set or null to remove the image
+ * @param dx X offset of the image
+ * @param dy Y offset of the image
+ * @param scale Image scaling factor
+ * @param rotation Rotatation angle of the image (radians)
+ */
+ public void setUnderlayImage(BufferedImage image,
+ double dx, double dy, double scale, double rotation) {
+ if (image == null) {
+ this.underlayImage = null;
+ this.imageTransform = null;
+ this.curTransform = null;
+ return;
+ }
+ this.underlayImage = image;
+ this.imageTransform = AffineTransform.getRotateInstance(rotation);
+ this.imageTransform.scale(scale, scale);
+ this.curTransform = new AffineTransform(imageTransform);
+ this.underlayImgDx = dx;
+ this.underlayImgDy = dy;
+
+ curTransform.scale(PlayFieldGraphic.getScale(),
+ PlayFieldGraphic.getScale());
+ curTransform.translate(this.underlayImgDx, this.underlayImgDy);
+
+ }
+
+ /**
+ * Sets the zooming/scaling factor
+ * @param scale The new scale
+ */
+ public void setScale(double scale) {
+ PlayFieldGraphic.setScale(scale);
+ this.updateFieldSize();
+ if (this.imageTransform != null) {
+ this.curTransform = new AffineTransform(imageTransform);
+ curTransform.scale(scale, scale);
+ curTransform.translate(this.underlayImgDx, this.underlayImgDy);
+ }
+ }
+
+ /**
+ * Sets the source for the map graphics and enables map graphics showing
+ * @param simMap The map to show
+ */
+ public void setMap(SimMap simMap) {
+ this.mapGraphic = new MapGraphic(simMap);
+ this.showMapGraphic = true;
+ }
+
+ /**
+ * Enables/disables showing of map graphics
+ * @param show True if the map graphics should be shown (false if not)
+ */
+ public void setShowMapGraphic(boolean show) {
+ this.showMapGraphic = show;
+ }
+
+ /**
+ * Enables or disables the automatic clearing of overlay graphics.
+ * If enabled, overlay graphics are cleared every time a new graphics
+ * object is set to be drawn.
+ * @param clear Auto clear is enabled if this is true, disabled on false
+ */
+ public void setAutoClearOverlay(boolean clear) {
+ this.autoClearOverlay = clear;
+ }
+
/**
* Enables or disables the automatic clearing of overlay graphics.
* If enabled, overlay graphics are cleared every time a new graphics
@@ -165,124 +165,124 @@ public void setAutoClearOverlay(boolean clear) {
public void setFocusOnClick(boolean focus) {
this.focusOnClick = focus;
}
-
- /**
- * Draws the play field. To be called by Swing framework or directly if
- * different context than screen is desired
- * @param g The graphics context to draw the field to
- */
- public void paint(Graphics g) {
- Graphics2D g2 = (Graphics2D)g;
- g2.setBackground(bgColor);
-
+
+ /**
+ * Draws the play field. To be called by Swing framework or directly if
+ * different context than screen is desired
+ * @param g The graphics context to draw the field to
+ */
+ public void paint(Graphics g) {
+ Graphics2D g2 = (Graphics2D)g;
+ g2.setBackground(bgColor);
+
g2.translate(PLAYFIELD_OFFSET, PLAYFIELD_OFFSET);
-
- // clear old playfield graphics
- g2.clearRect(-PLAYFIELD_OFFSET, -PLAYFIELD_OFFSET,
- this.getWidth() + PLAYFIELD_OFFSET,
- this.getHeight() + PLAYFIELD_OFFSET);
- if (underlayImage != null) {
- g2.drawImage(underlayImage,curTransform, null);
- }
-
- // draw map (is exists and drawing requested)
- if (mapGraphic != null && showMapGraphic) {
- mapGraphic.draw(g2);
- }
-
- // draw hosts
- for (DTNHost h : w.getHosts()) {
- new NodeGraphic(h).draw(g2);
- }
-
- // draw overlay graphics
- for (int i=0, n=overlayGraphics.size(); i
-
-
-
-Contains the classes of Graphical User Interface's playfield -view
-(the graphical presentation of the nodes' locations and other information).
-
-
-
\ No newline at end of file
+
+
+
+
+Contains the classes of Graphical User Interface's playfield -view
+(the graphical presentation of the nodes' locations and other information).
+
+
+
diff --git a/input/BinaryEventsReader.java b/input/BinaryEventsReader.java
index b51b038cc..5612dda78 100644
--- a/input/BinaryEventsReader.java
+++ b/input/BinaryEventsReader.java
@@ -1,9 +1,9 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package input;
-
+package input;
+
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -14,124 +14,124 @@
import java.util.List;
import core.SimError;
-
-/**
- * Reads External Events from a binary file. Can also create binary files
- * from a list of external events.
- */
-public class BinaryEventsReader implements ExternalEventsReader {
- /** Extension of binary external events file */
- public static final String BINARY_EXT = ".binee";
-
- private ObjectInputStream in;
- private int eventsLeft;
-
- /**
- * Constructor.
- * @param eventsFile The file where the events are read
- */
- public BinaryEventsReader(File eventsFile) {
- try {
- FileInputStream fis = new FileInputStream(eventsFile);
- in = new ObjectInputStream(fis);
- // first object should tell the amount of events
- eventsLeft = (Integer)in.readObject();
- } catch (IOException e) {
- throw new SimError(e);
- } catch (ClassNotFoundException e) {
- throw new SimError("Invalid binary input file for external " +
- "events:" + eventsFile.getAbsolutePath(), e);
- }
-
- }
-
- /**
- * Read events from a binary file created with storeBinaryFile method
- * @param nrof Maximum number of events to read
- * @return Events in an ArrayList (empty list if didn't read any)
- * @see #storeToBinaryFile(String, List)
- */
- @SuppressWarnings("unchecked") // suppress cast warnings
- public List readEvents(int nrof) {
- ArrayList events = new ArrayList(nrof);
-
- if (eventsLeft == 0) {
- return events;
- }
-
- try {
- for (int i=0; i < nrof && eventsLeft > 0; i++) {
- events.add((ExternalEvent)in.readObject());
- eventsLeft--;
- }
- if (eventsLeft == 0) {
- in.close();
- }
- } catch (Exception e) { // FIXME: quick 'n' dirty exception handling
- throw new SimError(e);
- }
- return events;
- }
-
- /**
- * Checks if the given file is a binary external events file
- * @param file The file to check
- * @return True if the file is a binary ee file, false if not
- */
- public static boolean isBinaryEeFile(File file) {
- if (!file.getName().endsWith(BINARY_EXT)) {
- return false;
- }
-
- // extension matches, try to read an event
- try {
- BinaryEventsReader r = new BinaryEventsReader(file);
- r.readEvents(1);
- r.close();
- }
- catch (SimError e) {
- return false; // read failed -> not a valid file
- }
-
- return true; // seems to be a valid binary ee file
- }
-
- /**
- * Stores the events to a binary file
- * @param fileName Path to the file where the events are stored
- * @param events List of events to store
- * @throws IOException if something in storing went wrong
- */
- public static void storeToBinaryFile(String fileName,
- List events) throws IOException {
-
- // make sure the file name ends with binary extension
- if (!fileName.endsWith(BINARY_EXT)) {
- fileName += "BINARY_EXT";
- }
-
- ObjectOutputStream out;
- FileOutputStream fos = new FileOutputStream(fileName);
- out = new ObjectOutputStream(fos);
-
- // store the number of events
- out.writeObject(new Integer(events.size()));
-
- // store events
- for (ExternalEvent ee : events) {
- out.writeObject(ee);
- }
-
- out.close();
- }
-
- public void close() {
- try {
- this.in.close();
- }
- catch (IOException ioe) {
- throw new SimError(ioe);
- }
- }
-
-}
+
+/**
+ * Reads External Events from a binary file. Can also create binary files
+ * from a list of external events.
+ */
+public class BinaryEventsReader implements ExternalEventsReader {
+ /** Extension of binary external events file */
+ public static final String BINARY_EXT = ".binee";
+
+ private ObjectInputStream in;
+ private int eventsLeft;
+
+ /**
+ * Constructor.
+ * @param eventsFile The file where the events are read
+ */
+ public BinaryEventsReader(File eventsFile) {
+ try {
+ FileInputStream fis = new FileInputStream(eventsFile);
+ in = new ObjectInputStream(fis);
+ // first object should tell the amount of events
+ eventsLeft = (Integer)in.readObject();
+ } catch (IOException e) {
+ throw new SimError(e);
+ } catch (ClassNotFoundException e) {
+ throw new SimError("Invalid binary input file for external " +
+ "events:" + eventsFile.getAbsolutePath(), e);
+ }
+
+ }
+
+ /**
+ * Read events from a binary file created with storeBinaryFile method
+ * @param nrof Maximum number of events to read
+ * @return Events in an ArrayList (empty list if didn't read any)
+ * @see #storeToBinaryFile(String, List)
+ */
+ @SuppressWarnings("unchecked") // suppress cast warnings
+ public List readEvents(int nrof) {
+ ArrayList events = new ArrayList(nrof);
+
+ if (eventsLeft == 0) {
+ return events;
+ }
+
+ try {
+ for (int i=0; i < nrof && eventsLeft > 0; i++) {
+ events.add((ExternalEvent)in.readObject());
+ eventsLeft--;
+ }
+ if (eventsLeft == 0) {
+ in.close();
+ }
+ } catch (Exception e) { // FIXME: quick 'n' dirty exception handling
+ throw new SimError(e);
+ }
+ return events;
+ }
+
+ /**
+ * Checks if the given file is a binary external events file
+ * @param file The file to check
+ * @return True if the file is a binary ee file, false if not
+ */
+ public static boolean isBinaryEeFile(File file) {
+ if (!file.getName().endsWith(BINARY_EXT)) {
+ return false;
+ }
+
+ // extension matches, try to read an event
+ try {
+ BinaryEventsReader r = new BinaryEventsReader(file);
+ r.readEvents(1);
+ r.close();
+ }
+ catch (SimError e) {
+ return false; // read failed -> not a valid file
+ }
+
+ return true; // seems to be a valid binary ee file
+ }
+
+ /**
+ * Stores the events to a binary file
+ * @param fileName Path to the file where the events are stored
+ * @param events List of events to store
+ * @throws IOException if something in storing went wrong
+ */
+ public static void storeToBinaryFile(String fileName,
+ List events) throws IOException {
+
+ // make sure the file name ends with binary extension
+ if (!fileName.endsWith(BINARY_EXT)) {
+ fileName += "BINARY_EXT";
+ }
+
+ ObjectOutputStream out;
+ FileOutputStream fos = new FileOutputStream(fileName);
+ out = new ObjectOutputStream(fos);
+
+ // store the number of events
+ out.writeObject(new Integer(events.size()));
+
+ // store events
+ for (ExternalEvent ee : events) {
+ out.writeObject(ee);
+ }
+
+ out.close();
+ }
+
+ public void close() {
+ try {
+ this.in.close();
+ }
+ catch (IOException ioe) {
+ throw new SimError(ioe);
+ }
+ }
+
+}
diff --git a/input/ConnectionEvent.java b/input/ConnectionEvent.java
index e5f616aa7..d4f412d68 100644
--- a/input/ConnectionEvent.java
+++ b/input/ConnectionEvent.java
@@ -1,54 +1,54 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package input;
+package input;
import core.DTNHost;
import core.World;
-
-/**
- * A connection up/down event.
- */
-public class ConnectionEvent extends ExternalEvent {
- /** address of the node the (dis)connection is from */
- protected int fromAddr;
- /** address of the node the (dis)connection is to */
- protected int toAddr;
- /** Is this a "connection up" event*/
+
+/**
+ * A connection up/down event.
+ */
+public class ConnectionEvent extends ExternalEvent {
+ /** address of the node the (dis)connection is from */
+ protected int fromAddr;
+ /** address of the node the (dis)connection is to */
+ protected int toAddr;
+ /** Is this a "connection up" event*/
protected boolean isUp;
/** What is the interface number for this event*/
- protected String interfaceId;
-
- /**
- * Creates a new connection event
- * @param from End point of connection
+ protected String interfaceId;
+
+ /**
+ * Creates a new connection event
+ * @param from End point of connection
* @param to Another end of connection
- * @param interf The number of interface for the connection
+ * @param interf The number of interface for the connection
* @param up If true, this was a "connection up" event, if false, this
- * was a "connection down" event
- * @param time Time when the Connection event occurs
- */
- public ConnectionEvent(int from, int to, String interf, boolean up, double time) {
+ * was a "connection down" event
+ * @param time Time when the Connection event occurs
+ */
+ public ConnectionEvent(int from, int to, String interf, boolean up, double time) {
super(time);
- assert to != from : "Can't self connect";
- this.fromAddr = from;
- this.toAddr= to;
+ assert to != from : "Can't self connect";
+ this.fromAddr = from;
+ this.toAddr= to;
this.isUp = up;
- this.interfaceId = interf;
- }
-
+ this.interfaceId = interf;
+ }
+
@Override
public void processEvent(World world) {
DTNHost from = world.getNodeByAddress(this.fromAddr);
DTNHost to = world.getNodeByAddress(this.toAddr);
-
+
from.forceConnection(to, interfaceId, this.isUp);
}
-
- @Override
- public String toString() {
- return "CONN " + (isUp ? "up" : "down") + " @" + this.time + " " +
- this.fromAddr+"<->"+this.toAddr;
- }
-}
+
+ @Override
+ public String toString() {
+ return "CONN " + (isUp ? "up" : "down") + " @" + this.time + " " +
+ this.fromAddr+"<->"+this.toAddr;
+ }
+}
diff --git a/input/DTN2Events.java b/input/DTN2Events.java
index ec0311648..d4b8fa87c 100644
--- a/input/DTN2Events.java
+++ b/input/DTN2Events.java
@@ -1,6 +1,6 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
package input;
@@ -31,16 +31,16 @@
* @author teemuk
*/
public class DTN2Events implements EventQueue {
-
+
private Queue events;
-
- /**
+
+ /**
For keeping track of bundles we've seen in the past
Due to the routing implementation in dtnd it's likely
that dtnd will immediately return a bundle that is
forwarded to it from the ONE. */
private Map bundle_list;
-
+
/**
* Creates a new events object.
* @param s Settings
@@ -50,12 +50,12 @@ public DTN2Events(Settings s) {
this.bundle_list = new HashMap();
DTN2Manager.setEvents(this);
}
-
-
+
+
//************************************************************************//
// ParserHandler //
//************************************************************************//
-
+
/**
* Inner class that implements the CLA interface for receiving bundles from
* dtnd.
@@ -67,7 +67,7 @@ public class ParserHandler implements CLAInterface {
private String c_host;
private int c_port;
private DTNConsoleConnection console;
-
+
/**
* Creates a new parser handler.
* @param hostID ID of the host that this parser corresponds to
@@ -75,24 +75,24 @@ public class ParserHandler implements CLAInterface {
* @param consoleHost Hostname of the dtnd
* @param consolePort Console port of the dtnd
*/
- public ParserHandler(int hostID, DTN2Events eventsHandler,
+ public ParserHandler(int hostID, DTN2Events eventsHandler,
String consoleHost, int consolePort) {
this.host_id = hostID;
this.events = eventsHandler;
this.c_host = consoleHost;
this.c_port = consolePort;
}
-
+
//********************************************************************//
// CLAInterface Implementation //
//********************************************************************//
- public BundleTransferReceipt incomingBundle(String location,
+ public BundleTransferReceipt incomingBundle(String location,
CLAParser.BundleAttributes attributes) {
FileInputStream f_in;
-
- CLAInterface.BundleTransferReceipt r =
+
+ CLAInterface.BundleTransferReceipt r =
new CLAInterface.BundleTransferReceipt();
-
+
// Open the bundle file
try {
f_in = new FileInputStream(new File(location));
@@ -101,7 +101,7 @@ public BundleTransferReceipt incomingBundle(String location,
" (file not found)");
return r;
}
-
+
// Make a copy of the bundle
String filepath = "bundles/"+Math.round(Math.random()*1000000000)+
".bundle";
@@ -122,10 +122,10 @@ public BundleTransferReceipt incomingBundle(String location,
} catch (Exception e) {
// TBD
}
-
+
// Parse the bundle
Bundle bundle = new Bundle(new_f);
-
+
// Check that we haven't forwarded this bundle before
if (isReg(bundle)) {
r.reply = false;
@@ -134,18 +134,18 @@ public BundleTransferReceipt incomingBundle(String location,
} else {
regMsg(bundle);
}
-
+
// Lookup the receiving host
- Collection c =
+ Collection c =
DTN2Manager.getHosts(bundle.destination_EID);
if (c==null || c.isEmpty()) {
- Debug.p( "Couldn't find destination matching '" +
+ Debug.p( "Couldn't find destination matching '" +
bundle.destination_EID+"'");
r.reply = false;
r.bytes_sent = 0;
return r;
}
-
+
// Create a message for each matched recipient
// XXX: Ideally we'd only have one message,
// but ONE requires each message to have exactly one recipient
@@ -153,26 +153,26 @@ public BundleTransferReceipt incomingBundle(String location,
// Create a new message in the queue
this.events.enqueMsg(this.host_id, e.host_id, bundle);
}
-
+
// Pretend we've transmitted the whole bundle
r.reply = true;
r.bytes_sent = bundle.file.length();
-
+
return r;
}
public void connected() {
- /* The ECLA has been connected, we can now set it up through
+ /* The ECLA has been connected, we can now set it up through
the console */
this.console = new DTNConsoleConnection(this.c_host, this.c_port);
Thread t = new Thread(this.console);
t.start();
- this.console.queue("link add one dtn:one ALWAYSON extcl " +
+ this.console.queue("link add one dtn:one ALWAYSON extcl " +
"protocol=ONE\n");
this.console.queue("route add \"dtn://*\" one\n");
}
- public boolean error(String reason, Exception exception,
+ public boolean error(String reason, Exception exception,
boolean fatal) {
return false;
}
@@ -183,9 +183,9 @@ public boolean parseError(String reason) {
//********************************************************************//
}
//************************************************************************//
-
-
-
+
+
+
//************************************************************************//
// EventQueue Implementation //
//************************************************************************//
@@ -195,7 +195,7 @@ public ExternalEvent nextEvent() {
} else
return new ExternalEvent(Double.MAX_VALUE);
}
-
+
public double nextEventsTime() {
if (!this.events.isEmpty())
return SimClock.getTime();
@@ -203,25 +203,25 @@ public double nextEventsTime() {
return Double.MAX_VALUE;
}
//************************************************************************//
-
-
+
+
//************************************************************************//
// Public Methods //
//************************************************************************//
-
+
/**
* Creates a parser handler for the given host.
* @param hostID ID of the host that this parser corresponds to
* @param consoleHost Hostname of the dtnd
* @param consolePort Console port of the dtnd
*/
- public DTN2Events.ParserHandler getParserHandler(int hostID,
+ public DTN2Events.ParserHandler getParserHandler(int hostID,
String consoleHost, int consolePort) {
return new ParserHandler(hostID, this, consoleHost, consolePort);
}
//************************************************************************//
-
-
+
+
//************************************************************************//
// Private Methods //
//************************************************************************//
@@ -229,14 +229,14 @@ private void enqueMsg(int from, int to, Bundle bundle) {
String id;
id = "bundle."+from+"-"+to+"-"+bundle.creation_timestamp_time+
"-"+bundle.creation_timestamp_seq_no;
- MessageCreateEvent e = new MessageCreateEvent(from, to, id,
+ MessageCreateEvent e = new MessageCreateEvent(from, to, id,
(int)(bundle.file.length()), 0, SimClock.getTime());
synchronized (this.events) {
this.events.add(e);
}
DTN2Manager.addBundle(id,bundle);
}
-
+
// Keep track of the bundles we've received
private void regMsg(Bundle bundle) {
String key = bundle.source_EID+":"+bundle.destination_EID+":"+
@@ -244,7 +244,7 @@ private void regMsg(Bundle bundle) {
if (!this.bundle_list.containsKey(key))
this.bundle_list.put(key,null);
}
-
+
// Check if the bundle has been received before
private boolean isReg(Bundle bundle) {
String key = bundle.source_EID+":"+bundle.destination_EID+":"+
@@ -252,5 +252,5 @@ private boolean isReg(Bundle bundle) {
return this.bundle_list.containsKey(key);
}
//************************************************************************//
-
+
}
diff --git a/input/EventQueue.java b/input/EventQueue.java
index df0c67bd9..e653cb207 100644
--- a/input/EventQueue.java
+++ b/input/EventQueue.java
@@ -1,30 +1,30 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
- */
-package input;
-
-/**
- * Interface for event queues. Any class that is not a movement model or a
- * routing module but wishes to provide events for the simulation (like creating
- * messages) must implement this interface and register itself to the
- * simulator. See the {@link EventQueueHandler} class for configuration
- * instructions.
- */
-public interface EventQueue {
-
- /**
- * Returns the next event in the queue or ExternalEvent with time of
- * double.MAX_VALUE if there are no events left.
- * @return The next event
- */
- public ExternalEvent nextEvent();
-
- /**
- * Returns next event's time or Double.MAX_VALUE if there are no
- * events left in the queue.
- * @return Next event's time
- */
- public double nextEventsTime();
-
-}
+ * Released under GPLv3. See LICENSE.txt for details.
+ */
+package input;
+
+/**
+ * Interface for event queues. Any class that is not a movement model or a
+ * routing module but wishes to provide events for the simulation (like creating
+ * messages) must implement this interface and register itself to the
+ * simulator. See the {@link EventQueueHandler} class for configuration
+ * instructions.
+ */
+public interface EventQueue {
+
+ /**
+ * Returns the next event in the queue or ExternalEvent with time of
+ * double.MAX_VALUE if there are no events left.
+ * @return The next event
+ */
+ public ExternalEvent nextEvent();
+
+ /**
+ * Returns next event's time or Double.MAX_VALUE if there are no
+ * events left in the queue.
+ * @return Next event's time
+ */
+ public double nextEventsTime();
+
+}
diff --git a/input/EventQueueHandler.java b/input/EventQueueHandler.java
index 90fa5f4d7..93fbf0d09 100644
--- a/input/EventQueueHandler.java
+++ b/input/EventQueueHandler.java
@@ -1,40 +1,40 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package input;
-
+package input;
+
import java.util.ArrayList;
import java.util.List;
import core.Settings;
-
+
/**
*
- * Handler for managing event queues. Supports two different type of event
+ * Handler for managing event queues. Supports two different type of event
* queues: external event queues and event generator classes.
* For external event queues, the events are defined in external data
* file(s) (see e.g. input.StandarEventsReader). Event generator classes
* define events dynamically. Both type of event queues must implement
* the input.EventQueue interface.
*
- * The total number of event queues to load is defined with variable
+ * The total number of event queues to load is defined with variable
* NROF_SETTING
, e.g.
* Events.nrof = 3
- * Separate event queues are configured with syntax
+ * Separate event queues are configured with syntax
* EventsN.variable = value
e.g.:
* Events1.filePath = ee/messages.txt
* or
* Events2.class = RandomMessageGenerator
*
* External event files are used when the variable PATH_SETTING
- * is used to define the path to the event file and event generator class
- * is loaded when the name of the class is defined with
- * CLASS_SETTING
.
- */
-public class EventQueueHandler {
- /** Event queue settings main namespace ({@value})*/
- public static final String SETTINGS_NAMESPACE = "Events";
+ * is used to define the path to the event file and event generator class
+ * is loaded when the name of the class is defined with
+ * CLASS_SETTING
.
+ */
+public class EventQueueHandler {
+ /** Event queue settings main namespace ({@value})*/
+ public static final String SETTINGS_NAMESPACE = "Events";
/** number of event queues -setting id ({@value})*/
public static final String NROF_SETTING = "nrof";
@@ -43,22 +43,22 @@ public class EventQueueHandler {
public static final String CLASS_SETTING = "class";
/** name of the package where event generator classes are looked from */
public static final String CLASS_PACKAGE = "input";
-
- /** number of events to preload from file -setting id ({@value})*/
- public static final String PRELOAD_SETTING = "nrofPreload";
- /** path of external events file -setting id ({@value})*/
- public static final String PATH_SETTING = "filePath";
-
- private List queues;
-
- /**
- * Creates a new EventQueueHandler which can be queried for
- * event queues.
- */
- public EventQueueHandler() {
+
+ /** number of events to preload from file -setting id ({@value})*/
+ public static final String PRELOAD_SETTING = "nrofPreload";
+ /** path of external events file -setting id ({@value})*/
+ public static final String PATH_SETTING = "filePath";
+
+ private List queues;
+
+ /**
+ * Creates a new EventQueueHandler which can be queried for
+ * event queues.
+ */
+ public EventQueueHandler() {
Settings settings = new Settings(SETTINGS_NAMESPACE);
int nrof = settings.getInt(NROF_SETTING);
- this.queues = new ArrayList();
+ this.queues = new ArrayList();
for (int i=1; i <= nrof; i++) {
Settings s = new Settings(SETTINGS_NAMESPACE + i);
@@ -74,21 +74,21 @@ public EventQueueHandler() {
queues.add(new ExternalEventsQueue(path, preload));
}
else if (s.contains(CLASS_SETTING)) { // event generator class
- String className = CLASS_PACKAGE + "." +
+ String className = CLASS_PACKAGE + "." +
s.getSetting(CLASS_SETTING);
EventQueue eq = (EventQueue)s.createIntializedObject(className);
-
+
queues.add(eq);
- }
- }
+ }
+ }
}
-
- /**
+
+ /**
* Returns all the loaded event queues
* @return all the loaded event queues
*/
public List getEventQueues() {
return this.queues;
- }
-
-}
+ }
+
+}
diff --git a/input/ExternalEvent.java b/input/ExternalEvent.java
index 9a81fc86c..130067637 100644
--- a/input/ExternalEvent.java
+++ b/input/ExternalEvent.java
@@ -1,66 +1,66 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package input;
-
+package input;
+
import java.io.Serializable;
import core.World;
-
-/**
- * Super class for all external events. All new classes of external events
+
+/**
+ * Super class for all external events. All new classes of external events
* must extend this class. This can also be used as a dummy event if only
- * an update request (and no further actions) to all hosts is needed.
- */
-public class ExternalEvent implements Comparable, Serializable {
- /** Time of the event (simulated seconds) */
- protected double time;
-
- public ExternalEvent(double time) {
- this.time = time;
- }
-
- /**
- * Processes the external event.
- * @param world World where the actors of the event are
- */
- public void processEvent(World world) {
- // this is just a dummy event
- }
-
- /**
- * Returns the time when this event should happen.
- * @return Event's time
- */
- public double getTime() {
- return this.time;
- }
-
- /**
- * Compares two external events by their time.
- * @return -1, zero, 1 if this event happens before, at the same time,
- * or after the other event
- * @param other The other external event
- */
+ * an update request (and no further actions) to all hosts is needed.
+ */
+public class ExternalEvent implements Comparable, Serializable {
+ /** Time of the event (simulated seconds) */
+ protected double time;
+
+ public ExternalEvent(double time) {
+ this.time = time;
+ }
+
+ /**
+ * Processes the external event.
+ * @param world World where the actors of the event are
+ */
+ public void processEvent(World world) {
+ // this is just a dummy event
+ }
+
+ /**
+ * Returns the time when this event should happen.
+ * @return Event's time
+ */
+ public double getTime() {
+ return this.time;
+ }
+
+ /**
+ * Compares two external events by their time.
+ * @return -1, zero, 1 if this event happens before, at the same time,
+ * or after the other event
+ * @param other The other external event
+ */
public int compareTo(ExternalEvent other) {
- if (this.time == other.time) {
+ if (this.time == other.time) {
return 0;
}
else if (this.time < other.time) {
return -1;
- }
+ }
else {
return 1;
- }
- }
-
- /**
- * Returns a String representation of the event
- * @return a String representation of the event
- */
- public String toString() {
- return "ExtEvent @ " + this.time;
- }
-
-}
+ }
+ }
+
+ /**
+ * Returns a String representation of the event
+ * @return a String representation of the event
+ */
+ public String toString() {
+ return "ExtEvent @ " + this.time;
+ }
+
+}
diff --git a/input/ExternalEventsQueue.java b/input/ExternalEventsQueue.java
index 108540a20..90665887d 100644
--- a/input/ExternalEventsQueue.java
+++ b/input/ExternalEventsQueue.java
@@ -1,51 +1,51 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package input;
-
+package input;
+
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import core.Settings;
-
-/**
- * Queue of external events. This class also takes care of buffering
- * the events and preloading only a proper amount of them.
- */
-public class ExternalEventsQueue implements EventQueue {
- /** ExternalEvents namespace ({@value})*/
- public static final String SETTINGS_NAMESPACE = "ExternalEvents";
- /** number of event to preload -setting id ({@value})*/
- public static final String PRELOAD_SETTING = "nrofPreload";
- /** path of external events file -setting id ({@value})*/
+
+/**
+ * Queue of external events. This class also takes care of buffering
+ * the events and preloading only a proper amount of them.
+ */
+public class ExternalEventsQueue implements EventQueue {
+ /** ExternalEvents namespace ({@value})*/
+ public static final String SETTINGS_NAMESPACE = "ExternalEvents";
+ /** number of event to preload -setting id ({@value})*/
+ public static final String PRELOAD_SETTING = "nrofPreload";
+ /** path of external events file -setting id ({@value})*/
public static final String PATH_SETTING = "filePath";
-
+
/** default number of preloaded events */
- public static final int DEFAULT_NROF_PRELOAD = 500;
-
- private File eventsFile;
- private ExternalEventsReader reader;
- private int nextEventIndex;
- private int nrofPreload;
- private List queue;
- private boolean allEventsRead = false;
-
- /**
- * Creates a new Queue from a file
- * @param filePath Path to the file where the events are read from. If
- * file ends with extension defined in {@link BinaryEventsReader#BINARY_EXT}
- * the file is assumed to be a binary file.
- * @param nrofPreload How many events to preload
- * @see BinaryEventsReader#BINARY_EXT
- * @see BinaryEventsReader#storeToBinaryFile(String, List)
- */
- public ExternalEventsQueue(String filePath, int nrofPreload) {
- setNrofPreload(nrofPreload);
- init(filePath);
+ public static final int DEFAULT_NROF_PRELOAD = 500;
+
+ private File eventsFile;
+ private ExternalEventsReader reader;
+ private int nextEventIndex;
+ private int nrofPreload;
+ private List queue;
+ private boolean allEventsRead = false;
+
+ /**
+ * Creates a new Queue from a file
+ * @param filePath Path to the file where the events are read from. If
+ * file ends with extension defined in {@link BinaryEventsReader#BINARY_EXT}
+ * the file is assumed to be a binary file.
+ * @param nrofPreload How many events to preload
+ * @see BinaryEventsReader#BINARY_EXT
+ * @see BinaryEventsReader#storeToBinaryFile(String, List)
+ */
+ public ExternalEventsQueue(String filePath, int nrofPreload) {
+ setNrofPreload(nrofPreload);
+ init(filePath);
}
-
+
/**
* Create a new Queue based on the given settings: {@link #PRELOAD_SETTING}
* and {@link #PATH_SETTING}. The path setting supports value filling.
@@ -60,104 +60,104 @@ public ExternalEventsQueue(Settings s) {
}
String eeFilePath = s.valueFillString(s.getSetting(PATH_SETTING));
init(eeFilePath);
- }
-
- /**
- * Sets maximum number of events that are read when the next preload occurs
+ }
+
+ /**
+ * Sets maximum number of events that are read when the next preload occurs
* @param nrof Maximum number of events to read. If less than 1, default
- * value ( {@value DEFAULT_NROF_PRELOAD} ) is used.
- */
- public void setNrofPreload(int nrof) {
- if (nrof < 1) {
- nrof = DEFAULT_NROF_PRELOAD;
- }
- this.nrofPreload = nrof;
- }
-
- private void init(String eeFilePath) {
- this.eventsFile = new File(eeFilePath);
-
- if (BinaryEventsReader.isBinaryEeFile(eventsFile)) {
- this.reader = new BinaryEventsReader(eventsFile);
- }
- else {
- this.reader = new StandardEventsReader(eventsFile);
- }
-
- this.queue = readEvents(nrofPreload);
- this.nextEventIndex = 0;
- }
-
- /**
- * Returns next event's time or Double.MAX_VALUE if there are no
- * events left
- * @return Next event's time
- */
- public double nextEventsTime() {
- if (eventsLeftInBuffer() <= 0 ) {
- // in case user request time of an event that doesn't exist
- return Double.MAX_VALUE;
- }
- else {
- return queue.get(nextEventIndex).getTime();
- }
- }
-
- /**
- * Returns the next event in the queue or ExternalEvent with time of
- * double.MAX_VALUE if there are no events left
- * @return The next event
- */
- public ExternalEvent nextEvent() {
- if (queue.size() == 0) { // no more events
- return new ExternalEvent(Double.MAX_VALUE);
- }
-
- ExternalEvent ee = queue.get(nextEventIndex);
- nextEventIndex++;
-
- if (nextEventIndex >= queue.size()) { // ran out of events
- queue = readEvents(nrofPreload);
- nextEventIndex = 0;
- }
-
- return ee;
- }
-
- /**
- * Returns the amount of events left in the buffer at the moment
- * (the amount can increase later if more events are read).
- * @return The amount of events left or 0 there aren't any events
- */
- public int eventsLeftInBuffer() {
- if (queue == null || queue.size() == 0) {
- return 0;
- }
- else {
- return this.queue.size() - this.nextEventIndex;
- }
- }
-
-
- /**
- * Read some events from the external events reader
- * @param nrof Maximum number of events to read
- * @return A List of events that were read or an empty list if no events
- * could be read
- */
- private List readEvents(int nrof) {
- if (allEventsRead) {
- return new ArrayList(0);
- }
-
- List events = reader.readEvents(nrof);
-
- if (nrof > 0 && events.size() == 0) {
- reader.close();
- allEventsRead = true;
- }
-
- return events;
- }
-
-}
+ * value ( {@value DEFAULT_NROF_PRELOAD} ) is used.
+ */
+ public void setNrofPreload(int nrof) {
+ if (nrof < 1) {
+ nrof = DEFAULT_NROF_PRELOAD;
+ }
+ this.nrofPreload = nrof;
+ }
+
+ private void init(String eeFilePath) {
+ this.eventsFile = new File(eeFilePath);
+
+ if (BinaryEventsReader.isBinaryEeFile(eventsFile)) {
+ this.reader = new BinaryEventsReader(eventsFile);
+ }
+ else {
+ this.reader = new StandardEventsReader(eventsFile);
+ }
+
+ this.queue = readEvents(nrofPreload);
+ this.nextEventIndex = 0;
+ }
+
+ /**
+ * Returns next event's time or Double.MAX_VALUE if there are no
+ * events left
+ * @return Next event's time
+ */
+ public double nextEventsTime() {
+ if (eventsLeftInBuffer() <= 0 ) {
+ // in case user request time of an event that doesn't exist
+ return Double.MAX_VALUE;
+ }
+ else {
+ return queue.get(nextEventIndex).getTime();
+ }
+ }
+
+ /**
+ * Returns the next event in the queue or ExternalEvent with time of
+ * double.MAX_VALUE if there are no events left
+ * @return The next event
+ */
+ public ExternalEvent nextEvent() {
+ if (queue.size() == 0) { // no more events
+ return new ExternalEvent(Double.MAX_VALUE);
+ }
+
+ ExternalEvent ee = queue.get(nextEventIndex);
+ nextEventIndex++;
+
+ if (nextEventIndex >= queue.size()) { // ran out of events
+ queue = readEvents(nrofPreload);
+ nextEventIndex = 0;
+ }
+
+ return ee;
+ }
+
+ /**
+ * Returns the amount of events left in the buffer at the moment
+ * (the amount can increase later if more events are read).
+ * @return The amount of events left or 0 there aren't any events
+ */
+ public int eventsLeftInBuffer() {
+ if (queue == null || queue.size() == 0) {
+ return 0;
+ }
+ else {
+ return this.queue.size() - this.nextEventIndex;
+ }
+ }
+
+
+ /**
+ * Read some events from the external events reader
+ * @param nrof Maximum number of events to read
+ * @return A List of events that were read or an empty list if no events
+ * could be read
+ */
+ private List readEvents(int nrof) {
+ if (allEventsRead) {
+ return new ArrayList(0);
+ }
+
+ List events = reader.readEvents(nrof);
+
+ if (nrof > 0 && events.size() == 0) {
+ reader.close();
+ allEventsRead = true;
+ }
+
+ return events;
+ }
+
+}
diff --git a/input/ExternalEventsReader.java b/input/ExternalEventsReader.java
index 01fc065df..b010617c1 100644
--- a/input/ExternalEventsReader.java
+++ b/input/ExternalEventsReader.java
@@ -1,27 +1,27 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package input;
-
+package input;
+
import java.util.List;
-
-/**
- * Interface for external event readers.
- */
-public interface ExternalEventsReader {
-
- /**
- * Read events from the reader
- * @param nrof Maximum number of events to read
- * @return Events in a List
- */
- public List readEvents(int nrof);
-
- /**
- * Closes the input file streams of the reader.
- */
- public void close();
-
-
-}
+
+/**
+ * Interface for external event readers.
+ */
+public interface ExternalEventsReader {
+
+ /**
+ * Read events from the reader
+ * @param nrof Maximum number of events to read
+ * @return Events in a List
+ */
+ public List readEvents(int nrof);
+
+ /**
+ * Closes the input file streams of the reader.
+ */
+ public void close();
+
+
+}
diff --git a/input/ExternalMovementReader.java b/input/ExternalMovementReader.java
index 1ef7a480f..89ae9aaaf 100644
--- a/input/ExternalMovementReader.java
+++ b/input/ExternalMovementReader.java
@@ -1,9 +1,9 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package input;
-
+package input;
+
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
@@ -14,203 +14,203 @@
import core.Coord;
import core.SettingsError;
-
-
-/**
- * Reader for ExternalMovement movement model's time-location tuples.
- *
- * First line of the file should be the offset header. Syntax of the header
- * should be:
- * minTime maxTime minX maxX minY maxY minZ maxZ
- *
- * Last two values (Z-axis) are ignored at the moment but can be present
- * in the file.
- *
- * Following lines' syntax should be:
- * time id xPos yPos
- * where time
is the time when a node with id
should
- * be at location (xPos, yPos)
.
- *
- *
- * All lines must be sorted by time. Sampling interval (time difference between
- * two time instances) must be same for the whole file.
- *
- */
+
+
+/**
+ * Reader for ExternalMovement movement model's time-location tuples.
+ *
+ * First line of the file should be the offset header. Syntax of the header
+ * should be:
+ * minTime maxTime minX maxX minY maxY minZ maxZ
+ *
+ * Last two values (Z-axis) are ignored at the moment but can be present
+ * in the file.
+ *
+ * Following lines' syntax should be:
+ * time id xPos yPos
+ * where time
is the time when a node with id
should
+ * be at location (xPos, yPos)
.
+ *
+ *
+ * All lines must be sorted by time. Sampling interval (time difference between
+ * two time instances) must be same for the whole file.
+ *
+ */
public class ExternalMovementReader {
/* Prefix for comment lines (lines starting with this are ignored) */
- public static final String COMMENT_PREFIX = "#";
- private Scanner scanner;
- private double lastTimeStamp = -1;
- private String lastLine;
- private double minTime;
- private double maxTime;
- private double minX;
- private double maxX;
- private double minY;
- private double maxY;
- private boolean normalize;
-
-
- /**
- * Constructor. Creates a new reader that reads the data from a file.
- * @param inFilePath Path to the file where the data is read
- * @throws SettingsError if the file wasn't found
- */
- public ExternalMovementReader(String inFilePath) {
- this.normalize = true;
- File inFile = new File(inFilePath);
- try {
- scanner = new Scanner(inFile);
- } catch (FileNotFoundException e) {
- throw new SettingsError("Couldn't find external movement input " +
- "file " + inFile);
- }
-
- String offsets = scanner.nextLine();
-
- try {
- Scanner lineScan = new Scanner(offsets);
- minTime = lineScan.nextDouble();
- maxTime = lineScan.nextDouble();
- minX = lineScan.nextDouble();
- maxX = lineScan.nextDouble();
- minY = lineScan.nextDouble();
- maxY = lineScan.nextDouble();
- } catch (Exception e) {
- throw new SettingsError("Invalid offset line '" + offsets + "'");
- }
-
- lastLine = scanner.nextLine();
- }
-
- /**
- * Sets normalizing of read values on/off. If on, values returned by
- * {@link #readNextMovements()} are decremented by minimum values of the
- * offsets. Default is on (normalize).
- * @param normalize If true, normalizing is on (false -> off).
- */
- public void setNormalize(boolean normalize) {
- this.normalize = normalize;
- }
-
- /**
- * Reads all new id-coordinate tuples that belong to the same time instance
- * @return A list of tuples or empty list if there were no more moves
- * @throws SettingError if an invalid line was read
- */
- public List> readNextMovements() {
- ArrayList> moves =
- new ArrayList>();
-
- if (!scanner.hasNextLine()) {
- return moves;
- }
-
- Scanner lineScan = new Scanner(lastLine);
- double time = lineScan.nextDouble();
- String id = lineScan.next();
- double x = lineScan.nextDouble();
- double y = lineScan.nextDouble();
-
- if (normalize) {
- time -= minTime;
- x -= minX;
- y -= minY;
- }
-
- lastTimeStamp = time;
-
- while (scanner.hasNextLine() && lastTimeStamp == time) {
- lastLine = scanner.nextLine();
-
- if (lastLine.trim().length() == 0 ||
- lastLine.startsWith(COMMENT_PREFIX)) {
- continue; /* skip empty and comment lines */
+ public static final String COMMENT_PREFIX = "#";
+ private Scanner scanner;
+ private double lastTimeStamp = -1;
+ private String lastLine;
+ private double minTime;
+ private double maxTime;
+ private double minX;
+ private double maxX;
+ private double minY;
+ private double maxY;
+ private boolean normalize;
+
+
+ /**
+ * Constructor. Creates a new reader that reads the data from a file.
+ * @param inFilePath Path to the file where the data is read
+ * @throws SettingsError if the file wasn't found
+ */
+ public ExternalMovementReader(String inFilePath) {
+ this.normalize = true;
+ File inFile = new File(inFilePath);
+ try {
+ scanner = new Scanner(inFile);
+ } catch (FileNotFoundException e) {
+ throw new SettingsError("Couldn't find external movement input " +
+ "file " + inFile);
+ }
+
+ String offsets = scanner.nextLine();
+
+ try {
+ Scanner lineScan = new Scanner(offsets);
+ minTime = lineScan.nextDouble();
+ maxTime = lineScan.nextDouble();
+ minX = lineScan.nextDouble();
+ maxX = lineScan.nextDouble();
+ minY = lineScan.nextDouble();
+ maxY = lineScan.nextDouble();
+ } catch (Exception e) {
+ throw new SettingsError("Invalid offset line '" + offsets + "'");
+ }
+
+ lastLine = scanner.nextLine();
+ }
+
+ /**
+ * Sets normalizing of read values on/off. If on, values returned by
+ * {@link #readNextMovements()} are decremented by minimum values of the
+ * offsets. Default is on (normalize).
+ * @param normalize If true, normalizing is on (false -> off).
+ */
+ public void setNormalize(boolean normalize) {
+ this.normalize = normalize;
+ }
+
+ /**
+ * Reads all new id-coordinate tuples that belong to the same time instance
+ * @return A list of tuples or empty list if there were no more moves
+ * @throws SettingError if an invalid line was read
+ */
+ public List> readNextMovements() {
+ ArrayList> moves =
+ new ArrayList>();
+
+ if (!scanner.hasNextLine()) {
+ return moves;
+ }
+
+ Scanner lineScan = new Scanner(lastLine);
+ double time = lineScan.nextDouble();
+ String id = lineScan.next();
+ double x = lineScan.nextDouble();
+ double y = lineScan.nextDouble();
+
+ if (normalize) {
+ time -= minTime;
+ x -= minX;
+ y -= minY;
+ }
+
+ lastTimeStamp = time;
+
+ while (scanner.hasNextLine() && lastTimeStamp == time) {
+ lastLine = scanner.nextLine();
+
+ if (lastLine.trim().length() == 0 ||
+ lastLine.startsWith(COMMENT_PREFIX)) {
+ continue; /* skip empty and comment lines */
}
-
- // add previous line's tuple
- moves.add(new Tuple(id, new Coord(x,y)));
-
- lineScan = new Scanner(lastLine);
-
- try {
- time = lineScan.nextDouble();
- id = lineScan.next();
- x = lineScan.nextDouble();
- y = lineScan.nextDouble();
- } catch (Exception e) {
- throw new SettingsError("Invalid line '" + lastLine + "'");
- }
-
- if (normalize) {
- time -= minTime;
- x -= minX;
- y -= minY;
- }
- }
-
- if (!scanner.hasNextLine()) { // add the last tuple of the file
- moves.add(new Tuple(id, new Coord(x,y)));
- }
-
- return moves;
- }
-
- /**
- * Returns the time stamp where the last moves read with
- * {@link #readNextMovements()} belong to.
- * @return The time stamp
- */
- public double getLastTimeStamp() {
- return lastTimeStamp;
- }
-
- /**
- * Returns offset maxTime
- * @return the maxTime
- */
- public double getMaxTime() {
- return maxTime;
- }
-
- /**
- * Returns offset maxX
- * @return the maxX
- */
- public double getMaxX() {
- return maxX;
- }
-
- /**
- * Returns offset maxY
- * @return the maxY
- */
- public double getMaxY() {
- return maxY;
- }
-
- /**
- * Returns offset minTime
- * @return the minTime
- */
- public double getMinTime() {
- return minTime;
- }
-
- /**
- * Returns offset minX
- * @return the minX
- */
- public double getMinX() {
- return minX;
- }
-
- /**
- * Returns offset minY
- * @return the minY
- */
- public double getMinY() {
- return minY;
- }
-
-}
+
+ // add previous line's tuple
+ moves.add(new Tuple(id, new Coord(x,y)));
+
+ lineScan = new Scanner(lastLine);
+
+ try {
+ time = lineScan.nextDouble();
+ id = lineScan.next();
+ x = lineScan.nextDouble();
+ y = lineScan.nextDouble();
+ } catch (Exception e) {
+ throw new SettingsError("Invalid line '" + lastLine + "'");
+ }
+
+ if (normalize) {
+ time -= minTime;
+ x -= minX;
+ y -= minY;
+ }
+ }
+
+ if (!scanner.hasNextLine()) { // add the last tuple of the file
+ moves.add(new Tuple(id, new Coord(x,y)));
+ }
+
+ return moves;
+ }
+
+ /**
+ * Returns the time stamp where the last moves read with
+ * {@link #readNextMovements()} belong to.
+ * @return The time stamp
+ */
+ public double getLastTimeStamp() {
+ return lastTimeStamp;
+ }
+
+ /**
+ * Returns offset maxTime
+ * @return the maxTime
+ */
+ public double getMaxTime() {
+ return maxTime;
+ }
+
+ /**
+ * Returns offset maxX
+ * @return the maxX
+ */
+ public double getMaxX() {
+ return maxX;
+ }
+
+ /**
+ * Returns offset maxY
+ * @return the maxY
+ */
+ public double getMaxY() {
+ return maxY;
+ }
+
+ /**
+ * Returns offset minTime
+ * @return the minTime
+ */
+ public double getMinTime() {
+ return minTime;
+ }
+
+ /**
+ * Returns offset minX
+ * @return the minX
+ */
+ public double getMinX() {
+ return minX;
+ }
+
+ /**
+ * Returns offset minY
+ * @return the minY
+ */
+ public double getMinY() {
+ return minY;
+ }
+
+}
diff --git a/input/ExternalPathMovementReader.java b/input/ExternalPathMovementReader.java
index b49d95628..1a4085f50 100644
--- a/input/ExternalPathMovementReader.java
+++ b/input/ExternalPathMovementReader.java
@@ -1,6 +1,6 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
package input;
@@ -23,41 +23,41 @@
import core.SettingsError;
-/**
+/**
* External movement reader for traces that are in path format. Uses two
* trace files, one for the paths and one for specifying activity times.
* Nodes will follow the paths in the trace file, and pause between paths.
* Activity times refer to the periods of time when there is valid trace data
* about the node.
- *
+ *
* Reads external traces that are of the form:
* id time_1,x_1,y_1 time_2,x_2,y_2 ... \n
- *
+ *
* The first line should be:>
* maxID minTime maxTime minX maxX minY maxY
- *
+ *
*
Activity trace file format is:
* id activeStart activeEnd\n
- *
+ *
*
* The ID in the trace files must match IDs of nodes in the simulation, the
* coordinates must match the ONE coordinate system (units in meters) and the
* times must match the ONE simulation time.
*
- *
+ *
* Trace and activity files ending in .zip are assumed to be
* compressed and will be automatically uncompressed during reading. The whole
* trace is loaded into memory at once.
- *
+ *
* @author teemuk
*
*/
public class ExternalPathMovementReader {
// Singletons are evil, but I'm lazy
- private static Map singletons =
+ private static Map singletons =
new HashMap();
-
- /**
+
+ /**
* Represents a point on the path.
*/
public class Entry {
@@ -65,20 +65,20 @@ public class Entry {
public double x;
public double y;
}
-
- /**
+
+ /**
* Describes a node's activity time
*/
public class ActiveTime {
public double start;
public double end;
}
-
+
// Path cache
private List>> paths = null;
// Activity cache
private List> activeTimes = null;
-
+
// Settings
private boolean normalize = true;
private double minTime;
@@ -88,11 +88,11 @@ public class ActiveTime {
private double minY;
private double maxY;
private int maxID;
-
- /**
+
+ /**
* Creates a new reader by parsing the given files and building the internal
* caches.
- *
+ *
* @param traceFilePath path to the trace file
* @param activityFilePath path to the activity file
*/
@@ -104,7 +104,7 @@ private ExternalPathMovementReader(String traceFilePath,
long totalRead = 0;
long readSize = 0;
long printSize = 5*1024*1024;
-
+
BufferedReader reader = null;
try {
if (traceFilePath.endsWith(".zip")) {
@@ -123,7 +123,7 @@ private ExternalPathMovementReader(String traceFilePath,
throw new SettingsError("Couldn't find external movement input " +
"file " + inFile);
}
-
+
/*Scanner scanner = null;
try {
scanner = new Scanner(inFile);
@@ -131,7 +131,7 @@ private ExternalPathMovementReader(String traceFilePath,
throw new SettingsError("Couldn't find external movement input " +
"file " + inFile);
}*/
-
+
// Parse header
String offsets = reader.readLine();
if (offsets == null) {
@@ -150,17 +150,17 @@ private ExternalPathMovementReader(String traceFilePath,
} catch (Exception e) {
throw new SettingsError("Invalid offset line '" + offsets + "'");
}
-
+
// Initialize path cache
this.paths = new ArrayList>>(this.maxID + 1);
for (int i=0; i<=this.maxID; i++) {
this.paths.add(i, new LinkedList>());
}
-
+
// Parse traces
String line = reader.readLine();
while (line != null) {
-
+
readSize += line.length() + 1;
if (readSize >= printSize) {
totalRead += readSize;
@@ -169,7 +169,7 @@ private ExternalPathMovementReader(String traceFilePath,
" of " + (traceSize/1024) + "KB (" +
Math.round(100.0*totalRead/traceSize) + "%)");
}
-
+
if (line.equals("")) {
line = reader.readLine();
continue; // Skip empty lines
@@ -182,25 +182,25 @@ private ExternalPathMovementReader(String traceFilePath,
String dataPoint = traceScan.next();
int d1 = dataPoint.indexOf(',');
int d2 = dataPoint.indexOf(',', d1+1);
-
+
Entry e = new Entry();
e.time = Double.parseDouble(dataPoint.substring(0, d1));
e.x = Double.parseDouble(dataPoint.substring(d1+1, d2));
e.y = Double.parseDouble(dataPoint.substring(d2+1));
-
+
if (this.normalize) {
e.time -= this.minTime;
e.x -= this.minX;
e.y -= this.minY;
}
-
+
path.add(e);
}
paths.add(path);
-
+
line = reader.readLine();
}
-
+
// Parse activity times
inFile = new File(activityFilePath);
reader = null;
@@ -220,13 +220,13 @@ private ExternalPathMovementReader(String traceFilePath,
throw new SettingsError("Couldn't find external activity input " +
"file " + inFile);
}
-
+
// Init activity cache
this.activeTimes = new ArrayList>(this.maxID + 1);
for (int i=0; i<=this.maxID; i++) {
this.activeTimes.add(new LinkedList());
}
-
+
// Parse the file
line = reader.readLine();
while (line != null) {
@@ -243,33 +243,33 @@ private ExternalPathMovementReader(String traceFilePath,
a.end -= this.minTime;
}
times.add(a);
-
+
line = reader.readLine();
}
}
-
- /**
+
+ /**
* Returns the path for the node with the given ID.
- *
+ *
* @param ID ID of the node
* @return full path for the node.
*/
public List> getPaths(int ID) {
return this.paths.get(ID);
}
-
- /**
+
+ /**
* Returns the active time for the given ID.
- *
+ *
* @param ID ID of the node
* @return active times for the node.
*/
public List getActive(int ID) {
return this.activeTimes.get(ID);
}
-
+
/**
- * Sets normalizing of read values on/off. If on, values returned by
+ * Sets normalizing of read values on/off. If on, values returned by
* {@link #readNextMovements()} are decremented by minimum values of the
* offsets. Default is on (normalize).
* @param normalize If true, normalizing is on (false -> off).
@@ -277,8 +277,8 @@ public List getActive(int ID) {
public void setNormalize(boolean normalize) {
this.normalize = normalize;
}
-
-
+
+
/**
* Returns offset maxTime
* @return the maxTime
@@ -326,13 +326,13 @@ public double getMinX() {
public double getMinY() {
return minY;
}
-
-
- /**
+
+
+ /**
* Get an instance of the reader for the given file path. If the file has
* already been read previously it will not be read again and instead the
* previous instance of the reader will be returned.
- *
+ *
* @param filePath path where the file is read from
* @return instance of the reader that has loaded all the paths from the
* given trace file.
@@ -342,7 +342,7 @@ public static ExternalPathMovementReader getInstance(String traceFilePath,
if (!ExternalPathMovementReader.singletons.containsKey(traceFilePath)) {
try {
ExternalPathMovementReader.singletons.put(traceFilePath,
- new ExternalPathMovementReader(traceFilePath,
+ new ExternalPathMovementReader(traceFilePath,
activeFilePath));
} catch (IOException e) {
System.exit(1);
diff --git a/input/MessageBurstGenerator.java b/input/MessageBurstGenerator.java
index 1dcb0b11e..ae950f429 100644
--- a/input/MessageBurstGenerator.java
+++ b/input/MessageBurstGenerator.java
@@ -1,92 +1,92 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
- */
-package input;
-
-import core.Settings;
-
-/**
- * Message creation -external events generator. Creates bursts of messages where
- * every source node (defined with {@link MessageEventGenerator#HOST_RANGE_S})
- * creates a new message to every destination node (defined with
- * {@link MessageEventGenerator#TO_HOST_RANGE_S})on every interval.
- * The message size, burst times, and inter-burst intervals can be configured
- * like with {@link MessageEventGenerator}.
- * @see MessageEventGenerator
- */
-public class MessageBurstGenerator extends MessageEventGenerator {
- /** next index to use from the "from" range */
- private int nextFromOffset;
- private int nextToOffset;
-
- public MessageBurstGenerator(Settings s) {
- super(s);
- this.nextFromOffset = 0;
- this.nextToOffset = 0;
-
- if (this.toHostRange == null) {
- this.toHostRange = this.hostRange;
- }
- }
-
- /**
- * Returns the next message creation event
- * @see input.EventQueue#nextEvent()
- */
- public ExternalEvent nextEvent() {
- int responseSize = 0; /* no responses requested */
- int msgSize;
- int interval;
- int from;
- int to;
- boolean nextBurst = false;
-
- from = this.hostRange[0] + nextFromOffset;
- to = this.toHostRange[0] + nextToOffset;
-
- if (to == from) { /* skip self */
- to = this.toHostRange[0] + (++nextToOffset);
- }
-
- msgSize = drawMessageSize();
- MessageCreateEvent mce = new MessageCreateEvent(from, to, getID(),
- msgSize, responseSize, this.nextEventsTime);
-
- if (to < this.toHostRange[1] - 1) {
- this.nextToOffset++;
- } else {
- if (from < this.hostRange[1] - 1) {
- this.nextFromOffset++;
- this.nextToOffset = 0;
- } else {
- nextBurst = true;
- }
- }
-
- if (this.hostRange[0] + nextFromOffset ==
- this.toHostRange[0] + nextToOffset) {
- /* to and from would be same for next event */
- nextToOffset++;
- if (nextToOffset >= toHostRange[1]) {
- /* TODO: doesn't work correctly with non-aligned ranges */
- nextBurst = true;
- }
- }
-
- if (nextBurst) {
- interval = drawNextEventTimeDiff();
- this.nextEventsTime += interval;
- this.nextFromOffset = 0;
- this.nextToOffset = 0;
- }
-
- if (this.msgTime != null && this.nextEventsTime > this.msgTime[1]) {
- /* next event would be later than the end time */
- this.nextEventsTime = Double.MAX_VALUE;
- }
-
- return mce;
- }
-
-}
\ No newline at end of file
+ * Released under GPLv3. See LICENSE.txt for details.
+ */
+package input;
+
+import core.Settings;
+
+/**
+ * Message creation -external events generator. Creates bursts of messages where
+ * every source node (defined with {@link MessageEventGenerator#HOST_RANGE_S})
+ * creates a new message to every destination node (defined with
+ * {@link MessageEventGenerator#TO_HOST_RANGE_S})on every interval.
+ * The message size, burst times, and inter-burst intervals can be configured
+ * like with {@link MessageEventGenerator}.
+ * @see MessageEventGenerator
+ */
+public class MessageBurstGenerator extends MessageEventGenerator {
+ /** next index to use from the "from" range */
+ private int nextFromOffset;
+ private int nextToOffset;
+
+ public MessageBurstGenerator(Settings s) {
+ super(s);
+ this.nextFromOffset = 0;
+ this.nextToOffset = 0;
+
+ if (this.toHostRange == null) {
+ this.toHostRange = this.hostRange;
+ }
+ }
+
+ /**
+ * Returns the next message creation event
+ * @see input.EventQueue#nextEvent()
+ */
+ public ExternalEvent nextEvent() {
+ int responseSize = 0; /* no responses requested */
+ int msgSize;
+ int interval;
+ int from;
+ int to;
+ boolean nextBurst = false;
+
+ from = this.hostRange[0] + nextFromOffset;
+ to = this.toHostRange[0] + nextToOffset;
+
+ if (to == from) { /* skip self */
+ to = this.toHostRange[0] + (++nextToOffset);
+ }
+
+ msgSize = drawMessageSize();
+ MessageCreateEvent mce = new MessageCreateEvent(from, to, getID(),
+ msgSize, responseSize, this.nextEventsTime);
+
+ if (to < this.toHostRange[1] - 1) {
+ this.nextToOffset++;
+ } else {
+ if (from < this.hostRange[1] - 1) {
+ this.nextFromOffset++;
+ this.nextToOffset = 0;
+ } else {
+ nextBurst = true;
+ }
+ }
+
+ if (this.hostRange[0] + nextFromOffset ==
+ this.toHostRange[0] + nextToOffset) {
+ /* to and from would be same for next event */
+ nextToOffset++;
+ if (nextToOffset >= toHostRange[1]) {
+ /* TODO: doesn't work correctly with non-aligned ranges */
+ nextBurst = true;
+ }
+ }
+
+ if (nextBurst) {
+ interval = drawNextEventTimeDiff();
+ this.nextEventsTime += interval;
+ this.nextFromOffset = 0;
+ this.nextToOffset = 0;
+ }
+
+ if (this.msgTime != null && this.nextEventsTime > this.msgTime[1]) {
+ /* next event would be later than the end time */
+ this.nextEventsTime = Double.MAX_VALUE;
+ }
+
+ return mce;
+ }
+
+}
diff --git a/input/MessageCreateEvent.java b/input/MessageCreateEvent.java
index 27d8f0236..1f13c9b26 100644
--- a/input/MessageCreateEvent.java
+++ b/input/MessageCreateEvent.java
@@ -1,54 +1,54 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
- */
-package input;
-
-import core.DTNHost;
-import core.Message;
-import core.World;
-
-/**
- * External event for creating a message.
- */
-public class MessageCreateEvent extends MessageEvent {
- private int size;
- private int responseSize;
-
- /**
- * Creates a message creation event with a optional response request
- * @param from The creator of the message
- * @param to Where the message is destined to
- * @param id ID of the message
- * @param size Size of the message
- * @param responseSize Size of the requested response message or 0 if
- * no response is requested
- * @param time Time, when the message is created
- */
- public MessageCreateEvent(int from, int to, String id, int size,
- int responseSize, double time) {
- super(from,to, id, time);
- this.size = size;
- this.responseSize = responseSize;
- }
-
-
- /**
- * Creates the message this event represents.
- */
- @Override
- public void processEvent(World world) {
- DTNHost to = world.getNodeByAddress(this.toAddr);
- DTNHost from = world.getNodeByAddress(this.fromAddr);
-
- Message m = new Message(from, to, this.id, this.size);
- m.setResponseSize(this.responseSize);
- from.createNewMessage(m);
- }
-
- @Override
- public String toString() {
- return super.toString() + " [" + fromAddr + "->" + toAddr + "] " +
- "size:" + size + " CREATE";
- }
-}
+ * Released under GPLv3. See LICENSE.txt for details.
+ */
+package input;
+
+import core.DTNHost;
+import core.Message;
+import core.World;
+
+/**
+ * External event for creating a message.
+ */
+public class MessageCreateEvent extends MessageEvent {
+ private int size;
+ private int responseSize;
+
+ /**
+ * Creates a message creation event with a optional response request
+ * @param from The creator of the message
+ * @param to Where the message is destined to
+ * @param id ID of the message
+ * @param size Size of the message
+ * @param responseSize Size of the requested response message or 0 if
+ * no response is requested
+ * @param time Time, when the message is created
+ */
+ public MessageCreateEvent(int from, int to, String id, int size,
+ int responseSize, double time) {
+ super(from,to, id, time);
+ this.size = size;
+ this.responseSize = responseSize;
+ }
+
+
+ /**
+ * Creates the message this event represents.
+ */
+ @Override
+ public void processEvent(World world) {
+ DTNHost to = world.getNodeByAddress(this.toAddr);
+ DTNHost from = world.getNodeByAddress(this.fromAddr);
+
+ Message m = new Message(from, to, this.id, this.size);
+ m.setResponseSize(this.responseSize);
+ from.createNewMessage(m);
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + " [" + fromAddr + "->" + toAddr + "] " +
+ "size:" + size + " CREATE";
+ }
+}
diff --git a/input/MessageDeleteEvent.java b/input/MessageDeleteEvent.java
index b29671779..991b0bdf5 100644
--- a/input/MessageDeleteEvent.java
+++ b/input/MessageDeleteEvent.java
@@ -1,43 +1,43 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package input;
-
+package input;
+
import java.util.ArrayList;
import java.util.List;
-import core.DTNHost;
+import core.DTNHost;
import core.Message;
-import core.World;
-
-/**
- * External event for deleting a message.
- */
-
-public class MessageDeleteEvent extends MessageEvent {
- /** is the delete caused by a drop (not "normal" removing) */
- private boolean drop;
-
- /**
- * Creates a message delete event
- * @param host Where to delete the message
- * @param id ID of the message
- * @param time Time when the message is deleted
- */
- public MessageDeleteEvent(int host, String id, double time,
- boolean drop) {
- super(host, host, id, time);
- this.drop = drop;
- }
-
- /**
- * Deletes the message
+import core.World;
+
+/**
+ * External event for deleting a message.
+ */
+
+public class MessageDeleteEvent extends MessageEvent {
+ /** is the delete caused by a drop (not "normal" removing) */
+ private boolean drop;
+
+ /**
+ * Creates a message delete event
+ * @param host Where to delete the message
+ * @param id ID of the message
+ * @param time Time when the message is deleted
*/
- @Override
- public void processEvent(World world) {
+ public MessageDeleteEvent(int host, String id, double time,
+ boolean drop) {
+ super(host, host, id, time);
+ this.drop = drop;
+ }
+
+ /**
+ * Deletes the message
+ */
+ @Override
+ public void processEvent(World world) {
DTNHost host = world.getNodeByAddress(this.fromAddr);
-
+
if (id.equals(StandardEventsReader.ALL_MESSAGES_ID)) {
List ids = new ArrayList();
for (Message m : host.getMessageCollection()) {
@@ -46,14 +46,14 @@ public void processEvent(World world) {
for (String nextId : ids) {
host.deleteMessage(nextId, drop);
}
- } else {
+ } else {
host.deleteMessage(id, drop);
- }
- }
-
- @Override
- public String toString() {
- return super.toString() + " [" + fromAddr + "] DELETE";
- }
-
-}
+ }
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + " [" + fromAddr + "] DELETE";
+ }
+
+}
diff --git a/input/MessageEvent.java b/input/MessageEvent.java
index fb267b143..28cb34caf 100644
--- a/input/MessageEvent.java
+++ b/input/MessageEvent.java
@@ -1,36 +1,36 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package input;
-
-/**
- * A message related external event
- */
-public abstract class MessageEvent extends ExternalEvent {
- /** address of the node the message is from */
- protected int fromAddr;
- /** address of the node the message is to */
- protected int toAddr;
- /** identifier of the message */
- protected String id;
-
- /**
- * Creates a message event
- * @param from Where the message comes from
- * @param to Who the message goes to
- * @param id ID of the message
- * @param time Time when the message event occurs
- */
- public MessageEvent(int from, int to, String id, double time) {
- super(time);
- this.fromAddr = from;
- this.toAddr= to;
- this.id = id;
- }
-
- @Override
- public String toString() {
- return "MSG @" + this.time + " " + id;
- }
-}
+package input;
+
+/**
+ * A message related external event
+ */
+public abstract class MessageEvent extends ExternalEvent {
+ /** address of the node the message is from */
+ protected int fromAddr;
+ /** address of the node the message is to */
+ protected int toAddr;
+ /** identifier of the message */
+ protected String id;
+
+ /**
+ * Creates a message event
+ * @param from Where the message comes from
+ * @param to Who the message goes to
+ * @param id ID of the message
+ * @param time Time when the message event occurs
+ */
+ public MessageEvent(int from, int to, String id, double time) {
+ super(time);
+ this.fromAddr = from;
+ this.toAddr= to;
+ this.id = id;
+ }
+
+ @Override
+ public String toString() {
+ return "MSG @" + this.time + " " + id;
+ }
+}
diff --git a/input/MessageEventGenerator.java b/input/MessageEventGenerator.java
index 1c9aa45bd..bf2c87c67 100644
--- a/input/MessageEventGenerator.java
+++ b/input/MessageEventGenerator.java
@@ -1,6 +1,6 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
package input;
@@ -19,21 +19,21 @@ public class MessageEventGenerator implements EventQueue {
* value or a range (min, max) of uniformly distributed random values.
* Defines the message size (bytes). */
public static final String MESSAGE_SIZE_S = "size";
- /** Message creation interval range -setting id ({@value}). Can be either a
- * single value or a range (min, max) of uniformly distributed
+ /** Message creation interval range -setting id ({@value}). Can be either a
+ * single value or a range (min, max) of uniformly distributed
* random values. Defines the inter-message creation interval (seconds). */
public static final String MESSAGE_INTERVAL_S = "interval";
- /** Sender/receiver address range -setting id ({@value}).
+ /** Sender/receiver address range -setting id ({@value}).
* The lower bound is inclusive and upper bound exclusive. */
public static final String HOST_RANGE_S = "hosts";
- /** (Optional) receiver address range -setting id ({@value}).
- * If a value for this setting is defined, the destination hosts are
- * selected from this range and the source hosts from the
- * {@link #HOST_RANGE_S} setting's range.
+ /** (Optional) receiver address range -setting id ({@value}).
+ * If a value for this setting is defined, the destination hosts are
+ * selected from this range and the source hosts from the
+ * {@link #HOST_RANGE_S} setting's range.
* The lower bound is inclusive and upper bound exclusive. */
public static final String TO_HOST_RANGE_S = "tohosts";
- /** Message ID prefix -setting id ({@value}). The value must be unique
+ /** Message ID prefix -setting id ({@value}). The value must be unique
* for all message sources, so if you have more than one message generator,
* use different prefix for all of them. The random number generator's
* seed is derived from the prefix, so by changing the prefix, you'll get
@@ -41,10 +41,10 @@ public class MessageEventGenerator implements EventQueue {
public static final String MESSAGE_ID_PREFIX_S = "prefix";
/** Message creation time range -setting id ({@value}). Defines the time
* range when messages are created. No messages are created before the first
- * and after the second value. By default, messages are created for the
+ * and after the second value. By default, messages are created for the
* whole simulation time. */
public static final String MESSAGE_TIME_S = "time";
-
+
/** Time of the next event (simulated seconds) */
protected double nextEventsTime = 0;
/** Range of host addresses that can be senders or receivers */
@@ -64,10 +64,10 @@ public class MessageEventGenerator implements EventQueue {
/** Random number generator for this Class */
protected Random rng;
-
+
/**
- * Constructor, initializes the interval between events,
- * and the size of messages generated, as well as number
+ * Constructor, initializes the interval between events,
+ * and the size of messages generated, as well as number
* of hosts in the network.
* @param s Settings for this generator.
*/
@@ -76,7 +76,7 @@ public MessageEventGenerator(Settings s){
this.msgInterval = s.getCsvInts(MESSAGE_INTERVAL_S);
this.hostRange = s.getCsvInts(HOST_RANGE_S, 2);
this.idPrefix = s.getSetting(MESSAGE_ID_PREFIX_S);
-
+
if (s.contains(MESSAGE_TIME_S)) {
this.msgTime = s.getCsvDoubles(MESSAGE_TIME_S, 2);
}
@@ -89,10 +89,10 @@ public MessageEventGenerator(Settings s){
else {
this.toHostRange = null;
}
-
+
/* if prefix is unique, so will be the rng's sequence */
this.rng = new Random(idPrefix.hashCode());
-
+
if (this.sizeRange.length == 1) {
/* convert single value to range with 0 length */
this.sizeRange = new int[] {this.sizeRange[0], this.sizeRange[0]};
@@ -101,37 +101,37 @@ public MessageEventGenerator(Settings s){
s.assertValidRange(this.sizeRange, MESSAGE_SIZE_S);
}
if (this.msgInterval.length == 1) {
- this.msgInterval = new int[] {this.msgInterval[0],
+ this.msgInterval = new int[] {this.msgInterval[0],
this.msgInterval[0]};
}
else {
s.assertValidRange(this.msgInterval, MESSAGE_INTERVAL_S);
}
s.assertValidRange(this.hostRange, HOST_RANGE_S);
-
+
if (this.hostRange[1] - this.hostRange[0] < 2) {
if (this.toHostRange == null) {
- throw new SettingsError("Host range must contain at least two "
+ throw new SettingsError("Host range must contain at least two "
+ "nodes unless toHostRange is defined");
}
- else if (toHostRange[0] == this.hostRange[0] &&
+ else if (toHostRange[0] == this.hostRange[0] &&
toHostRange[1] == this.hostRange[1]) {
// XXX: teemuk: Since (X,X) == (X,X+1) in drawHostAddress()
// there's still a boundary condition that can cause an
// infinite loop.
- throw new SettingsError("If to and from host ranges contain" +
+ throw new SettingsError("If to and from host ranges contain" +
" only one host, they can't be the equal");
}
}
-
+
/* calculate the first event's time */
- this.nextEventsTime = (this.msgTime != null ? this.msgTime[0] : 0)
- + msgInterval[0] +
- (msgInterval[0] == msgInterval[1] ? 0 :
+ this.nextEventsTime = (this.msgTime != null ? this.msgTime[0] : 0)
+ + msgInterval[0] +
+ (msgInterval[0] == msgInterval[1] ? 0 :
rng.nextInt(msgInterval[1] - msgInterval[0]));
}
-
-
+
+
/**
* Draws a random host address from the configured address range
* @param hostRange The range of hosts
@@ -143,27 +143,27 @@ protected int drawHostAddress(int hostRange[]) {
}
return hostRange[0] + rng.nextInt(hostRange[1] - hostRange[0]);
}
-
+
/**
* Generates a (random) message size
* @return message size
*/
protected int drawMessageSize() {
- int sizeDiff = sizeRange[0] == sizeRange[1] ? 0 :
+ int sizeDiff = sizeRange[0] == sizeRange[1] ? 0 :
rng.nextInt(sizeRange[1] - sizeRange[0]);
return sizeRange[0] + sizeDiff;
}
-
+
/**
* Generates a (random) time difference between two events
* @return the time difference
*/
protected int drawNextEventTimeDiff() {
- int timeDiff = msgInterval[0] == msgInterval[1] ? 0 :
+ int timeDiff = msgInterval[0] == msgInterval[1] ? 0 :
rng.nextInt(msgInterval[1] - msgInterval[0]);
return msgInterval[0] + timeDiff;
}
-
+
/**
* Draws a destination host address that is different from the "from"
* address
@@ -175,13 +175,13 @@ protected int drawToAddress(int hostRange[], int from) {
int to;
do {
to = this.toHostRange != null ? drawHostAddress(this.toHostRange):
- drawHostAddress(this.hostRange);
+ drawHostAddress(this.hostRange);
} while (from==to);
-
+
return to;
}
-
- /**
+
+ /**
* Returns the next message creation event
* @see input.EventQueue#nextEvent()
*/
@@ -191,24 +191,24 @@ public ExternalEvent nextEvent() {
int interval;
int from;
int to;
-
+
/* Get two *different* nodes randomly from the host ranges */
- from = drawHostAddress(this.hostRange);
+ from = drawHostAddress(this.hostRange);
to = drawToAddress(hostRange, from);
-
+
msgSize = drawMessageSize();
interval = drawNextEventTimeDiff();
-
+
/* Create event and advance to next event */
- MessageCreateEvent mce = new MessageCreateEvent(from, to, this.getID(),
+ MessageCreateEvent mce = new MessageCreateEvent(from, to, this.getID(),
msgSize, responseSize, this.nextEventsTime);
- this.nextEventsTime += interval;
-
+ this.nextEventsTime += interval;
+
if (this.msgTime != null && this.nextEventsTime > this.msgTime[1]) {
/* next event would be later than the end time */
this.nextEventsTime = Double.MAX_VALUE;
}
-
+
return mce;
}
@@ -219,7 +219,7 @@ public ExternalEvent nextEvent() {
public double nextEventsTime() {
return this.nextEventsTime;
}
-
+
/**
* Returns a next free message ID
* @return next globally unique message ID
@@ -227,5 +227,5 @@ public double nextEventsTime() {
protected String getID(){
this.id++;
return idPrefix + this.id;
- }
+ }
}
diff --git a/input/MessageRelayEvent.java b/input/MessageRelayEvent.java
index 4d9d43199..e075a100f 100644
--- a/input/MessageRelayEvent.java
+++ b/input/MessageRelayEvent.java
@@ -1,70 +1,70 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package input;
-
+package input;
+
import core.DTNHost;
import core.World;
-
-/**
- * External event for all the stages of relaying a message between two
- * hosts (start and possible abort or delivery).
- */
-public class MessageRelayEvent extends MessageEvent {
- private int stage;
-
- /** Message relay stage constant for start of sending */
- public static final int SENDING = 1;
- /** Message relay stage constant for ready delivery */
- public static final int TRANSFERRED = 2;
- /** Message relay stage constant for aborted delivery */
- public static final int ABORTED = 3;
- /** Stage constant -> String representation mapping */
- public static final String[] STAGE_STRINGS = {"SENDING",
- "TRANSFERRED", "ABORTED"};
-
- /**
- * Creates a message relaying event
- * @param from Where the message comes from (at this hop)
- * @param to Who the message goes to (at this hop)
- * @param id ID of the message
- * @param time Time when this event happens
- * @param stage The stage of the event (SENDING, TRANSFERRED, or ABORTED)
- */
- public MessageRelayEvent(int from, int to, String id, double time,
- int stage) {
- super(from, to, id, time);
- this.stage = stage;
- }
-
- /**
- * Relays the message
- */
- public void processEvent(World world) {
- // get DTNHosts and pass messages between them
- DTNHost from = world.getNodeByAddress(this.fromAddr);
- DTNHost to = world.getNodeByAddress(this.toAddr);
-
- switch(stage) {
- case SENDING:
- from.sendMessage(id, to);
- break;
- case TRANSFERRED:
- to.messageTransferred(id, from);
- break;
- case ABORTED:
- to.messageAborted(id, from, -1);
- break;
- default:
- assert false : "Invalid stage (" + stage + ") for " + this;
- }
- }
-
- @Override
- public String toString() {
- return super.toString() + " [" + fromAddr + "->" + toAddr + "] " +
- STAGE_STRINGS[stage-1];
- }
-
-}
+
+/**
+ * External event for all the stages of relaying a message between two
+ * hosts (start and possible abort or delivery).
+ */
+public class MessageRelayEvent extends MessageEvent {
+ private int stage;
+
+ /** Message relay stage constant for start of sending */
+ public static final int SENDING = 1;
+ /** Message relay stage constant for ready delivery */
+ public static final int TRANSFERRED = 2;
+ /** Message relay stage constant for aborted delivery */
+ public static final int ABORTED = 3;
+ /** Stage constant -> String representation mapping */
+ public static final String[] STAGE_STRINGS = {"SENDING",
+ "TRANSFERRED", "ABORTED"};
+
+ /**
+ * Creates a message relaying event
+ * @param from Where the message comes from (at this hop)
+ * @param to Who the message goes to (at this hop)
+ * @param id ID of the message
+ * @param time Time when this event happens
+ * @param stage The stage of the event (SENDING, TRANSFERRED, or ABORTED)
+ */
+ public MessageRelayEvent(int from, int to, String id, double time,
+ int stage) {
+ super(from, to, id, time);
+ this.stage = stage;
+ }
+
+ /**
+ * Relays the message
+ */
+ public void processEvent(World world) {
+ // get DTNHosts and pass messages between them
+ DTNHost from = world.getNodeByAddress(this.fromAddr);
+ DTNHost to = world.getNodeByAddress(this.toAddr);
+
+ switch(stage) {
+ case SENDING:
+ from.sendMessage(id, to);
+ break;
+ case TRANSFERRED:
+ to.messageTransferred(id, from);
+ break;
+ case ABORTED:
+ to.messageAborted(id, from, -1);
+ break;
+ default:
+ assert false : "Invalid stage (" + stage + ") for " + this;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + " [" + fromAddr + "->" + toAddr + "] " +
+ STAGE_STRINGS[stage-1];
+ }
+
+}
diff --git a/input/OneFromEachMessageGenerator.java b/input/OneFromEachMessageGenerator.java
index b30399819..793752c2f 100644
--- a/input/OneFromEachMessageGenerator.java
+++ b/input/OneFromEachMessageGenerator.java
@@ -1,75 +1,75 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
- */
-package input;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import core.Settings;
-import core.SettingsError;
-
-/**
- * Message creation -external events generator. Creates one message from
- * every source node (defined with {@link MessageEventGenerator#HOST_RANGE_S})
- * to one of the destination nodes (defined with
- * {@link MessageEventGenerator#TO_HOST_RANGE_S}).
- * The message size, first messages time and the intervals between creating
- * messages can be configured like with {@link MessageEventGenerator}. End
- * time is not respected, but messages are created until every from-node has
- * created a message.
- * @see MessageEventGenerator
- */
-public class OneFromEachMessageGenerator extends MessageEventGenerator {
- private List fromIds;
-
- public OneFromEachMessageGenerator(Settings s) {
- super(s);
- this.fromIds = new ArrayList();
-
- if (toHostRange == null) {
- throw new SettingsError("Destination host (" + TO_HOST_RANGE_S +
- ") must be defined");
- }
- for (int i = hostRange[0]; i < hostRange[1]; i++) {
- fromIds.add(i);
- }
- Collections.shuffle(fromIds, rng);
- }
-
- /**
- * Returns the next message creation event
- * @see input.EventQueue#nextEvent()
- */
- public ExternalEvent nextEvent() {
- int responseSize = 0; /* no responses requested */
- int from;
- int to;
-
- from = this.fromIds.remove(0);
- to = drawToAddress(toHostRange, -1);
-
- if (to == from) { /* skip self */
- if (this.fromIds.size() == 0) { /* oops, no more from addresses */
- this.nextEventsTime = Double.MAX_VALUE;
- return new ExternalEvent(Double.MAX_VALUE);
- } else {
- from = this.fromIds.remove(0);
- }
- }
-
- if (this.fromIds.size() == 0) {
- this.nextEventsTime = Double.MAX_VALUE; /* no messages left */
- } else {
- this.nextEventsTime += drawNextEventTimeDiff();
- }
-
- MessageCreateEvent mce = new MessageCreateEvent(from, to, getID(),
- drawMessageSize(), responseSize, this.nextEventsTime);
-
- return mce;
- }
-
-}
\ No newline at end of file
+ * Released under GPLv3. See LICENSE.txt for details.
+ */
+package input;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import core.Settings;
+import core.SettingsError;
+
+/**
+ * Message creation -external events generator. Creates one message from
+ * every source node (defined with {@link MessageEventGenerator#HOST_RANGE_S})
+ * to one of the destination nodes (defined with
+ * {@link MessageEventGenerator#TO_HOST_RANGE_S}).
+ * The message size, first messages time and the intervals between creating
+ * messages can be configured like with {@link MessageEventGenerator}. End
+ * time is not respected, but messages are created until every from-node has
+ * created a message.
+ * @see MessageEventGenerator
+ */
+public class OneFromEachMessageGenerator extends MessageEventGenerator {
+ private List fromIds;
+
+ public OneFromEachMessageGenerator(Settings s) {
+ super(s);
+ this.fromIds = new ArrayList();
+
+ if (toHostRange == null) {
+ throw new SettingsError("Destination host (" + TO_HOST_RANGE_S +
+ ") must be defined");
+ }
+ for (int i = hostRange[0]; i < hostRange[1]; i++) {
+ fromIds.add(i);
+ }
+ Collections.shuffle(fromIds, rng);
+ }
+
+ /**
+ * Returns the next message creation event
+ * @see input.EventQueue#nextEvent()
+ */
+ public ExternalEvent nextEvent() {
+ int responseSize = 0; /* no responses requested */
+ int from;
+ int to;
+
+ from = this.fromIds.remove(0);
+ to = drawToAddress(toHostRange, -1);
+
+ if (to == from) { /* skip self */
+ if (this.fromIds.size() == 0) { /* oops, no more from addresses */
+ this.nextEventsTime = Double.MAX_VALUE;
+ return new ExternalEvent(Double.MAX_VALUE);
+ } else {
+ from = this.fromIds.remove(0);
+ }
+ }
+
+ if (this.fromIds.size() == 0) {
+ this.nextEventsTime = Double.MAX_VALUE; /* no messages left */
+ } else {
+ this.nextEventsTime += drawNextEventTimeDiff();
+ }
+
+ MessageCreateEvent mce = new MessageCreateEvent(from, to, getID(),
+ drawMessageSize(), responseSize, this.nextEventsTime);
+
+ return mce;
+ }
+
+}
diff --git a/input/OneToEachMessageGenerator.java b/input/OneToEachMessageGenerator.java
index 157fa27e5..d0294495b 100644
--- a/input/OneToEachMessageGenerator.java
+++ b/input/OneToEachMessageGenerator.java
@@ -1,75 +1,75 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
- */
-package input;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import core.Settings;
-import core.SettingsError;
-
-/**
- * Message creation -external events generator. Creates one message from
- * source node/nodes (defined with {@link MessageEventGenerator#HOST_RANGE_S})
- * to all destination nodes (defined with
- * {@link MessageEventGenerator#TO_HOST_RANGE_S}).
- * The message size, first messages time and the intervals between creating
- * messages can be configured like with {@link MessageEventGenerator}. End
- * time is not respected, but messages are created until there's a message for
- * every destination node.
- * @see MessageEventGenerator
- */
-public class OneToEachMessageGenerator extends MessageEventGenerator {
- private List toIds;
-
- public OneToEachMessageGenerator(Settings s) {
- super(s);
- this.toIds = new ArrayList();
-
- if (toHostRange == null) {
- throw new SettingsError("Destination host (" + TO_HOST_RANGE_S +
- ") must be defined");
- }
- for (int i = toHostRange[0]; i < toHostRange[1]; i++) {
- toIds.add(i);
- }
- Collections.shuffle(toIds, rng);
- }
-
- /**
- * Returns the next message creation event
- * @see input.EventQueue#nextEvent()
- */
- public ExternalEvent nextEvent() {
- int responseSize = 0; /* no responses requested */
- int from;
- int to;
-
- from = drawHostAddress(hostRange);
- to = this.toIds.remove(0);
-
- if (to == from) { /* skip self */
- if (this.toIds.size() == 0) { /* oops, no more from addresses */
- this.nextEventsTime = Double.MAX_VALUE;
- return new ExternalEvent(Double.MAX_VALUE);
- } else {
- to = this.toIds.remove(0);
- }
- }
-
- if (this.toIds.size() == 0) {
- this.nextEventsTime = Double.MAX_VALUE; /* no messages left */
- } else {
- this.nextEventsTime += drawNextEventTimeDiff();
- }
-
- MessageCreateEvent mce = new MessageCreateEvent(from, to, getID(),
- drawMessageSize(), responseSize, this.nextEventsTime);
-
- return mce;
- }
-
-}
\ No newline at end of file
+ * Released under GPLv3. See LICENSE.txt for details.
+ */
+package input;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import core.Settings;
+import core.SettingsError;
+
+/**
+ * Message creation -external events generator. Creates one message from
+ * source node/nodes (defined with {@link MessageEventGenerator#HOST_RANGE_S})
+ * to all destination nodes (defined with
+ * {@link MessageEventGenerator#TO_HOST_RANGE_S}).
+ * The message size, first messages time and the intervals between creating
+ * messages can be configured like with {@link MessageEventGenerator}. End
+ * time is not respected, but messages are created until there's a message for
+ * every destination node.
+ * @see MessageEventGenerator
+ */
+public class OneToEachMessageGenerator extends MessageEventGenerator {
+ private List toIds;
+
+ public OneToEachMessageGenerator(Settings s) {
+ super(s);
+ this.toIds = new ArrayList();
+
+ if (toHostRange == null) {
+ throw new SettingsError("Destination host (" + TO_HOST_RANGE_S +
+ ") must be defined");
+ }
+ for (int i = toHostRange[0]; i < toHostRange[1]; i++) {
+ toIds.add(i);
+ }
+ Collections.shuffle(toIds, rng);
+ }
+
+ /**
+ * Returns the next message creation event
+ * @see input.EventQueue#nextEvent()
+ */
+ public ExternalEvent nextEvent() {
+ int responseSize = 0; /* no responses requested */
+ int from;
+ int to;
+
+ from = drawHostAddress(hostRange);
+ to = this.toIds.remove(0);
+
+ if (to == from) { /* skip self */
+ if (this.toIds.size() == 0) { /* oops, no more from addresses */
+ this.nextEventsTime = Double.MAX_VALUE;
+ return new ExternalEvent(Double.MAX_VALUE);
+ } else {
+ to = this.toIds.remove(0);
+ }
+ }
+
+ if (this.toIds.size() == 0) {
+ this.nextEventsTime = Double.MAX_VALUE; /* no messages left */
+ } else {
+ this.nextEventsTime += drawNextEventTimeDiff();
+ }
+
+ MessageCreateEvent mce = new MessageCreateEvent(from, to, getID(),
+ drawMessageSize(), responseSize, this.nextEventsTime);
+
+ return mce;
+ }
+
+}
diff --git a/input/ScheduledUpdatesQueue.java b/input/ScheduledUpdatesQueue.java
index b4b98f7a4..fa0259e82 100644
--- a/input/ScheduledUpdatesQueue.java
+++ b/input/ScheduledUpdatesQueue.java
@@ -1,6 +1,6 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
package input;
@@ -9,14 +9,14 @@
/**
* Event queue where simulation objects can request an update to happen
- * at the specified simulation time. Multiple updates at the same time
+ * at the specified simulation time. Multiple updates at the same time
* are merged to a single update.
*/
public class ScheduledUpdatesQueue implements EventQueue {
/** Time of the event (simulated seconds) */
private ExternalEvent nextEvent;
private List updates;
-
+
/**
* Constructor. Creates an empty update queue.
*/
@@ -24,25 +24,25 @@ public ScheduledUpdatesQueue(){
this.nextEvent = new ExternalEvent(Double.MAX_VALUE);
this.updates = new ArrayList();
}
-
+
/**
* Returns the next scheduled event or event with time Double.MAX_VALUE
- * if there aren't any.
+ * if there aren't any.
* @return the next scheduled event
*/
public ExternalEvent nextEvent() {
ExternalEvent event = this.nextEvent;
-
+
if (this.updates.size() == 0) {
this.nextEvent = new ExternalEvent(Double.MAX_VALUE);
}
else {
this.nextEvent = this.updates.remove(0);
}
-
+
return event;
}
-
+
/**
* Returns the next scheduled event's time or Double.MAX_VALUE if there
* aren't any events left
@@ -70,14 +70,14 @@ else if (this.nextEvent.getTime() > simTime) { // new nextEvent
putToQueue(ee);
}
}
-
+
/**
* Puts a event to the queue in the right place
* @param ee The event to put to the queue
*/
private void putToQueue(ExternalEvent ee) {
double eeTime = ee.getTime();
-
+
for (int i=0, n=this.updates.size(); i add to the end of the list */
- this.updates.add(ee);
+ this.updates.add(ee);
}
-
+
public String toString() {
String times = "updates @ " + this.nextEvent.getTime();
-
+
for (ExternalEvent ee : this.updates) {
times += ", " + ee.getTime();
}
-
+
return times;
}
}
diff --git a/input/StandardEventsReader.java b/input/StandardEventsReader.java
index 7e09f661c..99b462c70 100644
--- a/input/StandardEventsReader.java
+++ b/input/StandardEventsReader.java
@@ -1,9 +1,9 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package input;
-
+package input;
+
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
@@ -15,45 +15,45 @@
import java.util.regex.Pattern;
import core.SimError;
-
-/**
- *
- * External events reader for standard-format events
- * (created e.g by the dtnsim2parser).
- *
- *
- * Syntax:
- *
- * <time> <actionId> <msgId> <hostId>
- * [<host2Id> [<size>] [<respSize>]]
- *
- *
- * All actions (except CONNECTION) must have first four fields. SEND, DELIVERED
- * and ABORT actions need host2Id field too (the host who the message is/was
- * being transferred to). CREATE action needs the additional size
- * (of the message) field and can have also size-of-the-response field if
+
+/**
+ *
+ * External events reader for standard-format events
+ * (created e.g by the dtnsim2parser).
+ *
+ *
+ * Syntax:
+ *
+ * <time> <actionId> <msgId> <hostId>
+ * [<host2Id> [<size>] [<respSize>]]
+ *
+ *
+ * All actions (except CONNECTION) must have first four fields. SEND, DELIVERED
+ * and ABORT actions need host2Id field too (the host who the message is/was
+ * being transferred to). CREATE action needs the additional size
+ * (of the message) field and can have also size-of-the-response field if
* a response to this message is requested.
- * CONNNECTION action is followed by the two hosts which connect (or
+ *
CONNNECTION action is followed by the two hosts which connect (or
* disconnect) to each other and then either "up" or "down" depending on whether
- * the connection was created or destroyed.
+ * the connection was created or destroyed.
*
* Message DROP and REMOVE events can use {@value #ALL_MESSAGES_ID} as the
- * message ID for referring to all messages the node has in message buffer
+ * message ID for referring to all messages the node has in message buffer
* (i.e., to delete all messages).
- *
- */
-public class StandardEventsReader implements ExternalEventsReader {
- /** Identifier of message creation event ({@value}) */
- public static final String CREATE = "C";
- /** Identifier of message transfer start event ({@value}) */
- public static final String SEND = "S";
- /** Identifier of message delivered event ({@value}) */
- public static final String DELIVERED = "DE";
- /** Identifier of message transfer aborted event ({@value}) */
- public static final String ABORT = "A";
- /** Identifier of message dropped event ({@value}) */
- public static final String DROP = "DR";
- /** Identifier of message removed event ({@value}) */
+ *
+ */
+public class StandardEventsReader implements ExternalEventsReader {
+ /** Identifier of message creation event ({@value}) */
+ public static final String CREATE = "C";
+ /** Identifier of message transfer start event ({@value}) */
+ public static final String SEND = "S";
+ /** Identifier of message delivered event ({@value}) */
+ public static final String DELIVERED = "DE";
+ /** Identifier of message transfer aborted event ({@value}) */
+ public static final String ABORT = "A";
+ /** Identifier of message dropped event ({@value}) */
+ public static final String DROP = "DR";
+ /** Identifier of message removed event ({@value}) */
public static final String REMOVE = "R";
/** Identifier of connection event ({@value}) */
public static final String CONNECTION = "CONN";
@@ -61,68 +61,68 @@ public class StandardEventsReader implements ExternalEventsReader {
public static final String CONNECTION_DOWN = "down";
/** Value identifier of connection up event ({@value}) */
public static final String CONNECTION_UP = "up";
- /** Message identifier to use to refer to all messages ({@value}) */
- public static final String ALL_MESSAGES_ID = "*";
-
+ /** Message identifier to use to refer to all messages ({@value}) */
+ public static final String ALL_MESSAGES_ID = "*";
+
//private Scanner scanner;
- private BufferedReader reader;
-
- public StandardEventsReader(File eventsFile){
- try {
+ private BufferedReader reader;
+
+ public StandardEventsReader(File eventsFile){
+ try {
//this.scanner = new Scanner(eventsFile);
- this.reader = new BufferedReader(new FileReader(eventsFile));
- } catch (FileNotFoundException e) {
- throw new SimError(e.getMessage(),e);
- }
- }
-
-
- public List readEvents(int nrof) {
- ArrayList events = new ArrayList(nrof);
- int eventsRead = 0;
- // skip empty and comment lines
- Pattern skipPattern = Pattern.compile("(#.*)|(^\\s*$)");
-
+ this.reader = new BufferedReader(new FileReader(eventsFile));
+ } catch (FileNotFoundException e) {
+ throw new SimError(e.getMessage(),e);
+ }
+ }
+
+
+ public List readEvents(int nrof) {
+ ArrayList events = new ArrayList(nrof);
+ int eventsRead = 0;
+ // skip empty and comment lines
+ Pattern skipPattern = Pattern.compile("(#.*)|(^\\s*$)");
+
String line;
try {
line = this.reader.readLine();
} catch (IOException e1) {
throw new SimError("Reading from external event file failed.");
- }
- while (eventsRead < nrof && line != null) {
- Scanner lineScan = new Scanner(line);
- if (skipPattern.matcher(line).matches()) {
+ }
+ while (eventsRead < nrof && line != null) {
+ Scanner lineScan = new Scanner(line);
+ if (skipPattern.matcher(line).matches()) {
// skip empty and comment lines
try {
line = this.reader.readLine();
} catch (IOException e) {
throw new SimError("Reading from external event file " +
"failed.");
- }
- continue;
- }
-
- double time;
- String action;
- String msgId;
- int hostAddr;
+ }
+ continue;
+ }
+
+ double time;
+ String action;
+ String msgId;
+ int hostAddr;
int host2Addr;
-
- try {
- time = lineScan.nextDouble();
- action = lineScan.next();
-
- if (action.equals(DROP)) {
+
+ try {
+ time = lineScan.nextDouble();
+ action = lineScan.next();
+
+ if (action.equals(DROP)) {
msgId = lineScan.next();
hostAddr = getHostAddress(lineScan.next());
- events.add(new MessageDeleteEvent(hostAddr, msgId,
- time, true));
- }
+ events.add(new MessageDeleteEvent(hostAddr, msgId,
+ time, true));
+ }
else if (action.equals(REMOVE)) {
msgId = lineScan.next();
- hostAddr = getHostAddress(lineScan.next());
- events.add(new MessageDeleteEvent(hostAddr, msgId,
- time, false));
+ hostAddr = getHostAddress(lineScan.next());
+ events.add(new MessageDeleteEvent(hostAddr, msgId,
+ time, false));
}
else if (action.equals(CONNECTION)) {
String connEventType;
@@ -130,12 +130,12 @@ else if (action.equals(CONNECTION)) {
hostAddr = getHostAddress(lineScan.next());
host2Addr = getHostAddress(lineScan.next());
connEventType = lineScan.next();
-
+
String interfaceId = null;
if (lineScan.hasNext()) {
interfaceId = lineScan.next();
- }
-
+ }
+
if (connEventType.equalsIgnoreCase(CONNECTION_UP)) {
isUp = true;
}
@@ -143,93 +143,93 @@ else if (connEventType.equalsIgnoreCase(CONNECTION_DOWN)) {
isUp = false;
}
else {
- throw new SimError("Unknown up/down value '" +
+ throw new SimError("Unknown up/down value '" +
connEventType + "'");
}
-
- ConnectionEvent ce = new ConnectionEvent(hostAddr,
+
+ ConnectionEvent ce = new ConnectionEvent(hostAddr,
host2Addr, interfaceId, isUp, time);
-
+
events.add(ce);
- }
+ }
else {
msgId = lineScan.next();
- hostAddr = getHostAddress(lineScan.next());
-
- host2Addr = getHostAddress(lineScan.next());
-
- if (action.equals(CREATE)){
- int size = lineScan.nextInt();
- int respSize = 0;
- if (lineScan.hasNextInt()) {
- respSize = lineScan.nextInt();
- }
- events.add(new MessageCreateEvent(hostAddr, host2Addr,
- msgId, size, respSize, time));
- }
- else {
- int stage = -1;
- if (action.equals(SEND)) {
- stage = MessageRelayEvent.SENDING;
- }
- else if (action.equals(DELIVERED)) {
- stage = MessageRelayEvent.TRANSFERRED;
- }
- else if (action.equals(ABORT)) {
- stage = MessageRelayEvent.ABORTED;
- }
- else {
- throw new SimError("Unknown action '" + action +
- "' in external events");
- }
- events.add(new MessageRelayEvent(hostAddr, host2Addr,
- msgId, time, stage));
- }
- }
- // discard the newline in the end
- if (lineScan.hasNextLine()) {
- lineScan.nextLine(); // TODO: test
+ hostAddr = getHostAddress(lineScan.next());
+
+ host2Addr = getHostAddress(lineScan.next());
+
+ if (action.equals(CREATE)){
+ int size = lineScan.nextInt();
+ int respSize = 0;
+ if (lineScan.hasNextInt()) {
+ respSize = lineScan.nextInt();
+ }
+ events.add(new MessageCreateEvent(hostAddr, host2Addr,
+ msgId, size, respSize, time));
+ }
+ else {
+ int stage = -1;
+ if (action.equals(SEND)) {
+ stage = MessageRelayEvent.SENDING;
+ }
+ else if (action.equals(DELIVERED)) {
+ stage = MessageRelayEvent.TRANSFERRED;
+ }
+ else if (action.equals(ABORT)) {
+ stage = MessageRelayEvent.ABORTED;
+ }
+ else {
+ throw new SimError("Unknown action '" + action +
+ "' in external events");
+ }
+ events.add(new MessageRelayEvent(hostAddr, host2Addr,
+ msgId, time, stage));
+ }
+ }
+ // discard the newline in the end
+ if (lineScan.hasNextLine()) {
+ lineScan.nextLine(); // TODO: test
}
eventsRead++;
- if (eventsRead < nrof) {
+ if (eventsRead < nrof) {
line = this.reader.readLine();
- }
- } catch (Exception e) {
- throw new SimError("Can't parse external event " +
- (eventsRead+1) + " from '" + line + "'", e);
- }
- }
-
- return events;
- }
-
- /**
- * Parses a host address from a hostId string (the numeric part after
- * optional non-numeric part).
- * @param hostId The id to parse the address from
- * @return The address
- * @throws SimError if no address could be parsed from the id
- */
- private int getHostAddress(String hostId) {
- String addressPart = "";
- if (hostId.matches("^\\d+$")) {
- addressPart = hostId; // host id is only the address
- }
- else if (hostId.matches("^\\D+\\d+$")) {
- String [] parts = hostId.split("\\D");
- addressPart = parts[parts.length-1]; // last occurence is the addr
- }
- else {
- throw new SimError("Invalid host ID '" + hostId + "'");
- }
-
- return Integer.parseInt(addressPart);
- }
-
- public void close() {
+ }
+ } catch (Exception e) {
+ throw new SimError("Can't parse external event " +
+ (eventsRead+1) + " from '" + line + "'", e);
+ }
+ }
+
+ return events;
+ }
+
+ /**
+ * Parses a host address from a hostId string (the numeric part after
+ * optional non-numeric part).
+ * @param hostId The id to parse the address from
+ * @return The address
+ * @throws SimError if no address could be parsed from the id
+ */
+ private int getHostAddress(String hostId) {
+ String addressPart = "";
+ if (hostId.matches("^\\d+$")) {
+ addressPart = hostId; // host id is only the address
+ }
+ else if (hostId.matches("^\\D+\\d+$")) {
+ String [] parts = hostId.split("\\D");
+ addressPart = parts[parts.length-1]; // last occurence is the addr
+ }
+ else {
+ throw new SimError("Invalid host ID '" + hostId + "'");
+ }
+
+ return Integer.parseInt(addressPart);
+ }
+
+ public void close() {
try {
this.reader.close();
- } catch (IOException e) {}
- }
-
-}
+ } catch (IOException e) {}
+ }
+
+}
diff --git a/input/WKTMapReader.java b/input/WKTMapReader.java
index 24ac27ec6..b5790dad9 100644
--- a/input/WKTMapReader.java
+++ b/input/WKTMapReader.java
@@ -1,9 +1,9 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package input;
-
+package input;
+
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
@@ -16,144 +16,144 @@
import movement.map.MapNode;
import movement.map.SimMap;
import core.Coord;
-
-/**
- * "Well-known text syntax" map data reader.
- * Note: Understands only LINESTRING
s and
- * MULTILINESTRING
s. Skips all POINT
data.
- * Other data causes IOException.
- */
-public class WKTMapReader extends WKTReader {
- private Hashtable nodes;
- /** are all paths bidirectional */
- private boolean bidirectionalPaths = true;
- private int nodeType = -1;
-
- /**
- * Constructor. Creates a new WKT reader ready for addPaths() calls.
- * @param bidi If true, all read paths are set bidirectional (i.e. if node A
- * is a neighbor of node B, node B is also a neighbor of node A).
- */
- public WKTMapReader(boolean bidi) {
- this.bidirectionalPaths = bidi;
- this.nodes = new Hashtable();
- }
-
- /**
- * Sets bidirectional paths on/off.
- * @param bidi If true, all paths are set bidirectional (false -> not)
- */
- public void setBidirectional(boolean bidi) {
- this.bidirectionalPaths = bidi;
- }
-
- /**
- * Returns the map nodes that were read in a collection
- * @return the map nodes that were read in a collection
- */
- public Collection getNodes() {
- return this.nodes.values();
- }
-
- /**
- * Returns the original Map object that was used to read the map
- * @return the original Map object that was used to read the map
- */
- public Map getNodesHash() {
- return this.nodes;
- }
-
- /**
- * Returns new a SimMap that is based on the read map
- * @return new a SimMap that is based on the read map
- */
- public SimMap getMap() {
- return new SimMap(this.nodes);
- }
-
- /**
- * Adds paths to the map and adds given type to all nodes' type.
- * @param file The file where the WKT data is read from
- * @param type The type to use (integer value, see class {@link MapNode}))
- * @throws IOException If something went wrong while reading the file
- */
- public void addPaths(File file, int type) throws IOException {
- addPaths(new FileReader(file), type);
- }
-
-
- /**
- * Add paths to current path set. Adding paths multiple times
- * has the same result as concatenating the data before adding it.
- * @param input Reader where the WKT data is read from
- * @param nodeType The type to use (integer value, see class
- * {@link MapNode}))
- * @throws IOException if something went wrong with reading from the input
- */
- public void addPaths(Reader input, int nodeType) throws IOException {
- this.nodeType = nodeType;
- String type;
- String contents;
-
- init(input);
-
- while((type = nextType()) != null) {
- if (type.equals(LINESTRING)) {
- contents = readNestedContents();
- updateMap(parseLineString(contents));
- }
- else if (type.equals(MULTILINESTRING)) {
- for (List list : parseMultilinestring()) {
- updateMap(list);
- }
- }
- else {
- // known type but not interesting -> skip
- readNestedContents();
- }
- }
- }
-
- /**
- * Updates simulation map with coordinates in the list
- * @param coords The list of coordinates
- */
- private void updateMap(List coords) {
- MapNode previousNode = null;
- for (Coord c : coords) {
- previousNode = createOrUpdateNode(c, previousNode);
- }
- }
-
- /**
- * Creates or updates a node that is in location c and next to
- * node previous
- * @param c The location coordinates of the node
- * @param previous Previous node whose neighbor node at c is
- * @return The created/updated node
- */
- private MapNode createOrUpdateNode(Coord c, MapNode previous) {
- MapNode n = null;
-
- n = nodes.get(c); // try to get the node at that location
-
- if (n == null) { // no node in that location -> create new
- n = new MapNode(c);
- nodes.put(c, n);
- }
-
- if (previous != null) {
- n.addNeighbor(previous);
- if (bidirectionalPaths) {
- previous.addNeighbor(n);
- }
- }
-
- if (nodeType != -1) {
- n.addType(nodeType);
- }
-
- return n;
- }
-
-}
+
+/**
+ * "Well-known text syntax" map data reader.
+ * Note: Understands only LINESTRING
s and
+ * MULTILINESTRING
s. Skips all POINT
data.
+ * Other data causes IOException.
+ */
+public class WKTMapReader extends WKTReader {
+ private Hashtable nodes;
+ /** are all paths bidirectional */
+ private boolean bidirectionalPaths = true;
+ private int nodeType = -1;
+
+ /**
+ * Constructor. Creates a new WKT reader ready for addPaths() calls.
+ * @param bidi If true, all read paths are set bidirectional (i.e. if node A
+ * is a neighbor of node B, node B is also a neighbor of node A).
+ */
+ public WKTMapReader(boolean bidi) {
+ this.bidirectionalPaths = bidi;
+ this.nodes = new Hashtable();
+ }
+
+ /**
+ * Sets bidirectional paths on/off.
+ * @param bidi If true, all paths are set bidirectional (false -> not)
+ */
+ public void setBidirectional(boolean bidi) {
+ this.bidirectionalPaths = bidi;
+ }
+
+ /**
+ * Returns the map nodes that were read in a collection
+ * @return the map nodes that were read in a collection
+ */
+ public Collection getNodes() {
+ return this.nodes.values();
+ }
+
+ /**
+ * Returns the original Map object that was used to read the map
+ * @return the original Map object that was used to read the map
+ */
+ public Map getNodesHash() {
+ return this.nodes;
+ }
+
+ /**
+ * Returns new a SimMap that is based on the read map
+ * @return new a SimMap that is based on the read map
+ */
+ public SimMap getMap() {
+ return new SimMap(this.nodes);
+ }
+
+ /**
+ * Adds paths to the map and adds given type to all nodes' type.
+ * @param file The file where the WKT data is read from
+ * @param type The type to use (integer value, see class {@link MapNode}))
+ * @throws IOException If something went wrong while reading the file
+ */
+ public void addPaths(File file, int type) throws IOException {
+ addPaths(new FileReader(file), type);
+ }
+
+
+ /**
+ * Add paths to current path set. Adding paths multiple times
+ * has the same result as concatenating the data before adding it.
+ * @param input Reader where the WKT data is read from
+ * @param nodeType The type to use (integer value, see class
+ * {@link MapNode}))
+ * @throws IOException if something went wrong with reading from the input
+ */
+ public void addPaths(Reader input, int nodeType) throws IOException {
+ this.nodeType = nodeType;
+ String type;
+ String contents;
+
+ init(input);
+
+ while((type = nextType()) != null) {
+ if (type.equals(LINESTRING)) {
+ contents = readNestedContents();
+ updateMap(parseLineString(contents));
+ }
+ else if (type.equals(MULTILINESTRING)) {
+ for (List list : parseMultilinestring()) {
+ updateMap(list);
+ }
+ }
+ else {
+ // known type but not interesting -> skip
+ readNestedContents();
+ }
+ }
+ }
+
+ /**
+ * Updates simulation map with coordinates in the list
+ * @param coords The list of coordinates
+ */
+ private void updateMap(List coords) {
+ MapNode previousNode = null;
+ for (Coord c : coords) {
+ previousNode = createOrUpdateNode(c, previousNode);
+ }
+ }
+
+ /**
+ * Creates or updates a node that is in location c and next to
+ * node previous
+ * @param c The location coordinates of the node
+ * @param previous Previous node whose neighbor node at c is
+ * @return The created/updated node
+ */
+ private MapNode createOrUpdateNode(Coord c, MapNode previous) {
+ MapNode n = null;
+
+ n = nodes.get(c); // try to get the node at that location
+
+ if (n == null) { // no node in that location -> create new
+ n = new MapNode(c);
+ nodes.put(c, n);
+ }
+
+ if (previous != null) {
+ n.addNeighbor(previous);
+ if (bidirectionalPaths) {
+ previous.addNeighbor(n);
+ }
+ }
+
+ if (nodeType != -1) {
+ n.addType(nodeType);
+ }
+
+ return n;
+ }
+
+}
diff --git a/input/WKTReader.java b/input/WKTReader.java
index 2c8c83caf..d772d985a 100644
--- a/input/WKTReader.java
+++ b/input/WKTReader.java
@@ -1,9 +1,9 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
+ * Released under GPLv3. See LICENSE.txt for details.
*/
-package input;
-
+package input;
+
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
@@ -15,313 +15,313 @@
import java.util.Scanner;
import core.Coord;
-
-/**
- * Class for reading "Well-known text syntax" files. See e.g.
- * Wikipedia for
- * WKT syntax details. For example, Open JUMP
- * GIS program can save compatible data from many other formats.
- */
-public class WKTReader {
- /** known WKT type LINESTRING */
- public static final String LINESTRING = "LINESTRING";
- /** known WKT type MULTILINESTRING */
- public static final String MULTILINESTRING = "MULTILINESTRING";
- /** known WKT type POINT */
- public static final String POINT = "POINT";
-
- /** are all lines of the file read */
- private boolean done;
- /** reader for the data */
- private BufferedReader reader;
-
- /**
- * Read point data from a file
- * @param file The file to read points from
- * @return A list of coordinates read from the file
- * @throws IOException if something went wrong while reading
- */
- public List readPoints(File file) throws IOException {
- return readPoints(new FileReader(file));
- }
-
- /**
- * Read point data from a Reader
- * @param r The Reader to read points from
- * @return A list of coordinates that were read
- * @throws IOException if something went wrong while reading
- */
- public List readPoints(Reader r) throws IOException {
- List points = new ArrayList();
-
- String type;
- init(r);
-
- while((type = nextType()) != null) {
- if (type.equals(POINT)) {
- points.add(parsePoint());
- }
- else {
- // known type but not interesting -> skip
- readNestedContents();
- }
- }
-
- return points;
- }
-
- /**
- * Read line (LINESTRING) data from a file
- * @param file The file to read data from
- * @return A list of coordinate lists read from the file
- * @throws IOException if something went wrong while reading
- */
- public List> readLines(File file) throws IOException {
- List> lines = new ArrayList>();
-
- String type;
- init(new FileReader(file));
-
- while((type = nextType()) != null) {
- if (type.equals(LINESTRING)) {
- lines.add(parseLineString(readNestedContents()));
- }
- else {
- // known type but not interesting -> skip
- readNestedContents();
- }
- }
-
- return lines;
- }
-
-
- /**
- * Initialize the reader to use a certain input reader
- * @param input The input to use
- */
- protected void init(Reader input) {
- setDone(false);
- reader = new BufferedReader(input);
- }
-
- /**
- * Returns the next type read from the reader given at init or null
- * if no more types can be read
- * @return the next type read from the reader given at init
- * @throws IOException
- */
- protected String nextType() throws IOException {
- String type = null;
-
- while (!done && type == null) {
- type = readWord(reader);
-
- if (type.length() < 1) { // discard empty lines
- type = null;
- continue;
- }
- }
-
- return type;
- }
-
- /**
- * Returns true if type is one of the known WKT types
- * @param type The type to check
- * @return true if type is one of the known WKT types
- */
- protected boolean isKnownType(String type) {
- if (type.equals(LINESTRING)) {
- return true;
- }
- else if (type.equals(MULTILINESTRING)) {
- return true;
- }
- else if (type.equals(POINT)) {
- return true;
- }
- else {
- return false;
- }
- }
-
- /**
- * Reads a "word", ie whitespace delimited string of characters, from
- * the reader
- * @param r Reader to read the characters from
- * @return The word that was read (or empty string if nothing was read)
- * @throws IOException
- */
- protected String readWord(Reader r) throws IOException {
- StringBuffer buf = new StringBuffer();
- char c = skipAllWhitespace(r);
-
- // read non-whitespace part
- while(c != (char)-1 && !Character.isWhitespace(c)) {
- buf.append(c);
- c = (char)r.read();
- }
-
- if (c == (char)-1) {
- setDone(true);
- }
- return buf.toString();
- }
-
- /**
- * Parses a MULTILINESTRING statement that has nested linestrings from
- * the current reader
- * @return List of parsed Coord lists
- * @throws IOException
- */
- protected List> parseMultilinestring()
- throws IOException {
- List> list = new ArrayList>();
- String multiContents = readNestedContents(reader);
- StringReader r2 = new StringReader(multiContents);
- String lineString = readNestedContents(r2);
-
- while (lineString.length() > 0) {
- list.add(parseLineString(lineString));
- lineString = readNestedContents(r2);
- }
-
- return list;
- }
-
- /**
- * Parses a WKT point data from the intialized reader
- * @return Point data as a Coordinate
- * @throws IOException if couldn't parse coordinate values
- */
- protected Coord parsePoint() throws IOException {
- String coords = readNestedContents(reader);
- Scanner s = new Scanner(coords);
- double x,y;
-
- try {
- x = s.nextDouble();
- y = s.nextDouble();
- } catch (RuntimeException e) {
- throw new IOException("Bad coordinate values: '" + coords + "'");
- }
-
- return new Coord(x,y);
- }
-
- /**
- * Reads and skips all characters until character "until" is read or
- * end of stream is reached. Also the expected character is discarded.
- * @param r Reader to read characters from
- * @param until What character to expect
- * @throws IOException
- */
- protected void skipUntil(Reader r, char until) throws IOException {
- char c;
- do {
- c = (char)r.read();
- } while (c != until && c != (char)-1);
- }
-
- /**
- * Skips all consecutive whitespace characters from reader
- * @param r Reader where the whitespace is skipped
- * @return First non-whitespace character read from the reader
- * @throws IOException
- */
- protected char skipAllWhitespace(Reader r) throws IOException {
- char c;
- do {
- c = (char)r.read();
- } while (Character.isWhitespace(c) && c != (char)-1);
-
- return c;
- }
-
- /**
- * Reads everything from the first opening parenthesis until line that
- * ends to a closing parenthesis and returns the contents in one string
- * @param r Reader to read the input from
- * @return The text between the parentheses
- */
- public String readNestedContents(Reader r) throws IOException {
- StringBuffer contents = new StringBuffer();
- int parOpen; // nrof open parentheses
- char c = '\0';
-
- skipUntil(r,'(');
- parOpen = 1;
-
- while (c != (char)-1 && parOpen > 0) {
- c = (char)r.read();
- if (c == '(') {
- parOpen++;
- }
- if (c == ')') {
- parOpen--;
- }
- if (Character.isWhitespace(c)) {
- c = ' '; // convert all whitespace to basic space
- }
- contents.append(c);
- }
-
- contents.deleteCharAt(contents.length()-1); // remove last ')'
- return contents.toString();
- }
-
- /**
- * Returns nested contents from the reader given at init
- * @return nested contents from the reader given at init
- * @throws IOException
- * @see #readNestedContents(Reader)
- */
- public String readNestedContents() throws IOException {
- return readNestedContents(reader);
- }
-
- /**
- * Parses coordinate tuples from "LINESTRING" lines
- * @param line String that contains the whole "LINESTRING"'s content
- * @return List of coordinates parsed from the linestring
- */
- protected List parseLineString(String line) {
- List coords = new ArrayList();
- Scanner lineScan;
- Scanner tupleScan;
- double x,y;
- Coord c;
-
- lineScan = new Scanner(line);
- lineScan.useDelimiter(",");
-
- while (lineScan.hasNext()) {
- tupleScan = new Scanner(lineScan.next());
- x = Double.parseDouble(tupleScan.next());
- y = Double.parseDouble(tupleScan.next());
- c = new Coord(x,y);
-
- coords.add(c);
- }
-
- return coords;
- }
-
- /**
- * Returns true if the whole file has been read
- * @return true if the whole file has been read
- */
- protected boolean isDone() {
- return this.done;
- }
-
- /**
- * Sets the "is file read" state
- * @param done If true, reading is done
- */
- protected void setDone(boolean done) {
- this.done = done;
- }
-
-}
+
+/**
+ * Class for reading "Well-known text syntax" files. See e.g.
+ * Wikipedia for
+ * WKT syntax details. For example, Open JUMP
+ * GIS program can save compatible data from many other formats.
+ */
+public class WKTReader {
+ /** known WKT type LINESTRING */
+ public static final String LINESTRING = "LINESTRING";
+ /** known WKT type MULTILINESTRING */
+ public static final String MULTILINESTRING = "MULTILINESTRING";
+ /** known WKT type POINT */
+ public static final String POINT = "POINT";
+
+ /** are all lines of the file read */
+ private boolean done;
+ /** reader for the data */
+ private BufferedReader reader;
+
+ /**
+ * Read point data from a file
+ * @param file The file to read points from
+ * @return A list of coordinates read from the file
+ * @throws IOException if something went wrong while reading
+ */
+ public List readPoints(File file) throws IOException {
+ return readPoints(new FileReader(file));
+ }
+
+ /**
+ * Read point data from a Reader
+ * @param r The Reader to read points from
+ * @return A list of coordinates that were read
+ * @throws IOException if something went wrong while reading
+ */
+ public List readPoints(Reader r) throws IOException {
+ List points = new ArrayList();
+
+ String type;
+ init(r);
+
+ while((type = nextType()) != null) {
+ if (type.equals(POINT)) {
+ points.add(parsePoint());
+ }
+ else {
+ // known type but not interesting -> skip
+ readNestedContents();
+ }
+ }
+
+ return points;
+ }
+
+ /**
+ * Read line (LINESTRING) data from a file
+ * @param file The file to read data from
+ * @return A list of coordinate lists read from the file
+ * @throws IOException if something went wrong while reading
+ */
+ public List> readLines(File file) throws IOException {
+ List> lines = new ArrayList>();
+
+ String type;
+ init(new FileReader(file));
+
+ while((type = nextType()) != null) {
+ if (type.equals(LINESTRING)) {
+ lines.add(parseLineString(readNestedContents()));
+ }
+ else {
+ // known type but not interesting -> skip
+ readNestedContents();
+ }
+ }
+
+ return lines;
+ }
+
+
+ /**
+ * Initialize the reader to use a certain input reader
+ * @param input The input to use
+ */
+ protected void init(Reader input) {
+ setDone(false);
+ reader = new BufferedReader(input);
+ }
+
+ /**
+ * Returns the next type read from the reader given at init or null
+ * if no more types can be read
+ * @return the next type read from the reader given at init
+ * @throws IOException
+ */
+ protected String nextType() throws IOException {
+ String type = null;
+
+ while (!done && type == null) {
+ type = readWord(reader);
+
+ if (type.length() < 1) { // discard empty lines
+ type = null;
+ continue;
+ }
+ }
+
+ return type;
+ }
+
+ /**
+ * Returns true if type is one of the known WKT types
+ * @param type The type to check
+ * @return true if type is one of the known WKT types
+ */
+ protected boolean isKnownType(String type) {
+ if (type.equals(LINESTRING)) {
+ return true;
+ }
+ else if (type.equals(MULTILINESTRING)) {
+ return true;
+ }
+ else if (type.equals(POINT)) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ /**
+ * Reads a "word", ie whitespace delimited string of characters, from
+ * the reader
+ * @param r Reader to read the characters from
+ * @return The word that was read (or empty string if nothing was read)
+ * @throws IOException
+ */
+ protected String readWord(Reader r) throws IOException {
+ StringBuffer buf = new StringBuffer();
+ char c = skipAllWhitespace(r);
+
+ // read non-whitespace part
+ while(c != (char)-1 && !Character.isWhitespace(c)) {
+ buf.append(c);
+ c = (char)r.read();
+ }
+
+ if (c == (char)-1) {
+ setDone(true);
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Parses a MULTILINESTRING statement that has nested linestrings from
+ * the current reader
+ * @return List of parsed Coord lists
+ * @throws IOException
+ */
+ protected List> parseMultilinestring()
+ throws IOException {
+ List> list = new ArrayList>();
+ String multiContents = readNestedContents(reader);
+ StringReader r2 = new StringReader(multiContents);
+ String lineString = readNestedContents(r2);
+
+ while (lineString.length() > 0) {
+ list.add(parseLineString(lineString));
+ lineString = readNestedContents(r2);
+ }
+
+ return list;
+ }
+
+ /**
+ * Parses a WKT point data from the intialized reader
+ * @return Point data as a Coordinate
+ * @throws IOException if couldn't parse coordinate values
+ */
+ protected Coord parsePoint() throws IOException {
+ String coords = readNestedContents(reader);
+ Scanner s = new Scanner(coords);
+ double x,y;
+
+ try {
+ x = s.nextDouble();
+ y = s.nextDouble();
+ } catch (RuntimeException e) {
+ throw new IOException("Bad coordinate values: '" + coords + "'");
+ }
+
+ return new Coord(x,y);
+ }
+
+ /**
+ * Reads and skips all characters until character "until" is read or
+ * end of stream is reached. Also the expected character is discarded.
+ * @param r Reader to read characters from
+ * @param until What character to expect
+ * @throws IOException
+ */
+ protected void skipUntil(Reader r, char until) throws IOException {
+ char c;
+ do {
+ c = (char)r.read();
+ } while (c != until && c != (char)-1);
+ }
+
+ /**
+ * Skips all consecutive whitespace characters from reader
+ * @param r Reader where the whitespace is skipped
+ * @return First non-whitespace character read from the reader
+ * @throws IOException
+ */
+ protected char skipAllWhitespace(Reader r) throws IOException {
+ char c;
+ do {
+ c = (char)r.read();
+ } while (Character.isWhitespace(c) && c != (char)-1);
+
+ return c;
+ }
+
+ /**
+ * Reads everything from the first opening parenthesis until line that
+ * ends to a closing parenthesis and returns the contents in one string
+ * @param r Reader to read the input from
+ * @return The text between the parentheses
+ */
+ public String readNestedContents(Reader r) throws IOException {
+ StringBuffer contents = new StringBuffer();
+ int parOpen; // nrof open parentheses
+ char c = '\0';
+
+ skipUntil(r,'(');
+ parOpen = 1;
+
+ while (c != (char)-1 && parOpen > 0) {
+ c = (char)r.read();
+ if (c == '(') {
+ parOpen++;
+ }
+ if (c == ')') {
+ parOpen--;
+ }
+ if (Character.isWhitespace(c)) {
+ c = ' '; // convert all whitespace to basic space
+ }
+ contents.append(c);
+ }
+
+ contents.deleteCharAt(contents.length()-1); // remove last ')'
+ return contents.toString();
+ }
+
+ /**
+ * Returns nested contents from the reader given at init
+ * @return nested contents from the reader given at init
+ * @throws IOException
+ * @see #readNestedContents(Reader)
+ */
+ public String readNestedContents() throws IOException {
+ return readNestedContents(reader);
+ }
+
+ /**
+ * Parses coordinate tuples from "LINESTRING" lines
+ * @param line String that contains the whole "LINESTRING"'s content
+ * @return List of coordinates parsed from the linestring
+ */
+ protected List parseLineString(String line) {
+ List coords = new ArrayList();
+ Scanner lineScan;
+ Scanner tupleScan;
+ double x,y;
+ Coord c;
+
+ lineScan = new Scanner(line);
+ lineScan.useDelimiter(",");
+
+ while (lineScan.hasNext()) {
+ tupleScan = new Scanner(lineScan.next());
+ x = Double.parseDouble(tupleScan.next());
+ y = Double.parseDouble(tupleScan.next());
+ c = new Coord(x,y);
+
+ coords.add(c);
+ }
+
+ return coords;
+ }
+
+ /**
+ * Returns true if the whole file has been read
+ * @return true if the whole file has been read
+ */
+ protected boolean isDone() {
+ return this.done;
+ }
+
+ /**
+ * Sets the "is file read" state
+ * @param done If true, reading is done
+ */
+ protected void setDone(boolean done) {
+ this.done = done;
+ }
+
+}
diff --git a/input/package.html b/input/package.html
index ab7fd2259..f0a28be85 100644
--- a/input/package.html
+++ b/input/package.html
@@ -1,8 +1,8 @@
-
-
-
-
-Provides interfaces and classes for reading input data from external sources.
-
-
-
\ No newline at end of file
+
+
+
+
+Provides interfaces and classes for reading input data from external sources.
+
+
+
diff --git a/interfaces/ConnectivityGrid.java b/interfaces/ConnectivityGrid.java
index 4ee1082ae..ca24d16d1 100644
--- a/interfaces/ConnectivityGrid.java
+++ b/interfaces/ConnectivityGrid.java
@@ -1,323 +1,323 @@
-/*
+/*
* Copyright 2010 Aalto University, ComNet
- * Released under GPLv3. See LICENSE.txt for details.
- */
-package interfaces;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-
-import movement.MovementModel;
-
-import core.Coord;
-import core.DTNSim;
-import core.NetworkInterface;
-import core.Settings;
-import core.SettingsError;
-import core.World;
-
-/**
- *
- * Overlay grid of the world where each interface is put on a cell depending
- * of its location. This is used in cell-based optimization of connecting
- * the interfaces.
- *
- * The idea in short:
- * Instead of checking for every interface if some of the other interfaces are close
- * enough (this approach obviously doesn't scale) we check only interfaces that
- * are "close enough" to be possibly connected. Being close enough is
- * determined by keeping track of the approximate location of the interfaces
- * by storing them in overlay grid's cells and updating the cell information
- * every time the interfaces move. If two interfaces are in the same cell or in
- * neighboring cells, they have a chance of being close enough for
- * connection. Then only that subset of interfaces is checked for possible
- * connectivity.
- *
- *
- * Note: this class does NOT support negative
- * coordinates. Also, it makes sense to normalize the coordinates to start
- * from zero to conserve memory.
- */
-public class ConnectivityGrid extends ConnectivityOptimizer {
-
- /**
- * Cell based optimization cell size multiplier -setting id ({@value}).
- * Used in {@link World#OPTIMIZATION_SETTINGS_NS} name space.
- * Single ConnectivityCell's size is the biggest radio range times this.
- * Larger values save memory and decrease startup time but may result in
- * slower simulation.
- * Default value is {@link #DEF_CON_CELL_SIZE_MULT}.
- * Smallest accepted value is 1.
- */
- public static final String CELL_SIZE_MULT_S = "cellSizeMult";
- /** default value for cell size multiplier ({@value}) */
- public static final int DEF_CON_CELL_SIZE_MULT = 5;
-
- private GridCell[][] cells;
- private HashMap ginterfaces;
- private int cellSize;
- private int rows;
- private int cols;
- private static int worldSizeX;
- private static int worldSizeY;
- private static int cellSizeMultiplier;
-
- static HashMap gridobjects;
-
- static {
- DTNSim.registerForReset(ConnectivityGrid.class.getCanonicalName());
- reset();
- }
-
- public static void reset() {
- gridobjects = new HashMap();
-
- Settings s = new Settings(MovementModel.MOVEMENT_MODEL_NS);
- int [] worldSize = s.getCsvInts(MovementModel.WORLD_SIZE,2);
- worldSizeX = worldSize[0];
- worldSizeY = worldSize[1];
-
- s.setNameSpace(World.OPTIMIZATION_SETTINGS_NS);
- if (s.contains(CELL_SIZE_MULT_S)) {
- cellSizeMultiplier = s.getInt(CELL_SIZE_MULT_S);
- }
- else {
- cellSizeMultiplier = DEF_CON_CELL_SIZE_MULT;
- }
- if (cellSizeMultiplier < 1) {
- throw new SettingsError("Too small value (" + cellSizeMultiplier +
- ") for " + World.OPTIMIZATION_SETTINGS_NS +
- "." + CELL_SIZE_MULT_S);
- }
- }
-
- /**
- * Creates a new overlay connectivity grid
- * @param cellSize Cell's edge's length (must be larger than the largest
- * radio coverage's diameter)
- */
- private ConnectivityGrid(int cellSize) {
- this.rows = worldSizeY/cellSize + 1;
- this.cols = worldSizeX/cellSize + 1;
- // leave empty cells on both sides to make neighbor search easier
- this.cells = new GridCell[rows+2][cols+2];
- this.cellSize = cellSize;
-
- for (int i=0; i();
- }
-
- /**
- * Returns a connectivity grid object based on a hash value
- * @param key A hash value that separates different interfaces from each other
- * @param maxRange Maximum range used by the radio technology using this
- * connectivity grid.
- * @return The connectivity grid object for a specific interface
- */
- public static ConnectivityGrid ConnectivityGridFactory(int key,
- double maxRange) {
- if (gridobjects.containsKey((Integer)key)) {
- return (ConnectivityGrid)gridobjects.get((Integer)key);
- } else {
- ConnectivityGrid newgrid =
- new ConnectivityGrid((int)Math.ceil(maxRange *
- cellSizeMultiplier));
- gridobjects.put((Integer)key,newgrid);
- return newgrid;
- }
- }
-
- /**
- * Adds a network interface to the overlay grid
- * @param ni The new network interface
- */
- public void addInterface(NetworkInterface ni) {
- GridCell c = cellFromCoord(ni.getLocation());
- c.addInterface(ni);
- ginterfaces.put(ni,c);
- }
-
- /**
- * Removes a network interface from the overlay grid
- * @param ni The interface to be removed
- */
- public void removeInterface(NetworkInterface ni) {
- GridCell c = ginterfaces.get(ni);
- if (c != null) {
- c.removeInterface(ni);
- }
- ginterfaces.remove(ni);
- }
-
- /**
- * Adds interfaces to overlay grid
- * @param interfaces Collection of interfaces to add
- */
- public void addInterfaces(Collection interfaces) {
- for (NetworkInterface n : interfaces) {
- addInterface(n);
- }
- }
-
- /**
- * Checks and updates (if necessary) interface's position in the grid
- * @param ni The interface to update
- */
- public void updateLocation(NetworkInterface ni) {
- GridCell oldCell = (GridCell)ginterfaces.get(ni);
- GridCell newCell = cellFromCoord(ni.getLocation());
-
- if (newCell != oldCell) {
- oldCell.moveInterface(ni, newCell);
- ginterfaces.put(ni,newCell);
- }
- }
-
- /**
- * Finds all neighboring cells and the cell itself based on the coordinates
- * @param c The coordinates
- * @return Array of neighboring cells
- */
- private GridCell[] getNeighborCellsByCoord(Coord c) {
- // +1 due empty cells on both sides of the matrix
- int row = (int)(c.getY()/cellSize) + 1;
- int col = (int)(c.getX()/cellSize) + 1;
- return getNeighborCells(row,col);
- }
-
- /**
- * Returns an array of Cells that contains the neighbors of a certain
- * cell and the cell itself.
- * @param row Row index of the cell
- * @param col Column index of the cell
- * @return Array of neighboring Cells
- */
- private GridCell[] getNeighborCells(int row, int col) {
- return new GridCell[] {
- cells[row-1][col-1],cells[row-1][col],cells[row-1][col+1],//1st row
- cells[row][col-1],cells[row][col],cells[row][col+1],//2nd row
- cells[row+1][col-1],cells[row+1][col],cells[row+1][col+1]//3rd row
- };
- }
-
- /**
- * Get the cell having the specific coordinates
- * @param c Coordinates
- * @return The cell
- */
- private GridCell cellFromCoord(Coord c) {
- // +1 due empty cells on both sides of the matrix
- int row = (int)(c.getY()/cellSize) + 1;
- int col = (int)(c.getX()/cellSize) + 1;
-
- assert row > 0 && row <= rows && col > 0 && col <= cols : "Location " +
- c + " is out of world's bounds";
-
- return this.cells[row][col];
- }
-
- /**
- * Returns all interfaces that use the same technology and channel
- */
- public Collection getAllInterfaces() {
- return (Collection)ginterfaces.keySet();
- }
-
- /**
- * Returns all interfaces that are "near" (i.e., in neighboring grid cells)
- * and use the same technology and channel as the given interface
- * @param ni The interface whose neighboring interfaces are returned
- * @return List of near interfaces
- */
- public Collection getNearInterfaces(
- NetworkInterface ni) {
- ArrayList niList = new ArrayList();
- GridCell loc = (GridCell)ginterfaces.get(ni);
-
- if (loc != null) {
- GridCell[] neighbors =
- getNeighborCellsByCoord(ni.getLocation());
- for (int i=0; i < neighbors.length; i++) {
- niList.addAll(neighbors[i].getInterfaces());
- }
- }
-
- return niList;
- }
-
-
- /**
- * Returns a string representation of the ConnectivityCells object
- * @return a string representation of the ConnectivityCells object
- */
- public String toString() {
- return getClass().getSimpleName() + " of size " +
- this.cols + "x" + this.rows + ", cell size=" + this.cellSize;
- }
-
- /**
- * A single cell in the cell grid. Contains the interfaces that are
- * currently in that part of the grid.
- */
- public class GridCell {
- // how large array is initially chosen
- private static final int EXPECTED_INTERFACE_COUNT = 5;
- private ArrayList interfaces;
-
- private GridCell() {
- this.interfaces = new ArrayList(
- EXPECTED_INTERFACE_COUNT);
- }
-
- /**
- * Returns a list of of interfaces in this cell
- * @return a list of of interfaces in this cell
- */
- public ArrayList getInterfaces() {
- return this.interfaces;
- }
-
- /**
- * Adds an interface to this cell
- * @param ni The interface to add
- */
- public void addInterface(NetworkInterface ni) {
- this.interfaces.add(ni);
- }
-
- /**
- * Removes an interface from this cell
- * @param ni The interface to remove
- */
- public void removeInterface(NetworkInterface ni) {
- this.interfaces.remove(ni);
- }
-
- /**
- * Moves a interface in a Cell to another Cell
- * @param ni The interface to move
- * @param to The cell where the interface should be moved to
- */
- public void moveInterface(NetworkInterface ni, GridCell to) {
- to.addInterface(ni);
- boolean removeOk = this.interfaces.remove(ni);
- assert removeOk : "interface " + ni +
- " not found from cell with " + interfaces.toString();
- }
-
- /**
- * Returns a string representation of the cell
- * @return a string representation of the cell
- */
- public String toString() {
- return getClass().getSimpleName() + " with " +
- this.interfaces.size() + " interfaces :" + this.interfaces;
- }
- }
-
-}
\ No newline at end of file
+ * Released under GPLv3. See LICENSE.txt for details.
+ */
+package interfaces;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+
+import movement.MovementModel;
+
+import core.Coord;
+import core.DTNSim;
+import core.NetworkInterface;
+import core.Settings;
+import core.SettingsError;
+import core.World;
+
+/**
+ *