# Sharing the testbed with other users
This tutorial is based off of the [[ GNU Radio Benchmark example ]] to show how to enable the sharing of the testbed with other users.
## Why would you want to do this?
While CorteXlab was made to allow a single user to operate the testbed at a time, mainly to avoid harmful interference to the experimenter, a few situations might require sharing the testbed:
- **GNU Radio or wireless communications courses.** For teachers all over the world who would like to use CorteXlab as a teaching platform, using it for practical sessions with their students, sharing CorteXlab is the only way to go. If this is what you want to do, pay attention to the number of radio platforms and the number of students who will use them! Also, pay attention to the interference among students if transmissions are necessary (i.e., choose different frequencies for each student/group).
- **Radio challenges.** One interesting use of CorteXlab is to enable radio challenges to be carried out, where several competing groups might need to hack an ongoing communication, decode an unknown signal, or exploit spectrum holes to transmit. In this case the only way to allow simultaneous usage of the experimentation room is to enable sharing.
It is important to know that while sharing, there are no guarantees on interference in the room.
## Reserving the testbed
First, we need to reserve the CorteXlab room for the shared session. If you're teaching a course or if you're hosting a challenge, in order to guarantee the testbed will be free when you need, the best thing to do is to reserve it prior to the date of usage:
you@srvairlock:~/examples$ oarsub -l nodes=BEST,walltime=4:00:00 -t container -r '2018-07-21 14:00:00'
Beware that the //walltime// parameter has to span the whole session.
## Logging into the SSH front-end
Assuming your account has been correctly created, you can start by logging into the "srvairlock" SSH front-end:
you@yourpc:~$ ssh -X -v [-i path/to/the/key] -p 2269 username@gw.cortexlab.fr
If this doesn't work, either you still don't have an account (you can get one by going [[account|here]]) or your SSH keys aren't present in your computer, in which case you need to copy them from the computer you used to generated them. For more information on the connection process, please check [[access|here]].
If everything goes well you should get the CorteXlab welcome screen and an srvairlock prompt.
## Inspecting the example task
Retrieve the examples repository on GitHub :
you@srvairlock:~$ git clone https://github.com/CorteXlab/examples.git
you@srvairlock:~$ cd examples
Let's get inside and see what it's all about:
you@srvairlock:~/examples$ cd my_task
you@srvairlock:~/examples/my_task$ ls
benchmark_rx.py receive_path.py transmit_path.py
benchmark_tx.py scenario.yaml uhd_interface.py
Let's go over each one of these files:
* ''benchmark\_tx.py'': the GNU Radio python script for the OFDM transmitter
* ''benchmark\_rx.py'': the GNU Radio python script for the OFDM receiver
* ''transmit\_path.py'', ''receive\_path.py'' and ''uhd\_interface.py'': are helper codes for both benchmark python scripts
* ''scenario.yaml'': a scenario description file (in yaml format), which assigns the roles of "transmitter" and "receiver" to a set of nodes
Now, let's inspect the scenario description file, to understand what will happen during this experiment:
you@srvairlock:~/examples/my_task$ less scenario.yaml
Which will give you this:
# Example scenario description file
#
# All lines starting with "#" and empy lines are ignored
# Scenario textual description
# simple string (a one liner)
description: base scenario for CorteXlab
# Experiment maximum duration
# Time after which the experiment is forced to stop
# integer (seconds)
duration: 300
# Node list
#
# format:
#
# nodes:
# (machine):
# command: (entry point script relative to the task root)
nodes:
node4:
command: ./benchmark_rx.py --antenna="TX/RX" --rx-gain=25 -v -W 2M -f 2.49G
passive: true
node6:
command: ./benchmark_tx.py --antenna="TX/RX" --tx-amplitude=0.2 -v -W 2M -f 2.49G
The file is self-explanatory, but for now let's ignore all but the indented lines following ''node4:'' and ''node6:''. You'll have the opportunity to understand the rest better later on.
Let's go over each said line now:
* ''node4:'': This opens the node4 declaration of options
* ''command: ./benchmark\_rx.py --antenna="TX/RX" --rx-gain=25 -v -W 2M -f 2.49G'': states the command to run on node4. Details of the parameters are:
* ''--antenna="TX/RX"'': this indicates which antenna connector to use on the USRP radio platform connected to the node
* ''--rx-gain=25'': this sets the receive gain of the USRP radio platform
* ''-v'': this puts the script in verbose mode, printing debug information
* ''-W 2M'': this sets the bandwidth of the signal to 2 MHz
* ''-f 2.49G'': this sets the carrier frequency of the signal to 2.49 GHz
* ''passive: true'': the node 4 will be passive, meaning it will stop when all active nodes are finished
Same reasoning follows for the section on node6. So this is the scenario at hand:
* **Node4** behaves as the **OFDM receiver**
* **Node6** behaves as the **OFDM transmitter**
For more info on where these nodes are located inside the platform, please check the node position map at the home of this wiki.
## Creating the task file
Before submitting the task to the nodes, we need first to put the task into a format that can be readily understood by Minus. Minus is the experiment controller code, responsible for doing the dirty stuff for you:
* Firing up the right nodes to be used
* Copying the code onto the nodes
* Starting everything at the same instant
* Waiting until everything finishes, and stop stubborn code from running forever
* Copying results, error and output messages to srvairlock, so that you can access it
* Turning off everything and cleaning up
Let's prepare the task, but first we need to go back to the folder containing the task:
you@srvairlock:~/examples/my_task$ cd ..
you@srvairlock:~/examples$
And now, instruct Minus to create a task file:
you@srvairlock:~/examples$ minus task create my_task
you@srvairlock:~/examples$ ls
my_task my_task.task
And now we have a new file called ''my\_task.task'' which is ready to be submitted. Warning, do not leave a slash after the directory task name (i.e. ''my_task'' ) or the command will fail.
## Submitting the task
Now we need to give the task to Minus, so that it can operate its magic.
First we need to reserve the CorteXlab room:
you@srvairlock:~/examples$ oarsub -l nodes=BEST,walltime=0:30:00 -I
(If you're running your reservation in a container reservation):
you@srvairlock:~/examples$ oarsub -t inner= -l {"network_address in ('mnode4.cortexlab.fr', 'mnode6.cortexlab.fr')"}/nodes=2,walltime=0:30:00 -I
(Be sure that no one else is using the same node as you)
This will run a 30 minute job and open a subshell in which you can run minus tasks. This subshell will be killed after 30 minutes, and if you leave the shell earlier, it will terminate the corresponding oar job. More documentation on oar can be found [[reserve|here]]. You can also monitor the current jobs in the [gantt web interface](http://xp.cortexlab.fr/drawgantt/).
We then submit the minus task:
you@srvairlock:~/examples$ minus task submit my_task.task
Task with id 15 enqueued user .
You'll see that Minus recognizes you as the submitter of the task and gives you a task number (15 in this example). You'll want to __write down the number__ of the task as it will be important for checking its status or to abort it, if necessary.
Bear in mind that your task has been put on a queue and will await running tasks and other scheduled tasks to start, so it may take a while before it runs.
Minus can also help you check the status of the queue:
you@srvairlock:~/examples$ minus testbed status
num total tasks: 2540
num tasks waiting: 0
num tasks running: 0
tasks currently running:
(none)
These information are returned:
* ''num total tasks'': This is the number of the last created task
* ''num tasks waiting'': This is the number of tasks currently awaiting in the queue
* ''num tasks running'': This is the number of tasks currently executing (most of the time, there can only be one task running at the same time. Only in special situations, such as demos, tutorials, can several users run tasks concurrently).
* ''tasks currently running'': This is a detailed list of tasks currently running.
## Collecting and analyzing the output
Generally the OFDM example task will take a few minutes to run. Once it is finished, Minus will take care of copying the results and output messages back to your home folder in srvairlock, so that you can analyze it.
All results are stored by task number in the results folder, inside your home folder.
Let's go and have a look at them:
you@srvairlock:~/examples$ cd ../results
you@srvairlock:~/results$ ls
task_15
you@srvairlock:~/results$ cd task_15
you@srvairlock:~/results/task_15$ ls
node4.tgz node6.tgz
you@srvairlock:~/results/task_15$
So we see that we have a folder for each task and inside each folder one compressed file per participant node. Let's extract one of those files and see what's inside:
you@srvairlock:~/results/task_15$ tar -zxf node4.tgz
you@srvairlock:~/results/task_15$ ls
node4 node4.tgz node6.tgz
you@srvairlock:~/results/task_15$ cd node4
you@srvairlock:~/results/task_15/node4$ ls
benchmark_rx.py receive_path.pyc stdout.txt uhd_interface.pyc
benchmark_tx.py scenario.yaml transmit_path.py
receive_path.py stderr.txt uhd_interface.py
We see that all of the files we used to create the task are inside, but we have some new files. The *.pyc files are the python compiled files and we can safely ignore them. The other two are:
* ''stdout.txt'': all output messages from your GNU Radio python script are written here. These include GNU Radio messages as well as all "print"s you include in your code. Seeing the contents of this file is useful to assert its correct operation.
* ''stderr.txt'': all error messages are printed here. If you see strange things on the ''stdout.txt'' or nothing at all, it might be interesting to take a look at the ''stderr.txt'' to debug your code.
Let's take a look inside both, starting with the ''stdout.txt'':
you@srvairlock:~/results/task_15/node4$ less stdout.txt
You should get a long file that looks more or less like this:
linux; GNU C++ version 4.7.2; Boost_104900; UHD_003.007.001-84-gd99ce4ef
-- Opening a USRP2/N-Series device...
-- Current recv frame size: 1472 bytes
-- Current send frame size: 1472 bytes
-- Detecting internal GPSDO.... Found an internal GPSDO
-- found
-- Setting references to the internal GPSDO
-- Initializing time to the internal GPSDO
UHD Receiver:
UHD Args:
Freq: 2.49GHz
LO Offset: 0Hz
Gain: 25.000000 dB
Sample Rate: 2Msps
Antenna: TX/RX
Subdev Sec: None
Clock Source: None
Using Volk machine: avx_64_mmx_orc
OFDM Demodulator:
Modulation Type: bpsk
FFT length: 512
Occupied Tones: 200
CP length: 128
Warning: failed to enable realtime scheduling
ok: False pktno: 169 n_rcvd: 1 n_right: 0
ok: False pktno: 170 n_rcvd: 2 n_right: 0
ok: False pktno: 171 n_rcvd: 3 n_right: 0
ok: False pktno: 173 n_rcvd: 4 n_right: 0
ok: False pktno: 174 n_rcvd: 5 n_right: 0
ok: False pktno: 175 n_rcvd: 6 n_right: 0
ok: False pktno: 176 n_rcvd: 7 n_right: 0
ok: False pktno: 177 n_rcvd: 8 n_right: 0
ok: False pktno: 178 n_rcvd: 9 n_right: 0
ok: False pktno: 179 n_rcvd: 10 n_right: 0
ok: False pktno: 180 n_rcvd: 11 n_right: 0
ok: False pktno: 181 n_rcvd: 12 n_right: 0
ok: False pktno: 182 n_rcvd: 13 n_right: 0
ok: False pktno: 185 n_rcvd: 14 n_right: 0
ok: False pktno: 186 n_rcvd: 15 n_right: 0
ok: False pktno: 191 n_rcvd: 16 n_right: 0
ok: False pktno: 192 n_rcvd: 17 n_right: 0
ok: False pktno: 197 n_rcvd: 18 n_right: 0
ok: False pktno: 203 n_rcvd: 19 n_right: 0
...
Let's try to understand it:
* The first 9 lines correspond to the UHD messages
* The next 16 lines correspond to the GNU Radio messages and radio configuration parameters
* There might be a warning message about realtime scheduling that can be safely ignored
* The lines starting with ''ok: False pktno: 169 n\_rcvd: 1 n\_right: 0'' are from the receiver trying to decode the OFDM packets. Let's further inspect these lines:
* ''ok: False'': means the packet was incorrectly decoded, i.e., it failed to pass the checksum
* ''pktno: 169'': is the sequence number seen at the receiver
* ''n\_rcvd: 1'': is the number of received packets
* ''n\_right: 0'': is the number of correctly received packets
As can be seen, there's a local oscillator (LO) mismatch between both nodes that complicates the decoding process.
You can also look into the stderr.txt:
you@srvairlock:~/results/task_15/node4$ less stderr.txt
## What next?
Congratulations! You have finished your first tutorial on CorteXlab. Please, feel free to change the example task and try out different configurations, carrier frequencies, bands, and so on. You can always resubmit this task to test out different kinds of configurations.
One good example of what to do is to nudge the carrier frequency of approximately +/- 20 KHz and see if the decoding process works better.
To learn mode advanced concepts around creating and managing tasks on CorteXlab, please continue the tutorials.