Ad Hoc On Demand Distance Vector (AODV) is a reactive ad-hoc routing protocol which is scalable from tens to thousands of nodes with differing levels of mobility.
Some gaps in functionality observed when running identical topology/traffic flow simulation in ns2:\n\n1. no proactive route management in simulations with mobility. in ns2, if a neighbouring node roams out of range, the previous node's link layer generates a transmit failure message which aodv routing protocol in ns2 hooks into (see {{{ch->xmit_failure = aodv_rt_failed_callback}}} in\n\nThis causes AODV to:\n- generate a RRER for the destinations now made unreachable by the next hop being unreachable\n- forces node to RREQ once more for new route for destination\n\nin SWANS simulation, we have to wait until TIMEOUT condition (through non-receipt of 3 consecutive hello messages) ocurrs before route rediscovery takes place.\n\nNoticed that some todo's are left in mac layer code for SWANS, specifically residing in the {{{retryNo()}}} function. Added call to {{{NetInterface.notifyDrop()}}} function within {{{retryNo()}}} and implemented this in all concrete implementations of the interface ({{{NetIp}}}, {{{NetIpAIS}}}). \n\n{{{NetIp.notifyDrop}}} implemenation pseudo-code:\n\n- go through IFQ and remove all packets awaiting transmission via {{{pump()}}} through unreachable next hop\n- call {{{RouteInterface.notifyDrop()}}}.\n\n{{{RouteAodv.notifyDrop}}} implementation pseudo-code:\n\n- get a list of all the destinations made unreachable by next hop being unreachable\n- remove these\n- get node to send broadcast RRER, TTL=1 to neighbours\n- then successive requests to send a packet to unreachable destination lead to a RREQ being generated.\n\nOther issues:\n1. route expirations are only implemented if a {{{hello_wait_count}}} HELLO messages from a particular node are not received. This number is incremented on each call to {{{timeout()}}}. There are no alternative forms for route timeout which AODV mandates, including those when a entry in the routing table expires, as there is no {{{lifetime}}} field either in RREP's or the routing table entry. This has been fixed in pkiddie.route.RouteAODVMultiInterfaceExpireRoute. \n2. HELLO messages have only been implemented partially. HELLO messages should be broadcast from a node on each timeout when the routing protocol starts. In RouteAodv, HELLO messages seem to be unicast to a particular next hop.\n3. doesn't support routes over multiple interfaces. Fixed in pkiddie.route.RouteAODVMultiInterface. Modified route table entries to contain an interface id, and references to SendIpMsg() to send pkts via a particular interface id. RREQ broadcasts now iterate over all interfaces.\n\n
config.options.chkHttpReadOnly = false;\n
In the current implementation of DotNetNuke, the skinning engine automatically adds a container to a slave module, i.e. one instanced from a master module -- think the events details in the events module.\n\nThis may not exactly be the desired behaviour, but it is relatively easy to prevent. You need the source copy of DotNetNuke.\n\nThe magic happens in two places\n\n1. line 252 of {{{skin.vb}}}\n\n{{{\nIf ctlContainer Is Nothing Then\n ' if the module specifies that no container should be used\n If objModule.DisplayTitle = False Then\n Dim blnDisplayTitle As Boolean\n 'user PDK\n If IsNothing(Request.QueryString("user")) = False Then\n blnDisplayTitle = False\n Else\n ' always display container if the current user is the administrator or the module is being used in an admin case\n blnDisplayTitle = (PortalSecurity.IsInRoles(PortalSettings.AdministratorRoleName) Or PortalSecurity.IsInRoles(PortalSettings.ActiveTab.AdministratorRoles.ToString)) Or IsAdminSkin(PortalSettings.ActiveTab.IsAdminTab)\n End If\n \n ' unless the administrator has selected the Page Preview option\n If blnDisplayTitle = True Then\n If Not Request.Cookies("_Tab_Admin_Preview" & PortalSettings.PortalId.ToString) Is Nothing Then\n blnDisplayTitle = Not Boolean.Parse(Request.Cookies("_Tab_Admin_Preview" & PortalSettings.PortalId.ToString).Value)\n End If\n End If\n If blnDisplayTitle = False Then\n objModule.ContainerSrc = SkinController.FormatSkinSrc("[G]" & SkinInfo.RootContainer & "/_default/No Container.ascx", PortalSettings)\n ctlContainer = LoadContainer(objModule.ContainerSrc, objPane)\n End If\n End If\n End If\n}}}\n\nAs a simple hack skin.vb checks the query string of the browser for the key 'user' and if so, sets the 'DisplayTitle' to false. This propogates through and the No Container.ascx is loaded!\n\n2. line 970 or there abouts of {{{skin.vb }}}\n\n{{{ slaveModule.DisplayTitle = True }}}\n\nAgain, like above wrap this in an if..else statement checking for a particular value on the query string. This won't expose any security risks but will simply allow the user to choose in a programatical way whether the module shown should show its container.
AppIDS is my application layer Intrusion Detection System. It is based on the driver.heartbeat example.
The default implementation of SWANS has a vast array of mobility models we can use, including:\n\n- RandomWaypoint\n- Teleport\n- Static\n- RandomWalk\n\nBut none of the current mobility models to cater for completely scripted simulations, where the user is able to exactly specify an ordered sequence of locations the node must go to over the course of the simulation.\n\nIn this tutorial, I'll show you how we can define a new mobility model for use in SWANS.\n\nI started by creating a new Mobility interface derived from {{{ Mobility }}} called {{{ ScriptedMobility }}}. This defines an extra method called {{{ addPath }}} which allows the user in the simulation script to call {{{ addPath() }}} at simulation setup\n\\n{{{\npublic interface ScriptedMobility extends Mobility {\n \n void addPath(Location.Location2D loc, long speed, long time);\n}\n}}}\n\nMy new mobility model, which I've obscurely called 'MoveTo', then implements that interface, which in turn extends the Mobility interface, hence should provide implementation for the following methods: {{{ next }}}, {{{ init }}}, {{{ addPath }}}.\n{{{\n/**\n * Schedule next movement. This method will again be called after every\n * movement on the field.\n *\n * @param f field entity\n * @param id radio identifier\n * @param loc destination of move\n * @param info mobility information object\n */\n void next(FieldInterface f, Integer id, Location loc, MobilityInfo info);\n}}}\n\n{{{\n/**\n * Initiate mobility; initialize mobility data structures.\n *\n * @param f field entity\n * @param id node identifier\n * @param loc node location\n * @return mobility information object\n */\n MobilityInfo init(FieldInterface f, Integer id, Location loc);\n}}}\n\n{{{\n/**\n* Provides a mechanism for a user to add a new waypoint onto the current\n* mobility object\n*\n* @param loc desired node location\n* @param speed node speed (m/s)\n* @param time time to begin movement\n* @return void\n*/\n void addPath(Location.Location2D loc, long speed, long time);\n}}}\n\n1. Implementing init method\nAs the comment above suggests, this is used simply at simulation start up to initialise the mobility model on a node by node basis. For this simple waypoint model, I borrowed the RandomWaypoint MobilityInfo definition, as it stores everything necessary.\n\ninit():\n\n{{{\npublic MobilityInfo init(FieldInterface f, Integer id, Location loc)\n {\n return new RandomWaypointInfo();\n }\n}}}\n\nThis RandomWaypointInfo contains state information concerning the waypoint to reach, the number of steps required to reach that waypoint, and the duration of each step (corresponding to the percieved speed of the node)\n\n2. Implementing the next method\nMost of the processing should appear here. My {{{MoveTo}}} class contains a generic vector collection of type {{{LocationSpeedTime}}}:\n\n{{{\npublic static class LocationSpeedTime {\n \n public long time;\n public long speed;\n \n public Location.Location2D loc;\n \n public LocationSpeedTime(long time, Location2D loc, long speed)\n {\n this.time = time;\n this.loc = loc;\n this.speed = speed;\n }\n }\n}}}\n\nwhich corresponds to the arguments in the {{{addPath}}} method of ScriptedMobility. The use of a vector collection is not specified, you can store calls to addPath in any way you want.\n\nnext():\n{{{\npublic void next(FieldInterface f, Integer id, Location loc, MobilityInfo info) {\n boolean timesup=false; //used where previous waypoint not executed fully\n //but is time for new waypoint to become active\n \n boolean sleeping=false; //used in first waypoints case where we need to sleep\n //until first waypoint to be active\n \n //assert that the current location of the node is inside the bounds of the sim\n if(Main.ASSERT) \n Util.assertion(loc.inside(bounds));\n \n //this is special case - sleep until first waypoint event\n if (index==0)\n {\n JistAPI.sleep(locations.get(0).time); \n sleeping=true;\n }\n \n //set up movements\n try {\n RandomWaypointInfo rwi = (RandomWaypointInfo)info;\n \n //if we have more waypoints to go to\n if (index<locations.size())\n {\n //and no more steps \n if (rwi.steps==0 & !sleeping)\n {\n //sleep for duration until next waypoint should be active\n JistAPI.sleep(locations.get(index).time - JistAPI.getTime());\n }\n }\n \n //if we have more waypoints to go to\n if (index<locations.size())\n {\n //and the time of the simulation requires us to go to next waypoint\n if (JistAPI.getTime()>=locations.get(index).time)\n {\n timesup = true;\n }\n }\n \n //check we've reached destination or time for this destination is up\n if(rwi.steps==0 || timesup)\n {\n \n //no more waypoints to execute\n if (index>=locations.size())\n {\n return; //no future calls made to next()\n }\n \n rwi.waypoint = locations.get(index).loc;\n \n //assert new waypoint is in the bounds\n if(Main.ASSERT) {\n Util.assertion(rwi.waypoint.inside(bounds));\n }\n \n float speed = locations.get(index).speed; //get speed\n float dist = loc.distance(rwi.waypoint); //get distance between\n //current loc and waypoint\n \n rwi.steps = (int)Math.max(Math.floor(dist / precision), 1);\n \n if (Main.ASSERT) {\n Util.assertion(rwi.steps>0);\n }\n \n float time = dist / speed;\n \n rwi.stepTime = (long)(time*Constants.SECOND/rwi.steps);\n \n //increment index to point to next waypoint\n index++;\n }\n \n //until node reached dest, or time is up, keep stepping to reach destination\n JistAPI.sleep(rwi.stepTime);\n Location step = loc.step(rwi.waypoint, rwi.steps--);\n f.moveRadioOff(id, step);\n }\n \n catch(ClassCastException e) {\n // different mobility model installed\n }\n }\n}}}\n\nHopefully comments explain the functionality here. We simply are iterating through the list of waypoints specified by the user and held in the {{{locations}}} vector. Some extra functionality was required in the cases whereby:\n\n- the node moves any t>0. In this case we should sleep until the first waypoint becomes active.\n\n- the node has reached the waypoint, there are more to execute, but not for a while -- should sleep until next waypoint\n\n- the node has not reached the waypoint specified, and it is time for the next one to be executed -- we should now override movement instead to the new waypoint.\n\n3. Finally we need to implement the addPath method, something like this will do:\n{{{\npublic void addPath(Location.Location2D loc,long timeToStart,long speed)\n {\n this.locations.add(new LocationSpeedTime(timeToStart*Constants.SECOND,loc,speed));\n }\n}}}\n\n\n
I was investigating a simple way of running simulations within the Jist/SWANS framework to determine my success rate in simulation runs (the number of simulations which run to completion without exceptions) and came up with this. \n\n{{{\n\npublic class Sim24_Wrapper {\n \n /**\n * Null output stream, used for ignoring any simulation standard output\n * @author PDK140\n *\n */\n public static class NullOutputStream extends OutputStream\n {\n\n @Override\n public void write(int b) throws IOException {\n //do nothing!\n \n }\n }\n \n /**\n * Output stream with count, used for detecting any errors on run of simulation\n * \n * @author PDK140\n *\n */\n public static class OutputStreamWithCount extends OutputStream\n {\n StringBuilder sb;\n\n public OutputStreamWithCount()\n {\n sb = new StringBuilder();\n }\n \n @Override\n public void write(int b) throws IOException {\n sb.append((char)b);\n }\n \n public int getLength()\n {\n return sb.length();\n }\n \n public String toString()\n {\n return sb.toString();\n }\n \n public void clear()\n {\n //sb = new StringBuilder();\n sb.delete(0,sb.length());\n }\n \n \n }\n \n /** number of repeats */\n public static final int MAX_REPEATS = 100;\n \n /** successful integer, number of simulations run succesfully */\n static int successful=0;\n \n /** backup of System.out when we do want to print back out */\n static PrintStream ps = System.out;\n \n /** null printstream, used to ignore standard output when necessary */\n static PrintStream nullPs = new PrintStream(new NullOutputStream());\n \n /** string outputstream, used to detect if any errors in simulation run */\n static OutputStreamWithCount errorNullOutputStream = new OutputStreamWithCount();\n \n /** error printstream */\n static PrintStream errorNullPs = new PrintStream(errorNullOutputStream);\n \n static boolean QUIT_ON_FAIL = false;\n \n public static void main(String[] args) \n {\n System.setErr(errorNullPs);\n \n int curRepeat=1;\n \n //explore parameter space\n while (curRepeat<=MAX_REPEATS) {\n \n System.out.print(String.format("run %s",curRepeat));\n \n String[] arg = new String[] { "jist.swans.Main",\n "pkiddie.driver.Sim24_MaliciousNode_DelayPackets"};\n \n //try {\n \n System.setOut(nullPs);\n Constants.random = new Random(new Date().getTime());\n \n jist.runtime.Main.main(arg);\n \n System.setOut(ps);\n\n //}\n \n //catch (Exception ex) {\n if (errorNullOutputStream.getLength()>0) {\n \n //ex.printStackTrace();\n System.out.println(": failed, more info: "+errorNullOutputStream.toString());\n \n errorNullOutputStream.clear();\n \n if (QUIT_ON_FAIL) return;\n \n }\n \n else {\n successful++;\n \n System.out.println(": success!");\n }\n \n curRepeat++;\n }\n \n System.out.println(String.format("success rate: %s/%s",successful,curRepeat));\n \n }\n}\n}}}\n\nI subclass {{{OutputStream}}} to create: \n1. {{{NullOutputStream}}} used to discard any println statements for the simulation I'm running (in my case {{{}}}\n\n2. {{{OuputStreamWithCount}}} used to determine the presence of exceptions (unfortunately jist.main.Main handles exceptions so I redirect the stderr to this)\n\nI then run the simulation, and check the length of the static instance of {{{OutputStreamWithCount}}}. If its greater than 0, then we've caught an exception (not the nicest I agree!) and we can take the appropriate action, i.e. terminate the wrapper, carry on but mark it etc.
Dynamic Source Routing (DSR) is another reactive routing protocol based on source routing, which is the addition of the route to the IP packet header.
This is probably one of the great things about using Eclipse with Jist, is that you get full debugger support. There are a few pitfalls to be aware of, as a simulation doesnt necessarily execute in the same way as a normal piece of Java code.\n\nFor example, calls to {{{send()}}} or {{{receive()}}} at any of the layers of the protocol stack are not executed immediately. Instead when you step through the execution, you will most likely navigate inside a {{{JistAPI}}} class, where this method, or in the Jist terminology, event, is then queued in an event list for execution at a certain time. If you want to follow the sending of a message through the protocol stack, one of the best approaches is to navigate to the definition, for example {{{MacDumb.receive()}}}, put a breakpoint there, then resume and let Jist do its thing, and it will break so you can follow the execution within the {{{receive}}} event.
[[My Home]] MyResearch JistSwans [[ns2]]
Within {{{}}} in the {{{}}} package, a class responsible for assigning a message queue to each network interface in SWANS etc.\n\nWithin the {{{public void receive(Message msg, MacAddress lastHop, byte macId, boolean promisc)}}}, we simply check the state of the {{{promisc}}} field and then can do what we want accordingly, i.e.\n\n{{{\nif (promisc) {\nSystem.out.println("I overheard this packet promiscuously!");\n}\n}}}\n\nFurthermore, we can pass this onto the higher layers, if neccesary, by modifying {{{}}} and {{{}}} I'm using this for detecting the behaviour of neighbours, including dropped routing/data packet,\n
DotNetNuke is an open source Content Management System written for ASP.NET and works with either C# or VB compiled languages.
There are various situations where a packet should be dropped at the node level\n\n- Send/recieve buffer of network interface full\n- Destination specified on packet does not exist\n- Corruption: data/header does not pass CRC check\netc.
[[Eclipse|]] is an open-source development environment for developing applications in many different languages
Trust cannot be assured in an ad-hoc network since most ad-hoc networks consist of devices which roam in and out of range at will. But trust is important, especially in the ad-hoc network, and we can use trust in several manners:\n1. How often should I sample a packet originating from a particular node?\n2. How much should I trust the information provided to me by a particular node?\n\nI am exploring how trust can be established in terms of sampling packets in an ad-hoc network. Currently in [[NetSampler]], packets are assumed to be malicious/not malicious, and depending on the [[Sampling strategy|Sampling strategies]]\n\nI am also trying to anticipate ways that a trust mechanism can be compromised. Mainly this would be through:\n1. False information spreading (malicious packets generated by an impersonator, IDS packets generated that incriminate trusted node)\n2. Spoofing IP/MAC address of trusted node\n\nThere are several issues, including, a secure way of assigning a trust value to a node that is resilient to IP spoofing, or even a simple IP address change in order to circumvent the trust value associated with the node.
Comment the line \n{{{#define AODV_LINK_LAYER_DETECTION}}} within aodv.h. Then call make on the ns directory to rebuild the changes, and observe HELLO messages in the .tr file
This aspect of simulation is not covered in the sample simulation files, and is very useful for testing various scenarios is JIST/SWANS.\n\n{{{\n//lets assume no mobility currently but should be able to be done on a per node basis!\n Mobility mobility = new Mobility.Static();\n \n //set up field\n Field field = new Field(this.spatial,this.fading,this.pathLoss,\n mobility,Constants.PROPAGATION_LIMIT_DEFAULT);\n \n setupNode(0,0,0,field); //node 0 is still\n \n mobility = new Mobility.Teleport(fieldDimensions,5*Constants.SECOND);\n \n field.setMobility(mobility);\n setupNode(1,200,200,field); //node 1 should teleport within bounds every 20 secs\n}}}\n\nThe key property is {{{ field.setMobility }}} which accepts a reference to a mobility object.\n\nSo you can see that we have have nodes with different mobility patterns in a single field corresponding to our simulation
Usually, if a ethernet frame is received with a destination MAC not intended for the recepient node, it is discarded by the MAC layer. Enabling promiscuous mode means the MAC layer forwards this packet onto the higher layers. This is incredibly useful in an ad-hoc IDS in order to retreive additional information about the local neighbourhood.\n\nThis is not covered in the sample simulation drivers, but its relatively simple to implement.\n\n1. Create a MAC object from one of the types defined in SWANS {{{ Mac802_11 }}} or {{{MacDumb}}}\n\n2. the MAC object exposes a public property called {{{ setPromiscuous(bool) }}}, so we can do the following to set the MAC to operate in promiscuous mode\n\n{{{\nmac.setPromiscuous(true);\n}}}\n\nin your simulation code will do the trick. - [[SWANS++]] distribution with various bugfixes, GUI for VANET scenarios etc.
1. Raleigh\n\n2. Rician
Game Theory is an economic theory used in predicting optimal outcomes of games.
The science of the human immune system
1. Behaviour outside routing protocol specification.\nI'm assuming the use of AODV and there are several SHOULD's including adherence to the RREQ_RATE_LIMIT. If a node originates more than RREQ_RATE_LIMIT RREQ's per second, then the node is flagged as misbehaving and the appropriate action is taken.\n\nHow has this been implemented within Jist/SWANS? See [[RREQ_RATE_LIMIT Implementation|RREQ_RATE_LIMITImpl]]\n\n2. MAC/IP spoofing.\nI am using some previous work which leverages the 802.11 sequence number generation. Given a series of communications between a pair of nodes, there should be a linear increase in sequence numbers within the 802.11 frames. If one of these nodes has been spoofed during communications, there is a very high likelihood that the sequence number will be anomalous. [ref] recommends that +/- 30 is a good threshold of sequence numbers, and anything that varies outside these limits should be tagged as misbehaviour. Of course, this doesnt take into account mobility, where it could appear that the nodes 802.11 frame sequence number is anomalous.\n\nSee [[Spoofing Implementation|SpoofingImpl]] for Jist/SWANS implementation of MAC-IP spoofing, and detection\n\n3. Dropped packets.\nTo detect dropped packets, we enable promicuous mode on each of the nodes within the simulation. We extend the network layer so that we can determine which packets have been heard promisciously and which ones havent, and then perform the relevant processing on these.
A good example of a simple application layer program running over a Jist/SWANS simulation is {{{}}} and related application layer implementation {{{}}}. This illustrates a heartbeat neighbour discovery protocol, showing how we can queue discoveries to abide by simulation time.\n\nBlueprint for an application layer program:\n\n1. Create a new class in {{{}}} and inherit from {{{AppInterface}}} and {{{NetInterface.NetHandler}}}.\n\n2. Implement the relevent interface methods, including {{{receive()}}} and {{{run()}}}\n\n3. If implementing a custom protocol, you can hook up your simulation so that custom packets that your protocol generates are received directly on the new application layer {{{receive()}}} method. See {{{}}} and {{{}}} for the specific implementation. You will need to call {{{setProtocolHandler}}} and implement a custom protocol number for your custom protocol.\n\n4. Any code that you want to run periodically should be put in {{{run}}}. Much like the simple {{{Hello world}}} example in the Jist handbook, you can call {{{JistAPI.sleep(time)}}} and recall {{{run}}} from within itself and this will be called until the simulation terminates (and won't generate a stack overflow like infinite recursion would normally!)
I guess the singlemost obstruction in using SWANS for worthwhile research is the lack of a proper trace mechanism (without writing your own of course!) so my intention here is to emulate the {{{ }}} trace file support in ns under Jist/SWANS. \n\nUsing JavisTrace as a base, with extensions to write both a {{{ .tr }}} and {{{ .nam }}} file. Why not make use of the multitude of post-processing perl and NAM itself which is an excellent network animator?\n\nChanges:\n\n- {{{ dump() }}} methods to dump the current trace line by line\n- {{{ formatNam }}} and {{{ formatTrace }}} for .nam and .tr files respectively\n- singleton instance of the Trace object, accessible throughout simulation environment\n\nMain architectural differences\n\nns2: my belief is that routing messages (RREQ/RREP/RRER), and routed messages from the UDP/TCP agent are sent from the routing agent to the next nodes routing agent. SWANS: messages are ALWAYS delivered to the network layer before being sent to the correct agent through this important line in the {{{ receive }}} method of the {{{ NetIp }}} class\n\n{{{ \ngetProtocolHandler(ipmsg.getProtocol()).receive(ipmsg.getPayload(), \n ipmsg.getSrc(), lastHop, macId, ipmsg.getDst(), \n ipmsg.getPriority(), (byte)ipmsg.getTTL());\n}}}\n\neach payload has a particular protocol id, which signified if it is an AODV packet, a TCP or UDP packet etc etc.
[[Jist/SWANS|]] is a discrete time event network simulator written in Java. I'm using it for my networking research due to a flexible, object oriented approach. Measurements taken from identical simulations show it compares favourably, and can outperform other network simulators [ [[Jist/SWANS @ Cornell|]]].\n\nThe API is very modular, built around the layers of the OSI stack (so easy to see where new functionality should be coded). New network, routing, MAC, or physical layers can be added with relative ease due to the use of interfaces in the particular layers, for example RadioInterface, NetInterface, RouteInterface, which defines the basic functionality that should be implemented.\n\nThere is a small but growing community of users, with several other projects using and extending the Jist/SWANS distributions: \n\n1. [[SWANS++]]: Adds functionality and fixes bugs in the latest version of Jist/SWANS, currently at 1.0.6. Also a [[forum|]].\n2. Extensions by ULM university: [[jist-swans-1.0.6-ulm|]]\n3. Extensions and bug fixes by Gabriel Kliot:
/***\n|''Name:''|LegacyStrikeThroughPlugin|\n|''Description:''|Support for legacy (pre 2.1) strike through formatting|\n|''Version:''|1.0.1|\n|''Date:''|Jul 21, 2006|\n|''Source:''||\n|''Author:''|MartinBudden (mjbudden (at) gmail (dot) com)|\n|''License:''|[[BSD open source license]]|\n|''CoreVersion:''|2.1.0|\n|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|\n\n***/\n\n//{{{\n\n// Ensure that the LegacyStrikeThrough Plugin is only installed once.\nif(!version.extensions.LegacyStrikeThroughPlugin)\n {\n version.extensions.LegacyStrikeThroughPlugin = true;\n\nconfig.formatters.push(\n{\n name: "legacyStrikeByChar",\n match: "==",\n termRegExp: /(==)/mg,\n element: "strike",\n handler: config.formatterHelpers.createElementAndWikify\n});\n\n} // end of "install only once"\n//}}}\n
Jist has the [[apache log4j|]] library built into it, and it is used extensively in the simulation kernel to log events of interest such as those of the {{{JistController}}}. We can actually use this library independantly of the current logging, and I have done so for {{{RouteAodv}}}, my ad-hoc protocol of choice for my current research.\n\nTo declare a new logger instance\n{{{}}}\n{{{\npublic class RouteAodv implements RouteInterface.Aodv\n{\n //create a new logger for RouteAodv\n public static Logger logger = Logger.getLogger(RouteAodv.class);\n /** debug mode. */\n public static final boolean DEBUG_MODE = true;\n}}}\n\nI have also redirected the standard debugging methods within such as {{{ printlndebug }}} etc to write to the logger instance\n{{{}}}\n{{{\n /////////////////////////////////////////////\n // DEBUG CODE\n //\n\n /**\n * Println given string with JiST time and local net address, if debug mode on.\n * \n * @param s string to print\n */ \n private void printlnDebug(String s)\n {\n if (RouteAodv.DEBUG_MODE)\n {\n logger.log(Priority.DEBUG, JistAPI.getTime()+"\st"+netAddr+": "+s);\n }\n }\n\n /**\n * Println given string with JiST time and given net address, if debug mode on.\n * \n * @param s string to print\n * @param addr node address\n */\n private static void printlnDebug(String s, NetAddress addr)\n {\n if (RouteAodv.DEBUG_MODE)\n { \n logger.log(Priority.DEBUG, JistAPI.getTime()+"\st"+addr+": "+s);\n //System.out.println(JistAPI.getTime()+"\st"+addr+": "+s);\n }\n }\n \n /**\n * Println given string only if debug mode on.\n * \n * @param s string to print\n */\n private static void printlnDebug_plain(String s)\n {\n if (RouteAodv.DEBUG_MODE)\n {\n logger.log(Priority.DEBUG,s);\n //System.out.println(s);\n }\n }\n}}}\n\nWe can then access this logger instance in our simulation file\n{{{}}}\n{{{\n//setup logging for aodv class\n Logger logger = Logger.getLogger(RouteAodv.class);\n File logDir = new File(directory); \n logger.setLevel(Level.DEBUG);\n \n Logger rootLogger = Logger.getRootLogger();\n rootLogger.removeAllAppenders();\n \n \n try {\n logDir.mkdir(); //check if directory exists\n \n File log = new File(directory+filename);\n boolean success = log.createNewFile(); //create the file\n \n if (!success) { //if create file fails\n throw new RuntimeException("Could not create file: "+directory+filename);\n }\n \n FileOutputStream fs = new FileOutputStream(log);\n //Enumeration appenders = logger.getAllAppenders();\n \n logger.addAppender(new WriterAppender(new PatternLayout(),fs));\n } catch (IOException e1) {\n // TODO Auto-generated catch block\n e1.printStackTrace();\n }\n}}}\n\nIn the above code sample I create a directory for the log files and create the log file itself, which I have named elsewhere. I then create a new {{{WriterAppender}}} which takes in a {{{FileStream}}} object to which I write any logs to.\n\nTo silence the 'root logger' to which Jist natively writes to the console, I remove all appenders on the rootLogger object. Once I've done this I don't get any logging on the console, and a nice log of all the AODV data in a file. And it seems there are very little overheads.\n\nThere is a great tutorial which covers all of the basics of logging [[here|]].\n\nNext step is to get trace file support like ns2 built in, use the log4j library
[[My Home|My Home]]\nJistSwans
Message queues in network interface hardware buffers are of a finite size.
The only current implementation of a queue in SWANS is {{{ NoDrop }}} which has the unfortunate effect of causing a simulation exception if the message queue has reached its capacity.\n\nA simple resolution is to insert a return statement instead of the exception where {{{size==capacity}}}, i.e.\n\n{{{\nif(size==capacity)\n { \n //throw new IndexOutOfBoundsException("list maximum exceeded");\n return;\n }\n}}}\n\nbut this does not inform the simulation environment that in essence the packet has been dropped intentionally, and should really be logged.
There are various mobility models in network simulators, all aimed at providing node movement.\n\nRandomWaypoint\n
The Network layer {{{NetInteface}}} / {{{NetIp}}} has the concept of an interfaceid, but unfortunately this hasn't been extended to the routing protocols etc. I've extended Jist so we are able to define multiple radios/MAC's per node (1-1 mapping of MAC onto radio), as well as implementing a channelNo in the RadioInfoUnique class so nodes on different interfaces can:\na) have different bandwidths\nb) set up a private channel\n\nRoute discovery through AODV now takes into account the interface RREQ's/RREP's were received on, and the RouteTableEntry has been extended to allow this information to be stored. Furthermore, RREQ broadcasts iterate over all interfaces a node has.\n\n
Welcome to my logbook! I'll be using this to write notes as I further develop my research and I hope will be somewhat legible if you are familar with Jist/SWANS etc. Any comments or questions please [[email me|]].
My PhD research is looking into the use of [[Game Theory|GameTheory]] and [[Human Immunology|HumanImmunology]] analogies to implement into an ad-hoc network to provide a multi-layered robust security system.
Defines the basic functionality a network layer should offer
Is a custom written (and very simple!) .NET based network simulator, which models the formation of '[[trust]]' between ad-hoc nodes. It's not been written with performance in mind! :)\n\nUsage:\n\n- Define a Simulation by instantiating a Simulation object.\n- Start Simulator with {{{StartSim(Simulation s)}}}\n- Step through Simulation using {{{ Simulator.StepTime()}}}
This is a list of the concepts I'm using in developing the solution to my research question, and ongoing developments to the Jist/SWANS simulation platform\n\nPromiscuousMode\nMessageQueue\nMobilityModels\nDropPacket
The implementation is incredibly simplistic - we simply 'return' from the send/recv methods where necessary
These are samplers that are given extra information when making a decision whether to sample or not
Two ray\n\nFree space\n\nShadowing
My blog:\n\nMy PhD personal webpage:
I've just profiled a UDP simulation with 36 nodes and the simulation spends most of its time garbage collecting, finally running out of memory and terminating prematurely. It's easy to increase the heap size from the default as a {{{jvmarg}}} within the 'run' target of your ant script, simply by adding the following:\n\n{{{\n<jvmarg value="-Xmx1024m"/>\n}}}\n\nIn Eclipse, you can add this to the VM arguments text box in your run configuration, under the Arguments tab.\n\nThis will increase the maximum heap size from the default 128mb to 1024mb. Obviously if you have more RAM then you could try allocating more to the JVM.
When simulating networks with greater than 10 nodes using a TCP transport/application layer I've noticed there are ocassions where the simulation hangs.\n\nUpon pausing a hung simulation in Eclipse (when nothing further is being written to a file logger I've got set up) it seems the simulation gets stuck in the TcpSocket.receiveData() method. I don't know the specific internals of TCP but it seemed when an out of order ACK was received by a node (with payload.size=0) it is added to the receiveBuffer for processing later. \n\nBUT, when that time comes to processing the out-of-order ACK it seems to get stuck in a while loop around the line 1886: \n\n{{{\nwhile ((tempMsg=rMsgBuffer.retrieve(rcv_nxt)) != null).\n}}}\n\nThis is because a few lines down {{{rcv_next}}} is incremented based on the payload size, which for an ACK is 0, so it infinitely loops.\n\nWhat i've done (and initial testing shows it doesnt seem to affect performance) is to only enqueue out-of-order DATA packets, by adding an if statement in the {{{TcpSocket.onReceiveValidDataorACK()}}} method between the line:\n\n{{{\nrMsgBuffer.insert (msg);\n}}}\n\nwhich now becomes:\n\n{{{\n// save message in out-of-order buffer (but still in window) -- PDK only buffer data packets\n if (msg.getPayload().getSize() > 0) {\n rMsgBuffer.insert (msg);\n }\n}}}
i.e. extending from the base {{{RouteAodv}}} class. It seems that the Jist rewriter adds an accessor method {{{_jistMethod_Set__ref}}} to each class, which is tagged as final so fails at the verfication as the base/derived classes have the same final method. \n \nI was able to get around it with a small tweak to, which doesnt seem to introduce any side-effects (though you might want to do additional testing just to make sure!). \n \n1. Navigate to method: {{{public ClassGen doClass(ClassGen cg)}}} in {{{}}} \n \n2. Remove the {{{ACC_FINAL}}} flag on the following line: \n \n{{{MethodGen mg = new MethodGen(fg.getAccessFlags() | Constants.ACC_FINAL, Type.VOID, \nnew Type[] { fg.getType() }, new String[] { "_x" }, \nRewriter.JIST_METHOD_SET+Rewriter.JIST_REF_SUFFIX, \ncg.getClassName(), il, cg.getConstantPool()); }}}\n \nSeems to do the job and I can now created derived classes from RouteAodv/NetIp.
If you've been following some of the other workarounds such as [[blocking issues with tcp simulations|Stopping Driver.TCP and Driver.UDP from blocking if your running Java > 1.4]] you'll know how necessary an ant build script is, in order to compile some of the distro at least to 1.4 bytecode for these simulations to work appropriately.\n\nNetbeans also uses ant files by default so you can easily use the same project you have set up in Eclipse within netbeans. Unfortunately, it doesnt give you the full run dialog experience as in Eclipse, so you have to create a run target in order to run a Jist/SWANS simulation, something like this:\n\n{{{\n<target name="run" depends="compile" description="Runner">\n \n <java classname="jist.runtime.Main">\n <arg value="jist.swans.Main"/>\n <arg value="driver.tcp"/>\n <classpath id="libs">\n <pathelement location="libs/bcel.jar"/> <!-- new -->\n <pathelement location="libs/log4j.jar"/>\n <pathelement location="libs/bsh.jar"/>\n <pathelement location="libs/checkstyle-all.jar"/>\n <pathelement location="libs/jargs.jar"/>\n <pathelement location="libs/jython.jar"/>\n <pathelement location="libs/opencsv-1.8.jar"/>\n <pathelement location="src"/>\n </classpath>\n </java>\n </target>\n}}}\n\nA useful feature in netbeans is the integrated profiler, which will let you profile memory, CPU and performance of a running simulation, great if you're getting out of memory exceptions or if the simulation is going slower than you expect. In order to use the profiler, we have to set up yet another build target, a profile target, which is virtually identical to the run target, with some added tasks. For the above {{{driver.tcp}}} example, something like this should do (see xml style comments for added lines)\n\n{{{\n<target name="profile" description="Profile Project">\n <nbprofiledirect> <!--required task for profiling-->\n <classpath id="libs">\n <pathelement location="libs/log4j.jar"/>\n <pathelement location="libs/bsh.jar"/>\n <pathelement location="libs/checkstyle-all.jar"/>\n <pathelement location="libs/jargs.jar"/>\n <pathelement location="libs/jython.jar"/>\n <pathelement location="libs/opencsv-1.8.jar"/>\n <pathelement location="src"/>\n </classpath>\n </nbprofiledirect>\n\n <java classname="jist.runtime.Main">\n <!--<arg value="-conf"/>\n <arg value="C:\sUsers\sPaul\sDocuments\sNetBeansProjects\sjist-swans-1.0.6-dev\ssrc\"/>-->\n <arg value="jist.swans.Main"/>\n <arg value="pkiddie.driver.tcp"/>\n <classpath id="libs">\n <pathelement location="libs/bcel.jar"/> <!-- new -->\n <!--<pathelement location="libs/bcel51.jar"/>--> <!-- old -->\n <pathelement location="libs/log4j.jar"/>\n <pathelement location="libs/bsh.jar"/>\n <pathelement location="libs/checkstyle-all.jar"/>\n <pathelement location="libs/jargs.jar"/>\n <pathelement location="libs/jython.jar"/>\n <pathelement location="libs/opencsv-1.8.jar"/>\n <pathelement location="src"/>\n </classpath>\n <jvmarg value="${}"/> <!-- required redirection for profiling -->\n </java>\n </target>\n}}}\nwhich will run the driver.tcp example in the Jist/SWANS distro under the profiler.
Promiscuous Mode is whereby a network adapter is able to overhear packets not destined to itself through transmissions from other nodes that are in range. Ad-hoc routing protocols like DSR [ref] use this to provide optimisations that are otherwise not possible
1. RreqOverflow table\n\n2. Hook AppIDS to receive all packets destined for network layer.\n\n3. Sample incoming packet type. If packet type = RREQ, either\na) Add node to RreqOverflow table\nb) If node already exists in RreqOverflow table, then increment the number of RREQs observed\n\n4. Reset RreqOverflow table every second
Defines the basic functionality a radio phy should offer
A mobility model whereby a waypoint is selected at random from within the bounds of the simulation. The node progresses to that waypoint and once it has reached that destination a new waypoint is computed. In SWANS, additional parameters can be set, including the speed of the node and pause-time, defined as the time which the node should pause at the waypoint before setting off to another.
If you, like me, need to read some configuration settings in from a file at driver runtime, then you may have run into an issue whereby using the standard {{{FileInputStream}}} or {{{FileReader}}} classes doesn't work, due to the way the Swans rewriter operates, consequentially there is no correct overload of the {{{BufferedReader}}} in the {{{}}} package that will allow you to it, which is the main way to getting line-by-line file reading support in your Java app.\n\nIn order to get this working, I completely bypass Jist by tagging a new class (with a {{{BufferedReader}}} instance within) with {{{JistAPI.DoNotRewrite}}}, like the following:\n\n{{{\npublic static class BufferedReader implements JistAPI.DoNotRewrite\n{\n private FileInputStream fstream ;\n private DataInputStream in; \n private br;\n \n public BufferedReader(String file) throws FileNotFoundException\n {\n \n fstream = new FileInputStream(file);\n \n in = new DataInputStream(fstream);\n br = new InputStreamReader(in));\n \n }\n \n public String readLine() throws IOException\n {\n return br.readLine();\n }\n \n public void close() throws IOException\n {\n br.close();\n }\n \n \n}\n}}}\n\nI can then create an instance whenever I need file handling functionality within my driver.
Recently I've been looking at the credibility of manet simulations with an aim to make any simulations I do with SWANS as 'realistic' as possible. This includes the following:\n\n1. An adequate [[mobility model|MobilityModels]] - is random waypoint sufficient? I see most ad-hoc networks being set up in a particular area and then moving to some kind of pattern that isn't random, perhaps along a path?\n\n2. [[Fading models|FadingModels]] - raleigh or rician fading? Raleigh fading is reputed to be better for modelling scenarios with non-line of sight.\n\n3. [[Pathloss models|PathlossModels]] - Two-ray, free-space or shadowing model? A free-space model is like simulating nodes on a flat place, or a "flat earth" with no interference and a perfect channel. Two ray models ground reflections in terms of inteference. The shadowing model takes us even further.\n\n4. [[Signal reception|SignalReception]] - based on a bit error rate or SNR threshold.\n\nTo my suprise, most of not all of these are within the latest 1.0.6 release of SWANS. See the [[SWANS++|SWANS++]] project for the shadowing pathloss extension.
{{{ns <tcl_file> 2>err.txt}}}\n\nThis will output any debug messages using {{{fprintf}}} to a file
Defines the basic contract of a routing protocol
I'm using Eclipse 3.4.0\n\n1. Right click on your project in the left hand Package Explorer pane\n2. Click Run As -> Run Configurations\n3. Click 'new launch configuration' on top left of Run panel that pops up\n4. In Main class textbox, type: {{{ jist.runtime.Main }}}\n5. Now we need to provide the arguments. Lets say we want to run {{{}}} in the driver package\n6. Select the arguments tab, and enter {{{jist.swans.Main driver.udp}}} into the program arguments box.\n7. Go into the Classpath tab, click Advanced and Add Folder. Then add the {{{src}}} folder within your project (important if you are using the ant builder xml file in [[Stopping Driver.TCP and Driver.UDP from blocking if your running Java > 1.4]].\n7. Press Run to run the simulation. This launch configuration will be stored in your workspace so you only have to do this once.\n\nYou can also debug SWANS simulations easily by placing breakpoints and debugging, using the launch config you just created above.\n\nbtw, this seems a bit fiddly but it ensures that the networking code is non-blocking through the use of the SWANS rewriter
This is a set of extensions and bug fixes to the latest version of the [[Jist/SWANS wireless network simulator|]]. It includes visualisation tools for [[VANET]] as well as various small bug fixes centered around the routing agents SWANS provides including [[DSR]] and [[AODV]]\n\nInteresting additions in the [[changelog|swansppchangelog]] from my perspective include:\n- Addition of a VANET visualiser, which I hope to modify into a simple ad-hoc simulator to run real time simulations\n- Allow pausing of simulator - perfect for UI\n- NS2 style timers. These are more functional than existing timers and allow us to reschedule said timer: applicability to AODV route expirations, not currently part of the AODV implementation in JIST\n- PacketDropped events are now registered with the higher levels of the OSI stack\n- 802.11 implementation more robust and undefined states have been declared\n- Serialization of objects to persistant storage -- need to check this out (in\n- Planned future support in multi-channel communications\n
1. Node broadcasting a RREQ: as per the specification the RREQ's originator sequence number is incremented, and the routing table entry to self is updated to reflect this as well. In SWANS++, some additional error checking code? is in place to ensure a node always has a routing table entry to itself through looking up an entry that has the nodes own IP address.\n\n2. RREQ timeouts: instead of checking the rreq's own routeFound property, when a particular RREQ times out, the nodes routing table is checked for an entry that matches the destination IP in the RREQ. If the entry returned is null, or the nextHop's MAC address is null, then we queue another RREQ with a bigger TTL (expanding ring search) until the TTL_THRESHOLD\n\n3. packetDropped events registered from MAC/Networking layer: packet dropped method now exists in both {{{ }}} and {{{ }}}, so packet dropped events can be registered in trace files
These are simple sampling strategies which require no further information to make a decision on sampling
Currently implemented Sampling strategies in [[NetSampler]]\n\n[[Sampler]]:\n- ConstantRate\n- [[Random]]\n\n[[ParameterizedSampler]]:\n- ExponentialBackOff\n- NeighbourhoodAware\n- TitForTat\n- TrustBased\n
I got to admit, this wasnt made immediately clear in JIST. The {{{ callStaticAt }}} method of the JistAPI static class is responsible for this.\n\nFor example:\n\n{{{\nJistAPI.callStaticAt(method_writeColor, \n new Object[] { new Integer(node), \n new String(color)}, time*Constants.SECOND);\n}}}\n\nI've wrapped this in a function, {{{changeNodeColourAt(int node, String color, long time)}}} which makes it really easy to call within my simulation script. The above callStaticAt just tells Jist to call my method writeColour at a time of {{{time*Constants.SECOND}}} where the new Object[] is simply an array holding the arguments that the writeColour method takes\n\ndefinition of writeColour:\n\n{{{\npublic synchronized static void writeColor(int node, String color)\n {\n //n -t 130 -s 2 -S COLOR -c black -o red -i black -I red\n //-i <color> inside label color \n //-I <color> previous inside label color \n //-c <color> color \n //-o <color> previous color\n\n try {\n m_writer.write("n -t " + JistAPI.getTime()/(float)Constants.SECOND\n + " -s " + node + \n " -S COLOR -c " + color + " -i " + color);\n m_writer.newLine();\n } catch (IOException e) {\n // TODO Auto-generated catch block\n e.printStackTrace();\n }\n }\n}}}
Ad-hoc networking research, experiences with Jist/SWANS and other network simualators
Paul Kiddie
In order to detect spoofing, we need to allow some MAC-Network layer communication, as one of the steps we take is to store a MAC-IP pair for a given node, and in the case of the {{Mac_80211}} MAC, we also store the latest sequence number, for further verification
Although not particularly practical, for the purpose of explicitly scripting a simulation, it seemed a good idea to define radio topologies, in terms of what next-hop radios can communicate with one another, without having to worry about getting nodes in exactly the right location. I've overriden some functionality in RadioInfoShared to define a new boolean called UseStaticRouting. Then in the simulation, for each Radio object, we can define a list of links:\n\n{{{\n\nAddStaticLinks((RadioNoise)nodes.get(1).getRadios().get(0), //get interface 0 of node 1 and add links to radios on nodes 2,3 and 4\n new Integer[] {2,3,4});\n \nAddStaticLinks((RadioNoise)nodes.get(1).getRadios().get(1), //get interface 1 of node 2 and add links to 2nd radio on node 7 (Radio=17,Mac=17)\n new Integer[] {7+10});\n \n \nAddStaticLinks((RadioNoise)nodes.get(2).getRadios().get(0),\n new Integer[] {1,3,5});\n \n \nAddStaticLinks((RadioNoise)nodes.get(3).getRadios().get(0),\n new Integer[] {1,2,4,5});\n \n \nAddStaticLinks((RadioNoise)nodes.get(4).getRadios().get(0),\n new Integer[] {1,3,5,6});\n \n \nAddStaticLinks((RadioNoise)nodes.get(5).getRadios().get(0),\n new Integer[] {2,3,4,6});\n \n \nAddStaticLinks((RadioNoise)nodes.get(6).getRadios().get(0),\n new Integer[] {4,5,7});\n \n \nAddStaticLinks((RadioNoise)nodes.get(7).getRadios().get(0),\n new Integer[] {6});\n \n \nAddStaticLinks((RadioNoise)nodes.get(7).getRadios().get(1),\n new Integer[] {1+10}); \n}}}\n\nHere we have 7 nodes, and nodes 1 and 7 have two radios and thus two MACs but one logical address. The MAC addresses for the 2nd radio are 10+n where n = node number. The 1st and 2nd radio are segregated by a different 802.11 channel number
One of the advantages of adopting Jist/SWANS is the use of standard Java networking code, which during the rewriting process Jist/SWANS converts into the Jist/SWANS equivalents. Unfortunately, if you are running Java 1.5 and building the distribution out of the box using Eclipse, you may have noticed that {{{Driver.TCP}}} and {{{Driver.UDP}}} (in fact anything that uses rewritten networking method that blocks) blocks where it shouldnt! \n\nJist/SWANS was developed for Java 1.4 and thus the rewriting engine also is meant for 1.4. The format of the compiled .class file differs between 1.4 and 1.5 and I believe this is the source of the problem (You can verify this by compiling the distribution in {{{-source 1.4}}} and running {{{javap}}} on an offending class ({{{ServerSocket,Socket,UdpSocket}}}), and then recompiling in {{{-source 1.5}}} and doing the same)\n\nSo what i've done is created an ant build file which I use as my builder in Eclipse, which:\na) compiles the whole distribution in source 1.5, \nb) uses the 'touch' command on three offending files in the {{{}}} package, and compiles these as source 1.4\n\n{{{\n<?xml version="1.0" encoding="UTF-8"?>\n<!-- ====================================================================== \n 19 May 2008 13:29:39 \n\n project \n description\n \n ====================================================================== -->\n<project name="project" default="compile">\n <description>\n description\n </description>\n\n <!-- ================================= \n target: default \n ================================= -->\n <target name="compile">\n <javac srcdir="src/jist/runtime" debug="true" source="1.5">\n <classpath id="libs">\n <pathelement location="libs/bcel.jar"/> <!-- new -->\n <!--<pathelement location="libs/bcel51.jar"/>--> <!-- old -->\n <pathelement location="libs/log4j.jar"/> \n <pathelement location="libs/bsh.jar"/>\n <pathelement location="libs/checkstyle-all.jar"/>\n <pathelement location="libs/jargs.jar"/>\n <pathelement location="libs/jython.jar"/>\n <pathelement location="src"/>\n </classpath>\n </javac>\n <javac srcdir="src/jist/swans" debug="true" source="1.5">\n <classpath refid="libs">\n </classpath>\n </javac>\n <javac srcdir="src/jist/minisim" debug="true" source="1.5">\n <classpath refid="libs">\n </classpath>\n </javac>\n <javac srcdir="src/driver" debug="true" source="1.5">\n <classpath refid="libs" >\n </classpath>\n </javac>\n \n <touch file="src/swans/app/net/"></touch>\n <touch file="src/swans/app/net/"></touch>\n <touch file="src/swans/app/net/"></touch>\n <javac srcdir="src/swans/app/net" debug="true" source="1.4" >\n <classpath refid="libs">\n </classpath>\n </javac>\n \n \n <rmic base="src" classname="jist.runtime.Controller">\n <classpath refid="libs"></classpath>\n </rmic>\n <rmic base="src" classname="jist.runtime.RemoteIO.RemoteInputStreamSender">\n <classpath refid="libs"></classpath>\n </rmic>\n <rmic base="src" classname="jist.runtime.RemoteIO.RemoteOutputStreamReceiver">\n <classpath refid="libs"></classpath>\n </rmic>\n <rmic base="src" classname="jist.runtime.RemoteJist.Ping">\n <classpath refid="libs"></classpath>\n </rmic>\n <rmic base="src" classname="jist.runtime.RemoteJist.JistClient">\n <classpath refid="libs"></classpath>\n </rmic>\n <rmic base="src" classname="jist.runtime.RemoteJist.JobQueueServer">\n <classpath refid="libs"></classpath>\n </rmic>\n </target>\n <target name="clean">\n <delete>\n <fileset dir="." includes="**/*.class"/>\n </delete>\n </target>\n \n\n</project>\n}}}\n\nYou might have noticed {{{compilerarg value="-g:lines,source"}}} in the ant build file above. This deals with problems that arise if you use generics (like generic lists etc) in Java 1.5 which *may* cause a spurious rewriter error. A side effect of this is that it prevents you from debugging local variables. You can still debug arguments to a method, but they will be called {{{arg0,...n}}} depending on the number of arguments to that function.\n\nYou then need to make modifications to the launch configuration in order to ensure the non-blocking equivalents of the networking code is used:\n\n[[Running/debugging a SWANS simulation in Eclipse]]
Subclipse lets you browse and check out Subversion repositories from within the Eclipse IDE. Its relatively easy to set up and I found the following links really helpful:\n\n[[installing subversion, setting up a subversion server and preparing a repository|]] from UnrealWiki.\n[[using repository from within Eclipse|]] from Addison Wesley\n\nNote that when you install Subclipse, uncheck the Mylar integration plugin, as otherwise you will be unable to install Subclipse.
Though not supported natively, there have been a couple of research efforts looking at implementing this. The one I've based my tracing on is called [[Xtend-SWANS|]] which is based on some earlier work called [[JavisTrace|]].
I am using Unit Tests as a way of testing the individual components of a functional unit within [[NetSampler]]. I have chosen [[MbUnit|http://]] as it is based upon, and extends, the standard which is NUnit.\n\nI'm also making use of [[ReSharper|]] which amongst other things lets you run tests within Visual Studio 2005, with the use of an additional plug-in [[MbUnit plugin for ReSharper|]]
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |\n| 13/2/2007 12:23:24 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 13/2/2007 12:24:29 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 13/2/2007 12:25:25 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 13/2/2007 12:30:41 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 13/2/2007 12:30:49 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 13/2/2007 12:36:41 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 13/2/2007 12:49:42 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 13/2/2007 12:50:40 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 13/2/2007 12:56:40 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 13/2/2007 12:58:23 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 13/2/2007 12:58:49 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 13/2/2007 13:3:45 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 13/2/2007 13:9:47 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 16/2/2007 13:15:28 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 16/2/2007 13:21:16 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 16/2/2007 13:22:41 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 16/2/2007 13:44:41 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 20/2/2007 15:17:37 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 20/2/2007 15:21:39 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 20/2/2007 15:22:22 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 20/2/2007 16:35:5 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 20/2/2007 16:36:53 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 20/2/2007 16:38:59 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 20/2/2007 16:42:57 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 20/2/2007 16:45:52 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 20/2/2007 16:46:39 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 20/2/2007 16:53:56 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 20/2/2007 17:4:29 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 20/2/2007 17:4:51 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 22/2/2007 21:17:3 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 28/2/2007 15:25:23 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 28/2/2007 15:25:57 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 28/2/2007 15:32:36 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 28/2/2007 18:0:56 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 19/4/2007 12:22:46 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 19/4/2007 12:23:33 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 19/4/2007 15:35:47 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 19/4/2007 16:39:38 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 1/5/2007 10:59:14 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 1/5/2007 11:18:29 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 1/5/2007 11:35:8 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 8/6/2007 15:36:34 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 8/6/2007 15:37:49 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 5/7/2007 17:7:23 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 30/7/2007 15:10:16 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 30/7/2007 15:13:3 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 30/7/2007 15:19:51 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 30/7/2007 15:21:17 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 20/11/2007 13:39:21 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 20/11/2007 13:57:37 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 20/11/2007 13:58:4 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 20/11/2007 15:47:33 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 26/11/2007 10:52:4 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 26/11/2007 12:55:2 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 17/12/2007 11:58:19 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 17/12/2007 12:19:31 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 17/12/2007 12:23:8 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 17/12/2007 12:40:1 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 17/12/2007 12:54:52 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 17/12/2007 13:0:53 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 25/1/2008 12:36:20 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 25/1/2008 12:38:24 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 25/1/2008 12:39:56 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 25/1/2008 12:51:20 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 25/1/2008 13:9:18 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 25/1/2008 13:12:3 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 29/1/2008 16:48:44 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 31/1/2008 15:28:5 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 31/1/2008 15:39:33 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 3/9/2008 11:10:53 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 3/9/2008 11:16:54 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 3/9/2008 11:18:46 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 3/9/2008 11:23:0 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 3/9/2008 11:24:33 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 3/9/2008 11:26:17 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 3/9/2008 11:29:2 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 3/9/2008 11:31:4 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 3/9/2008 11:42:58 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 3/9/2008 11:56:7 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 3/9/2008 11:56:47 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 3/9/2008 11:57:31 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 3/9/2008 11:59:18 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 3/9/2008 12:53:20 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 3/9/2008 13:0:24 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 3/9/2008 13:4:44 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 3/9/2008 15:22:25 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 28/1/2009 16:38:55 | YourName | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 28/1/2009 16:40:56 | YourName | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 28/1/2009 16:46:22 | YourName | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 28/1/2009 16:49:15 | YourName | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 28/1/2009 17:1:54 | YourName | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 28/1/2009 17:5:15 | YourName | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 18/2/2009 10:22:1 | YourName | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 18/2/2009 11:46:11 | YourName | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 18/2/2009 17:7:19 | YourName | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 26/2/2009 12:7:9 | YourName | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 26/2/2009 12:9:4 | YourName | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 3/3/2009 17:12:39 | YourName | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 3/3/2009 17:40:19 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |\n| 31/7/2009 15:16:1 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . | Ok |\n| 31/7/2009 15:16:29 | Paul | [[/|]] | [[store.cgi|]] | . | index.html | . |
/***\n|''Name:''|UploadPlugin|\n|''Description:''|Save to web a TiddlyWiki|\n|''Version:''|3.4.4|\n|''Date:''|Sep 30, 2006|\n|''Source:''||\n|''Documentation:''||\n|''Author:''|BidiX (BidiX (at) bidix (dot) info)|\n|''License:''|[[BSD open source license| ]]|\n|''~CoreVersion:''|2.0.0|\n|''Browser:''|Firefox 1.5; InternetExplorer 6.0; Safari|\n|''Include:''|config.lib.file; config.lib.log; config.lib.options; PasswordTweak|\n|''Require:''|[[UploadService|]]|\n***/\n//{{{\nversion.extensions.UploadPlugin = {\n major: 3, minor: 4, revision: 4, \n date: new Date(2006,8,30),\n source: '',\n documentation: '',\n author: 'BidiX (BidiX (at) bidix (dot) info',\n license: '[[BSD open source license|]]',\n coreVersion: '2.0.0',\n browser: 'Firefox 1.5; InternetExplorer 6.0; Safari'\n};\n//}}}\n\n////+++!![config.lib.file]\n\n//{{{\nif (!config.lib) config.lib = {};\nif (!config.lib.file) config.lib.file= {\n author: 'BidiX',\n version: {major: 0, minor: 1, revision: 0}, \n date: new Date(2006,3,9)\n};\nconfig.lib.file.dirname = function (filePath) {\n var lastpos;\n if ((lastpos = filePath.lastIndexOf("/")) != -1) {\n return filePath.substring(0, lastpos);\n } else {\n return filePath.substring(0, filePath.lastIndexOf("\s\s"));\n }\n};\nconfig.lib.file.basename = function (filePath) {\n var lastpos;\n if ((lastpos = filePath.lastIndexOf("#")) != -1) \n filePath = filePath.substring(0, lastpos);\n if ((lastpos = filePath.lastIndexOf("/")) != -1) {\n return filePath.substring(lastpos + 1);\n } else\n return filePath.substring(filePath.lastIndexOf("\s\s")+1);\n};\nwindow.basename = function() {return "@@deprecated@@";};\n//}}}\n////===\n\n////+++!![config.lib.log]\n\n//{{{\nif (!config.lib) config.lib = {};\nif (!config.lib.log) config.lib.log= {\n author: 'BidiX',\n version: {major: 0, minor: 1, revision: 1}, \n date: new Date(2006,8,19)\n};\nconfig.lib.Log = function(tiddlerTitle, logHeader) {\n if (version.major < 2)\n this.tiddler = store.tiddlers[tiddlerTitle];\n else\n this.tiddler = store.getTiddler(tiddlerTitle);\n if (!this.tiddler) {\n this.tiddler = new Tiddler();\n this.tiddler.title = tiddlerTitle;\n this.tiddler.text = "| !date | !user | !location |" + logHeader;\n this.tiddler.created = new Date();\n this.tiddler.modifier = config.options.txtUserName;\n this.tiddler.modified = new Date();\n if (version.major < 2)\n store.tiddlers[tiddlerTitle] = this.tiddler;\n else\n store.addTiddler(this.tiddler);\n }\n return this;\n};\n\nconfig.lib.Log.prototype.newLine = function (line) {\n var now = new Date();\n var newText = "| ";\n newText += now.getDate()+"/"+(now.getMonth()+1)+"/"+now.getFullYear() + " ";\n newText += now.getHours()+":"+now.getMinutes()+":"+now.getSeconds()+" | ";\n newText += config.options.txtUserName + " | ";\n var location = document.location.toString();\n var filename = config.lib.file.basename(location);\n if (!filename) filename = '/';\n newText += "[["+filename+"|"+location + "]] |";\n this.tiddler.text = this.tiddler.text + "\sn" + newText;\n this.addToLine(line);\n};\n\nconfig.lib.Log.prototype.addToLine = function (text) {\n this.tiddler.text = this.tiddler.text + text;\n this.tiddler.modifier = config.options.txtUserName;\n this.tiddler.modified = new Date();\n if (version.major < 2)\n store.tiddlers[this.tiddler.tittle] = this.tiddler;\n else {\n store.addTiddler(this.tiddler);\n story.refreshTiddler(this.tiddler.title);\n store.notify(this.tiddler.title, true);\n }\n if (version.major < 2)\n store.notifyAll(); \n};\n//}}}\n////===\n\n////+++!![config.lib.options]\n\n//{{{\nif (!config.lib) config.lib = {};\nif (!config.lib.options) config.lib.options = {\n author: 'BidiX',\n version: {major: 0, minor: 1, revision: 0}, \n date: new Date(2006,3,9)\n};\n\nconfig.lib.options.init = function (name, defaultValue) {\n if (!config.options[name]) {\n config.options[name] = defaultValue;\n saveOptionCookie(name);\n }\n};\n//}}}\n////===\n\n////+++!![PasswordTweak]\n\n//{{{\nversion.extensions.PasswordTweak = {\n major: 1, minor: 0, revision: 3, date: new Date(2006,8,30),\n type: 'tweak',\n source: ''\n};\n//}}}\n/***\n!!config.macros.option\n***/\n//{{{\nconfig.macros.option.passwordCheckboxLabel = "Save this password on this computer";\nconfig.macros.option.passwordType = "password"; // password | text\n\nconfig.macros.option.onChangeOption = function(e)\n{\n var opt = this.getAttribute("option");\n var elementType,valueField;\n if(opt) {\n switch(opt.substr(0,3)) {\n case "txt":\n elementType = "input";\n valueField = "value";\n break;\n case "pas":\n elementType = "input";\n valueField = "value";\n break;\n case "chk":\n elementType = "input";\n valueField = "checked";\n break;\n }\n config.options[opt] = this[valueField];\n saveOptionCookie(opt);\n var nodes = document.getElementsByTagName(elementType);\n for(var t=0; t<nodes.length; t++) \n {\n var optNode = nodes[t].getAttribute("option");\n if (opt == optNode) \n nodes[t][valueField] = this[valueField];\n }\n }\n return(true);\n};\n\nconfig.macros.option.handler = function(place,macroName,params)\n{\n var opt = params[0];\n if(config.options[opt] === undefined) {\n return;}\n var c;\n switch(opt.substr(0,3)) {\n case "txt":\n c = document.createElement("input");\n c.onkeyup = this.onChangeOption;\n c.setAttribute ("option",opt);\n c.className = "txtOptionInput "+opt;\n place.appendChild(c);\n c.value = config.options[opt];\n break;\n case "pas":\n // input password\n c = document.createElement ("input");\n c.setAttribute("type",config.macros.option.passwordType);\n c.onkeyup = this.onChangeOption;\n c.setAttribute("option",opt);\n c.className = "pasOptionInput "+opt;\n place.appendChild(c);\n c.value = config.options[opt];\n // checkbox link with this password "save this password on this computer"\n c = document.createElement("input");\n c.setAttribute("type","checkbox");\n c.onclick = this.onChangeOption;\n c.setAttribute("option","chk"+opt);\n c.className = "chkOptionInput "+opt;\n place.appendChild(c);\n c.checked = config.options["chk"+opt];\n // text savePasswordCheckboxLabel\n place.appendChild(document.createTextNode(config.macros.option.passwordCheckboxLabel));\n break;\n case "chk":\n c = document.createElement("input");\n c.setAttribute("type","checkbox");\n c.onclick = this.onChangeOption;\n c.setAttribute("option",opt);\n c.className = "chkOptionInput "+opt;\n place.appendChild(c);\n c.checked = config.options[opt];\n break;\n }\n};\n//}}}\n/***\n!! Option cookie stuff\n***/\n//{{{\nwindow.loadOptionsCookie_orig_PasswordTweak = window.loadOptionsCookie;\nwindow.loadOptionsCookie = function()\n{\n var cookies = document.cookie.split(";");\n for(var c=0; c<cookies.length; c++) {\n var p = cookies[c].indexOf("=");\n if(p != -1) {\n var name = cookies[c].substr(0,p).trim();\n var value = cookies[c].substr(p+1).trim();\n switch(name.substr(0,3)) {\n case "txt":\n config.options[name] = unescape(value);\n break;\n case "pas":\n config.options[name] = unescape(value);\n break;\n case "chk":\n config.options[name] = value == "true";\n break;\n }\n }\n }\n};\n\nwindow.saveOptionCookie_orig_PasswordTweak = window.saveOptionCookie;\nwindow.saveOptionCookie = function(name)\n{\n var c = name + "=";\n switch(name.substr(0,3)) {\n case "txt":\n c += escape(config.options[name].toString());\n break;\n case "chk":\n c += config.options[name] ? "true" : "false";\n // is there an option link with this chk ?\n if (config.options[name.substr(3)]) {\n saveOptionCookie(name.substr(3));\n }\n break;\n case "pas":\n if (config.options["chk"+name]) {\n c += escape(config.options[name].toString());\n } else {\n c += "";\n }\n break;\n }\n c += "; expires=Fri, 1 Jan 2038 12:00:00 UTC; path=/";\n document.cookie = c;\n};\n//}}}\n/***\n!! Initializations\n***/\n//{{{\n// define config.options.pasPassword\nif (!config.options.pasPassword) {\n config.options.pasPassword = 'defaultPassword';\n window.saveOptionCookie('pasPassword');\n}\n// since loadCookies is first called befor password definition\n// we need to reload cookies\nwindow.loadOptionsCookie();\n//}}}\n////===\n\n////+++!![config.macros.upload]\n\n//{{{\nconfig.macros.upload = {\n accessKey: "U",\n formName: "UploadPlugin",\n contentType: "text/html;charset=UTF-8",\n defaultStoreScript: "store.php"\n};\n\n// only this two configs need to be translated\nconfig.macros.upload.messages = {\n aboutToUpload: "About to upload TiddlyWiki to %0",\n backupFileStored: "Previous file backuped in %0",\n crossDomain: "Certainly a cross-domain isue: access to an other site isn't allowed",\n errorDownloading: "Error downloading",\n errorUploadingContent: "Error uploading content",\n fileLocked: "Files is locked: You are not allowed to Upload",\n fileNotFound: "file to upload not found",\n fileNotUploaded: "File %0 NOT uploaded",\n mainFileUploaded: "Main TiddlyWiki file uploaded to %0",\n passwordEmpty: "Unable to upload, your password is empty",\n urlParamMissing: "url param missing",\n rssFileNotUploaded: "RssFile %0 NOT uploaded",\n rssFileUploaded: "Rss File uploaded to %0"\n};\n\nconfig.macros.upload.label = {\n promptOption: "Save and Upload this TiddlyWiki with UploadOptions",\n promptParamMacro: "Save and Upload this TiddlyWiki in %0",\n saveLabel: "save to web", \n saveToDisk: "save to disk",\n uploadLabel: "upload" \n};\n\nconfig.macros.upload.handler = function(place,macroName,params){\n // parameters initialization\n var storeUrl = params[0];\n var toFilename = params[1];\n var backupDir = params[2];\n var uploadDir = params[3];\n var username = params[4];\n var password; // for security reason no password as macro parameter\n var label;\n if (document.location.toString().substr(0,4) == "http")\n label = this.label.saveLabel;\n else\n label = this.label.uploadLabel;\n var prompt;\n if (storeUrl) {\n prompt = this.label.promptParamMacro.toString().format([this.toDirUrl(storeUrl, uploadDir, username)]);\n }\n else {\n prompt = this.label.promptOption;\n }\n createTiddlyButton(place, label, prompt, \n function () {\n config.macros.upload.upload(storeUrl, toFilename, uploadDir, backupDir, username, password); \n return false;}, \n null, null, this.accessKey);\n};\nconfig.macros.upload.UploadLog = function() {\n return new config.lib.Log('UploadLog', " !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |" );\n};\nconfig.macros.upload.UploadLog.prototype = config.lib.Log.prototype;\nconfig.macros.upload.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir, backupDir) {\n var line = " [[" + config.lib.file.basename(storeUrl) + "|" + storeUrl + "]] | ";\n line += uploadDir + " | " + toFilename + " | " + backupDir + " |";\n this.newLine(line);\n};\nconfig.macros.upload.UploadLog.prototype.endUpload = function() {\n this.addToLine(" Ok |");\n};\nconfig.macros.upload.basename = config.lib.file.basename;\nconfig.macros.upload.dirname = config.lib.file.dirname;\nconfig.macros.upload.toRootUrl = function (storeUrl, username)\n{\n return root = (this.dirname(storeUrl)?this.dirname(storeUrl):this.dirname(document.location.toString()));\n}\nconfig.macros.upload.toDirUrl = function (storeUrl, uploadDir, username)\n{\n var root = this.toRootUrl(storeUrl, username);\n if (uploadDir && uploadDir != '.')\n root = root + '/' + uploadDir;\n return root;\n}\nconfig.macros.upload.toFileUrl = function (storeUrl, toFilename, uploadDir, username)\n{\n return this.toDirUrl(storeUrl, uploadDir, username) + '/' + toFilename;\n}\nconfig.macros.upload.upload = function(storeUrl, toFilename, uploadDir, backupDir, username, password)\n{\n // parameters initialization\n storeUrl = (storeUrl ? storeUrl : config.options.txtUploadStoreUrl);\n toFilename = (toFilename ? toFilename : config.options.txtUploadFilename);\n backupDir = (backupDir ? backupDir : config.options.txtUploadBackupDir);\n uploadDir = (uploadDir ? uploadDir : config.options.txtUploadDir);\n username = (username ? username : config.options.txtUploadUserName);\n password = config.options.pasUploadPassword; // for security reason no password as macro parameter\n if (!password || password === '') {\n alert(config.macros.upload.messages.passwordEmpty);\n return;\n }\n if (storeUrl === '') {\n storeUrl = config.macros.upload.defaultStoreScript;\n }\n if (config.lib.file.dirname(storeUrl) === '') {\n storeUrl = config.lib.file.dirname(document.location.toString())+'/'+storeUrl;\n }\n if (toFilename === '') {\n toFilename = config.lib.file.basename(document.location.toString());\n }\n\n clearMessage();\n // only for forcing the message to display\n if (version.major < 2)\n store.notifyAll();\n if (!storeUrl) {\n alert(config.macros.upload.messages.urlParamMissing);\n return;\n }\n // Check that file is not locked\n if (window.BidiX && BidiX.GroupAuthoring && BidiX.GroupAuthoring.lock) {\n if (BidiX.GroupAuthoring.lock.isLocked() && !BidiX.GroupAuthoring.lock.isMyLock()) {\n alert(config.macros.upload.messages.fileLocked);\n return;\n }\n }\n \n var log = new this.UploadLog();\n log.startUpload(storeUrl, toFilename, uploadDir, backupDir);\n if (document.location.toString().substr(0,5) == "file:") {\n saveChanges();\n }\n var toDir = config.macros.upload.toDirUrl(storeUrl, toFilename, uploadDir, username);\n displayMessage(config.macros.upload.messages.aboutToUpload.format([toDir]), toDir);\n this.uploadChanges(storeUrl, toFilename, uploadDir, backupDir, username, password);\n if(config.options.chkGenerateAnRssFeed) {\n //var rssContent = convertUnicodeToUTF8(generateRss());\n var rssContent = generateRss();\n var rssPath = toFilename.substr(0,toFilename.lastIndexOf(".")) + ".xml";\n this.uploadContent(rssContent, storeUrl, rssPath, uploadDir, '', username, password, \n function (responseText) {\n if (responseText.substring(0,1) != '0') {\n displayMessage(config.macros.upload.messages.rssFileNotUploaded.format([rssPath]));\n }\n else {\n var toFileUrl = config.macros.upload.toFileUrl(storeUrl, rssPath, uploadDir, username);\n displayMessage(config.macros.upload.messages.rssFileUploaded.format(\n [toFileUrl]), toFileUrl);\n }\n // for debugging store.php uncomment last line\n //DEBUG alert(responseText);\n });\n }\n return;\n};\n\nconfig.macros.upload.uploadChanges = function(storeUrl, toFilename, uploadDir, backupDir, \n username, password) {\n var original;\n if (document.location.toString().substr(0,4) == "http") {\n original =, toFilename, uploadDir, backupDir, username, password);\n return;\n }\n else {\n // standard way : Local file\n \n original = loadFile(getLocalPath(document.location.toString()));\n if(window.Components) {\n // it's a mozilla browser\n try {\n"UniversalXPConnect");\n var converter = Components.classes[""]\n .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);\n converter.charset = "UTF-8";\n original = converter.ConvertToUnicode(original);\n }\n catch(e) {\n }\n }\n }\n //DEBUG alert(original);\n this.uploadChangesFrom(original, storeUrl, toFilename, uploadDir, backupDir, \n username, password);\n};\n\nconfig.macros.upload.uploadChangesFrom = function(original, storeUrl, toFilename, uploadDir, backupDir, \n username, password) {\n var startSaveArea = '<div id="' + 'storeArea">'; // Split up into two so that indexOf() of this source doesn't find it\n var endSaveArea = '</d' + 'iv>';\n // Locate the storeArea div's\n var posOpeningDiv = original.indexOf(startSaveArea);\n var posClosingDiv = original.lastIndexOf(endSaveArea);\n if((posOpeningDiv == -1) || (posClosingDiv == -1))\n {\n alert(config.messages.invalidFileError.format([document.location.toString()]));\n return;\n }\n var revised = original.substr(0,posOpeningDiv + startSaveArea.length) + \n allTiddlersAsHtml() + "\sn\st\st" +\n original.substr(posClosingDiv);\n var newSiteTitle;\n if(version.major < 2){\n newSiteTitle = (getElementText("siteTitle") + " - " + getElementText("siteSubtitle")).htmlEncode();\n } else {\n newSiteTitle = (wikifyPlain ("SiteTitle") + " - " + wikifyPlain ("SiteSubtitle")).htmlEncode();\n }\n\n revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");\n revised = revised.replaceChunk("<!--PRE-HEAD-START--"+">","<!--PRE-HEAD-END--"+">","\sn" + store.getTiddlerText("MarkupPreHead","") + "\sn");\n revised = revised.replaceChunk("<!--POST-HEAD-START--"+">","<!--POST-HEAD-END--"+">","\sn" + store.getTiddlerText("MarkupPostHead","") + "\sn");\n revised = revised.replaceChunk("<!--PRE-BODY-START--"+">","<!--PRE-BODY-END--"+">","\sn" + store.getTiddlerText("MarkupPreBody","") + "\sn");\n revised = revised.replaceChunk("<!--POST-BODY-START--"+">","<!--POST-BODY-END--"+">","\sn" + store.getTiddlerText("MarkupPostBody","") + "\sn");\n\n var response = this.uploadContent(revised, storeUrl, toFilename, uploadDir, backupDir, \n username, password, function (responseText) {\n if (responseText.substring(0,1) != '0') {\n alert(responseText);\n displayMessage(config.macros.upload.messages.fileNotUploaded.format([getLocalPath(document.location.toString())]));\n }\n else {\n if (uploadDir !== '') {\n toFilename = uploadDir + "/" + config.macros.upload.basename(toFilename);\n } else {\n toFilename = config.macros.upload.basename(toFilename);\n }\n var toFileUrl = config.macros.upload.toFileUrl(storeUrl, toFilename, uploadDir, username);\n if (responseText.indexOf("destfile:") > 0) {\n var destfile = responseText.substring(responseText.indexOf("destfile:")+9, \n responseText.indexOf("\sn", responseText.indexOf("destfile:")));\n toFileUrl = config.macros.upload.toRootUrl(storeUrl, username) + '/' + destfile;\n }\n else {\n toFileUrl = config.macros.upload.toFileUrl(storeUrl, toFilename, uploadDir, username);\n }\n displayMessage(config.macros.upload.messages.mainFileUploaded.format(\n [toFileUrl]), toFileUrl);\n if (backupDir && responseText.indexOf("backupfile:") > 0) {\n var backupFile = responseText.substring(responseText.indexOf("backupfile:")+11, \n responseText.indexOf("\sn", responseText.indexOf("backupfile:")));\n toBackupUrl = config.macros.upload.toRootUrl(storeUrl, username) + '/' + backupFile;\n displayMessage(config.macros.upload.messages.backupFileStored.format(\n [toBackupUrl]), toBackupUrl);\n }\n var log = new config.macros.upload.UploadLog();\n log.endUpload();\n store.setDirty(false);\n // erase local lock\n if (window.BidiX && BidiX.GroupAuthoring && BidiX.GroupAuthoring.lock) {\n BidiX.GroupAuthoring.lock.eraseLock();\n // change mtime with new mtime after upload\n var mtime = responseText.substr(responseText.indexOf("mtime:")+6);\n BidiX.GroupAuthoring.lock.mtime = mtime;\n }\n \n \n }\n // for debugging store.php uncomment last line\n //DEBUG alert(responseText);\n }\n );\n};\n\nconfig.macros.upload.uploadContent = function(content, storeUrl, toFilename, uploadDir, backupDir, \n username, password, callbackFn) {\n var boundary = "---------------------------"+"AaB03x"; \n var request;\n try {\n request = new XMLHttpRequest();\n } \n catch (e) { \n request = new ActiveXObject("Msxml2.XMLHTTP"); \n }\n if (window.netscape){\n try {\n if (document.location.toString().substr(0,4) != "http") {\n'UniversalBrowserRead');}\n }\n catch (e) {}\n } \n //DEBUG alert("user["+config.options.txtUploadUserName+"] password[" + config.options.pasUploadPassword + "]");\n // compose headers data\n var sheader = "";\n sheader += "--" + boundary + "\sr\snContent-disposition: form-data; name=\s"";\n sheader += config.macros.upload.formName +"\s"\sr\sn\sr\sn";\n sheader += "backupDir="+backupDir\n +";user=" + username \n +";password=" + password\n +";uploaddir=" + uploadDir;\n // add lock attributes to sheader\n if (window.BidiX && BidiX.GroupAuthoring && BidiX.GroupAuthoring.lock) {\n var l = BidiX.GroupAuthoring.lock.myLock;\n sheader += ";lockuser=" + l.user\n + ";mtime=" + l.mtime\n + ";locktime=" + l.locktime;\n }\n sheader += ";;\sr\sn"; \n sheader += "\sr\sn" + "--" + boundary + "\sr\sn";\n sheader += "Content-disposition: form-data; name=\s"userfile\s"; filename=\s""+toFilename+"\s"\sr\sn";\n sheader += "Content-Type: " + config.macros.upload.contentType + "\sr\sn";\n sheader += "Content-Length: " + content.length + "\sr\sn\sr\sn";\n // compose trailer data\n var strailer = new String();\n strailer = "\sr\sn--" + boundary + "--\sr\sn";\n //strailer = "--" + boundary + "--\sr\sn";\n var data;\n data = sheader + content + strailer;\n //"POST", storeUrl, true, username, password);\n try {\n"POST", storeUrl, true); \n }\n catch(e) {\n alert(config.macros.upload.messages.crossDomain + "\snError:" +e);\n exit;\n }\n request.onreadystatechange = function () {\n if (request.readyState == 4) {\n if (request.status == 200)\n callbackFn(request.responseText);\n else\n alert(config.macros.upload.messages.errorUploadingContent + "\snStatus: "+request.status.statusText);\n }\n };\n request.setRequestHeader("Content-Length",data.length);\n request.setRequestHeader("Content-Type","multipart/form-data; boundary="+boundary);\n request.send(data); \n};\n\n\ = function(uploadUrl, uploadToFilename, uploadDir, uploadBackupDir, \n username, password) {\n var request;\n try {\n request = new XMLHttpRequest();\n } \n catch (e) { \n request = new ActiveXObject("Msxml2.XMLHTTP"); \n }\n try {\n if (uploadUrl.substr(0,4) == "http") {\n"UniversalBrowserRead");\n }\n else {\n"UniversalXPConnect");\n }\n } catch (e) { }\n //"GET", document.location.toString(), true, username, password);\n try {\n"GET", document.location.toString(), true);\n }\n catch(e) {\n alert(config.macros.upload.messages.crossDomain + "\snError:" +e);\n exit;\n }\n \n request.onreadystatechange = function () {\n if (request.readyState == 4) {\n if(request.status == 200) {\n config.macros.upload.uploadChangesFrom(request.responseText, uploadUrl, \n uploadToFilename, uploadDir, uploadBackupDir, username, password);\n }\n else\n alert(config.macros.upload.messages.errorDownloading.format(\n [document.location.toString()]) + "\snStatus: "+request.status.statusText);\n }\n };\n request.send(null);\n};\n\n//}}}\n////===\n\n////+++!![Initializations]\n\n//{{{\nconfig.lib.options.init('txtUploadStoreUrl','store.php');\nconfig.lib.options.init('txtUploadFilename','');\nconfig.lib.options.init('txtUploadDir','');\nconfig.lib.options.init('txtUploadBackupDir','');\nconfig.lib.options.init('txtUploadUserName',config.options.txtUserName);\nconfig.lib.options.init('pasUploadPassword','');\nsetStylesheet(\n ".pasOptionInput {width: 11em;}\sn"+\n ".txtOptionInput.txtUploadStoreUrl {width: 25em;}\sn"+\n ".txtOptionInput.txtUploadFilename {width: 25em;}\sn"+\n ".txtOptionInput.txtUploadDir {width: 25em;}\sn"+\n ".txtOptionInput.txtUploadBackupDir {width: 25em;}\sn"+\n "",\n "UploadOptionsStyles");\nconfig.shadowTiddlers.UploadDoc = "[[Full Documentation| ]]\sn"; \nconfig.options.chkAutoSave = false; saveOptionCookie('chkAutoSave');\n\n//}}}\n////===\n\n////+++!![Core Hijacking]\n\n//{{{\nconfig.macros.saveChanges.label_orig_UploadPlugin = config.macros.saveChanges.label;\nconfig.macros.saveChanges.label = config.macros.upload.label.saveToDisk;\n\nconfig.macros.saveChanges.handler_orig_UploadPlugin = config.macros.saveChanges.handler;\n\nconfig.macros.saveChanges.handler = function(place)\n{\n if ((!readOnly) && (document.location.toString().substr(0,4) != "http"))\n createTiddlyButton(place,this.label,this.prompt,this.onClick,null,null,this.accessKey);\n};\n\n//}}}\n////===\n
Eclipse is a great open-source IDE for software development. To develop and debug Jist/SWANS with Eclipse you need to do a couple of things:\n\n1. Download the source distribution from the Jist/SWANS project site\n2. Unpack into a directory like {{{C:\sjist-swans-1.0.6}}}\n3. Open eclipse and select File -> New Project\n4. When asked, create a project from existing source and point to the {{{jist-swans-1.0.6}}} folder you just created. Give the project a name and let Eclipse take care of the rest.\n\nYou can now create simulations and use all the great features in Eclipse like intellisense of classes and methods, refactoring, and in-line debugging etc. \n\nBe aware that when you want to run a simulation, for example, {{{driver.heartbeat}}}, you should open the run/debug dialog and set the Main class to {{{jist.runtime.Main}}}. Then go to the Arguments tab and type in the name of the simulation, e.g. {{{driver.heartbeat}}}. Otherwise you will more than likely run into an error such as {{{entity expected}}}. This is down to the way that Jist/SWANS works, which is to take your compiled simulation and rewrite calls made to the {{{JistAPI}}}\n\n[[Debugging simulations or the Jist kernel with Eclipse]]
Vehicular Ad Hoc Network
Illustrates what kind of information we can get about the radio interface, including calculating effective range from transmit power, path loss and fading.
This SWANS driver is an extension of the aodvtest driver and allows us to send UDP messages in real time over the simulated network and see how the routing protocol responds - great for debugging
if you want to get started straight away, the vmware image hosted at (link from the ns2 wiki at + vmware player at is a good start. \n\nBear in mind this is the *basic* debian unix install and has no UI, so to write simulations you'll need to use {{{vi}}}. \n\nI also had to play with the path variable in {{{bash.rc}}} in order to start ns from anywhere. \n\nThe ns2 directory is located in the {{{root}}} folder. \n\nYou'll soon find that you want some kind of access between your host computer and the vmware image. First I enabled the virtual ethernet card on the linux guest by doing the following:\n{{{\nsu\nifconfig eth1 up //might be 2\ndhclient eth1\nping //just to check you can communicate with the outside world\n}}}\n\nI set up a public samba share on my Windows PC, and then used {{{smbmount}}} to mount this public share to a mount point {{{mnt/(share name)}}}. I used {{{apt-get install smbmount}}} in order to allow this (whilst logged in as su).\n\nI also disabled the annoying beep in the command line :)\n{{{\nsetterm -blength 0\n}}}\n\n{{{\npublic class AppImp implements AppInterface, NetInterface.NetHandler {\n \n private NetInterface netEntity; //network entity\n int nodenum; //node no\n Object self; //proxy ref to self\n \n /**\n * Set network entity.\n *\n * @param netEntity network entity\n */\n public void setNetEntity(NetInterface netEntity)\n {\n this.netEntity = netEntity;\n }\n\n /**\n * Return self-referencing NETWORK proxy entity.\n *\n * @return self-referencing NETWORK proxy entity\n */\n public NetInterface.NetHandler getNetProxy()\n {\n return (NetInterface.NetHandler)self;\n }\n\n /**\n * Return self-referencing APPLICATION proxy entity.\n *\n * @return self-referencing APPLICATION proxy entity\n */\n public AppInterface getAppProxy()\n {\n return (AppInterface)self;\n }\n \n public void run() {\n run(null);\n \n }\n\n public void run(String[] args) { \n PeriodicCall(); \n }\n\n public void receive(Message msg, NetAddress src, MacAddress lastHop,\n byte macId, NetAddress dst, byte priority, byte ttl) {\n //receive+process a custom protocol message here\n }\n \n \n public void PeriodicCall()\n {\n //schedule next periodic call\n JistAPI.sleep(Constants.SECOND);\n \n ((AppInterface)self).run(); //calls PeriodicCall() through run()\n \n }\n public AppImp(int nodenum,NetIp net)\n {\n this.nodenum = nodenum;\n this.self = JistAPI.proxyMany(\n this, new Class[] { AppInterface.class, NetInterface.NetHandler.class });\n = net;\n }\n\n}\n}}}
ns2 is one of the more popular network simulators, and although it's not my primary choice of network simulator, i'm using it specifically for a quick visual validation of my SWANS simulations. To do so, I parse trace files generated by SWANS which turns these into a comma-seperated values list of events like {{{move_node}}},{{{add_node}}},{{{create_flow}}} which a simulation.tcl file parses and adds to the ns2 event list, using standard ns2 simulation constructs
Changelog: driver Added: FlowHandler, GenericDriver, JistExperiment, VisualizerInterface, Visualizer, images \n\nY jist.runtime Added ignored packages to support XML encoding/decoding \nY Added support for pausing \nY Added support for pausing \nY Added support for pause/resume jist.swans \ Added various constants \nY jist.swans.field Added accessor methods for location and mobility information \nY Added support for speed, bearing and ?stopped? information, also added new mobility models and completed existing ones \nY Added generic pathloss with shadowing model Added RadioData, RadioDataInterface, Signal classes (for supporting multichannel eventually) \nAdded StreetMobility*, StreetPlacement* files to support STRAW mobility model \nAdded jist.swans.field.streets in support of STRAW \nY jist.swans.mac Added MacStats to track Mac-layer statistics \nY Mac802_11: Rearranged constructor, corrected some propagation delay calculations, \nY added support for unhandled radio modes (e.g. In radioIdle()), \nY added support for dropped packed notification to higher layers, \nY added support for recording of channel activity \nY MacInterface: Added support for setting of network interface and radio data \njist.swans.misc Astar*, Support for A* search algorithm (needed for STRAW shortest-time path calculations) \nLocation: Added support for bearing calculation \nY Pickle: Added support for serialization of objects (needed for porting to real-world code) \nY StatInterface: Early support for statistics \nY Added support for reusable (not one-shot) timer \nY Added support for writing data to files \ \nY MessageQueue: Added support for a drop message queue (messages dropped after queue buffer exceeded) \nY NetAddress: Overrides compareTo, toInt, hashCode \nY NetAddressIpFactory: Added to support lower-cost creation of NetAddresses \nY NetInterface: Added get/set methods for protocol information, packet dropping, access to the message queue and mac interface \nY NetIp: Added IpStats, implemented new NetInterface methods, added support for promiscuity \nY NetMessage: Added support for ?location? and ?next hop? headers, added setters \ \nAdded Channel, RadioEvent, RadioMessage, RadioMode for future support of multichannel \nRadioInfo: Added RadioInfoUnique \nRadioInterface: Added support for recording radio activity \nRadioNoise: Added support for recording congestion, activity \njist.swans.route \nAdded geo package to contain classes common to geographic location \n*GPSR*: Added GPSR implemenation \nY NS2Timer: Implemented Ns-2 style timers RouteCache, \nRouteDsr*_ns2: Port of ns-2 DSR to SWANS \nY RouteInterface: Added support for access to net entity, packet dropping, added interfaces for new routing protocols \nY (for AODV) All routing protocols: Added support for new interfaces, added visualization for some \njist.swans.trans \nTransInterface: Transport layer now has access to network layer \ntariavo Various utilities for tariavo's code
| tiddlyspot password:|<<option pasUploadPassword>>|\n| site management:|<<upload index.html . . pkiddie>>//(requires tiddlyspot password)//<<br>>[[control panel|]], [[download (go offline)|]]|\n| links:|[[|]], [[FAQs|]], [[announcements|]], [[blog|]], email [[support|]] & [[feedback|]], [[donate|]]|
wireless traces :\n\nAODV etc traces:\n\n
starter project:\n\nns manual: (html version)