#
# This is a script example, which illustrates the use of topologies in 
# an experiment scripts
#
# The scenario of this experiment involves two group of nodes: 'sender' and
# 'receiver'. The 'sender' group will generate some broadcast traffic, which will 
# be received by the 'receiver' group.
#
# Each group contains nodes that are not explicitly defined within this script, but 
# rather randomly drawn from the set of active nodes on the tested where this script is 
# running. In other words, this script example does not specifically name which node belongs to 
# which group. 
#
# More information on the available commands to define a topology are available on the 
# following page: 
# http://www.orbit-lab.org/wiki/Documentation/NodeHandler/Commands/defTopology
#
# In this example we:
# 1) Define some experiment parameters 
# 2) Define a simple 1st Topology, which is NOT used later in the experiment
# 3) Define a 2nd Topology, which will be used to build the 'sender' group of nodes
# 4) Define a 3rd Topology, which will be used to build the 'receiver' group of nodes
# 5) Define the 'sender' group of nodes
# 6) Define the 'receiver' group of nodes
# 7) Finally run the experiment
#

# 1)
# Define some parameters to be use in this experiment
#
defProperty('minNodeNumber', 12, 'Minimum number of nodes required for this experiment')
defProperty('receiverNumber', 8, 'Number of nodes in a receiver role')

# 2)
# Define a mock topology that we will use to verify the amount 
# of available active nodes on the testbed where this script is running
# The list of active nodes is automatically created at the end of an 'imageNodes4' process.
#
# This step is optional and could also be integrated within the 
# definition of a topology that will be really used. 
# It is just here as an example.
#
defTopology('stubTopo') { |t|
  # Load the topology which contains all the active nodes
  baseTopo = Topology['system:topo:active']
  # Check if there are enough nodes available in the 'baseTopo'
  # if not then exit this experiment
  if baseTopo.size < prop.minNodeNumber.value
    puts "Not enough node available! (size: #{baseTopo.size})"
    Experiment.done
  end
  puts "Number of active nodes on this testbed: #{baseTopo.size}"
  # do nothing else with this stub topology...
}

# 3)
# Define a topology that will hold the sender node(s) of this 
# experiment
#
defTopology('senderTopo') { |t|
  baseTopo = Topology['system:topo:active']
  # Draw a random node from the pool of active ones 
  aNode = baseTopo.getUniqueRandomNode 
  # Add this random node to this 'senderTopo' topology
  t.addNode(aNode.x, aNode.y)
  # Print the node that belongs to this topology
  puts "Size of the my sender Topology: #{t.size}"
  t.eachNode { |n|
    puts " - Node: #{n}"
  }
}

# 4)
# Define a topology that will hold the receiver node(s) of this 
# experiment
#
defTopology('receiverTopo') { |t|
  baseTopo = Topology['system:topo:active']
  # Repeat the following 'receiverNumber' of time
  for count in 1..prop.receiverNumber.value
    # Draw a random node from the pool of active ones 
    aNode = baseTopo.getUniqueRandomNode 
    # Add this random node to this 'receiverTopo' topology
    t.addNode(aNode.x, aNode.y)
  end
  # Print the nodes that belongs to this topology
  puts "Size of the my receiver Topology: #{t.size}"
  t.eachNode { |n|
    puts " - Node: #{n}"
  }
}

# 5)
# Define the 'sender' group for this experiment
# This group will include the node(s) from the 'senderTopo' topology
# See "HelloWorld" tutorial pages for more info on the following commands 
#
defGroup('sender', 'senderTopo') {|node|
	node.prototype("test:proto:sender", {
		'broadcast' => 'on',
		'destinationHost' => '192.168.255.255',
		'packetSize' => 1024,
		'rate' => 200,
		'protocol' => 'udp'    
	})
	node.net.w0.mode = "Master" 
	node.net.w0.type = "g" 
	node.net.w0.essid = "npc123" 
	node.net.w0.ip = "192.168.0.1" 
        wait 30
}

# 6)
# Define the 'receiver' group for this experiment
# This group will include the node(s) from the 'receiverTopo' topology
# See "HelloWorld" tutorial pages for more info on the following commands 
#
defGroup('receivers', 'receiverTopo') {|node|
	node.prototype("test:proto:receiver" , {
		'protocol' => 'udp'
	})
	node.net.w0.mode = "Managed" 
	node.net.w0.type = "g" 
	node.net.w0.essid = "npc123" 
	node.net.w0.ip = "%192.168.%x.%y" 
        wait 30
}

# 7)
# When all the applications are installed on the nodes in all the groups,
# we can start running the applications used in this experiment
# See "HelloWorld" tutorial pages for more info on the following commands 
#
whenAllInstalled() {|node|
	wait 15 
	allGroups.startApplications
	wait 15
	Experiment.done
}


