OS Tricks
- Thomas Watteyne
This page details some tricks we find very useful.
Python
When you plug a mote in your Linux-based OpenLBR, it will appear as /dev/ttyUSB
x, where x is a number. Similarly, when plugged into Windows, it appears as COM
x in your device manager. It is frustrating, each time you plug in a mote, to look for that number and change a global variable in your Python script.
Instead, the following script scans for the connected motes and returns a list containing the list of the serial ports a mote is connected to.
#!python import os serialport_names = [] def findSerialPortsNames(): global serialport_names if os.name=='nt': path = 'HARDWARE\\DEVICEMAP\\SERIALCOMM' key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, path) for i in range(winreg.QueryInfoKey(key)[1]): try: val = winreg.EnumValue(key,i) except: pass else: if val[0].find('VCP') > -1: serialport_names.append(str(val[1])) serialport_names.sort() elif os.name=='posix': serialport_names = glob.glob('/dev/ttyUSB*') serialport_names.sort()
After running the findSerialPortsNames()
function, you script can open the first serial port using:
serialHandler = serial.Serial(serialport_names[0],baudrate=115200)
When you start a script which attaches to the serial port your mote is attached to, chances are it will crash if you unplug your mote while the script is running. Similarly, if you start your script while the mote is not connected, chances are your script will crash and exit.
The following script is a way around. The function scan()
looks for connected motes. If no mote is connected, the script will run scan()
every second, until a mote is connected. When a mote connects, it constantly reads characters the mote sends and prints those. If the mote gets disconnected, it goes back to running scan()
every second.
#!python #!/usr/bin/python import serial, signal, sys, time, glob serialHandler = '' def scan(): return glob.glob('/dev/ttyUSB*') def serialRx(): while True: availableports = scan() if (len(availableports)>0): try: serialHandler = serial.Serial(availableports[0],baudrate=115200,timeout=5) except: err = sys.exc_info() sys.stderr.write( "Error serialRx 1: %s (%s) \n" % (str(err[0]), str(err[1]))) else: print "connected to "+serialHandler.portstr while True: try: char = serialHandler.read(1) except SystemExit: return except: err = sys.exc_info() sys.stderr.write( "Error serialRx 2: %s (%s) \n" % (str(err[0]), str(err[1]))) break else: print char else : print "no mote connected" time.sleep(1) def signal_handler(signal, frame): sys.exit(0) signal.signal(signal.SIGINT, signal_handler) serialRx()
This means that you can start running your script regardless of whether the mote is connected to the OpenLBR or not. Similarly, you can unplug your mote and replug it later on without having to deal with restarting the script.
LBR
You may have configured your OpenLBR to acquire it's IPv4 address through DHCP. If that is the case, chances are that the DHCP server gives it a different IPv4 address everytime the OpenLBR reboots. Since the OpenLBR does not have a screen, you don't know what IPv4 address to point your PuTTY to configure it.
One solution is to have the OpenLBR load a PHP script on a remote server. That server can store the IPv4 address of the OpenLBR which contacted it, and display it on some webpage for your to see.
On the remote server (in our case http://wsn.eecs.berkeley.edu/), create a folder openserver/
under your server's DocumentRoot and create the file record_openlbr_address.php
:
#!php <?php $file_name = "ipv4_".$_GET["hostname"].".txt"; $file_handler = fopen($file_name, "w"); $logdetails = $_SERVER['REMOTE_ADDR']; fwrite($file_handler, $logdetails); fclose($file_handler); ?> <html><body>This should be accessed only by an LBR.</body></html>
Make sure you can see that page, in our case http://wsn.eecs.berkeley.edu/openserver/record_openlbr_ipv4.php. Once you have visited that page once, a file ipv4_<hostname>.txt
should have been created, with hostname
the value of the GET
parameters passed when opening that page.
On the OpenLBR, create the file /etc/network/if-up.d/openlbr/reportaddress.sh
with the following content:
#!/bin/bash wget -O - http://wsn.eecs.berkeley.edu/openserver/record_openlbr_ipv4.php?hostname=`cat /etc/hostname` exit 0
We use the -O
flag of wget
so that it does not store any file when loading the PHP script. Don't forget to give the script execution privileges used chmod
.
Now, add the following line at the end of /etc/network/interfaces
on your OpenLBR:
post-up /etc/network/if-up.d/openlbr/reportaddress.sh
This instructs Debian to execute that script right after the OpenLBR's Ethernet interface is up. So now, each time your OpenLBR boots, read it's current IPv4 address at http://wsn.eecs.berkeley.edu/openserver/.
Misc
If you happen to be outside of the IPv6 cloud, and you still want to check whether a node is alive, you can ask http://lg.he.net/, which sits on the IPv6 cloud, to ping it for you.
We recommend vi
as a code editor. You can install it:
- in Linux by typing
apt-get install vim
; - in Windows by install gVim.
It comes with an auto-indent feature. To configure that, edit the configuration file:
C:\Program Files\Vim_vimrc
in Windows;~/.vimrc
in Linux
Add the following lines at the beginning to instruct the auto-indent engine to use soft tabulations of 3 spaces
set sw=3
When you edit some code, hit Esc
and type gg=G
to edit the whole file. Other vi tips at http://www.vim.org/tips/.
Windows
In an Administrator command window:
C:\Windows\system32>netsh interface ipv4 show interface Idx Met MTU State Name --- --- ----- ----------- ------------------- 1 50 4294967295 connected Loopback Pseudo-Interface 1 11 5 1300 disconnected Wireless Network Connection 10 20 1300 connected Local Area Connection C:\Windows\system32>netsh interface ipv4 set interface "10" MTU=1375 Ok. C:\Windows\system32>netsh interface ipv4 show interface Idx Met MTU State Name --- --- ----- ----------- ------------------- 1 50 4294967295 connected Loopback Pseudo-Interface 1 11 5 1300 disconnected Wireless Network Connection 10 20 1375 connected Local Area Connection
You can connect remotely to an OpenLBR or your OpenServer using PuTTY in Windows. Normally, you would specify a username in Connection
> Data
> Auto-login username
and enter the password when prompted. The problems are:
- you don't want to enter the password every time;
- a brute force attack will break you password and you'll end up reinstalling the server.
Instead, you should use public key authentication:
- download puttygen.exe
- double-click on it and choose
Generate
. Follow the instructions so you end up with two filespublic_key.pub
andprivate_key.ppk
on your hard drive. - on your Linux server:
- create a file called
/.ssh/authorized_keys2
(Ubuntu) or/.ssh/authorized_keys
(all other Linux flavors) which contains your publickey.If your
public_key.pub
contains:---- BEGIN SSH2 PUBLIC KEY ---- Comment: "rsa-key-thomas" AAAAB3NzaC1yc2EAAAABJQAAAIBx8jcskAQwgmw2ZR18K1cyW4NyQDFhLYiva4WL DHyVgxBuo95ndyeYHoc1lk6FpRpV9jdvTCD4rGx8OT28dFyVFvDSiNxbwm/qMHhv Y9Vtu7842h0Hkelb5w2DU8Qvp33OQ67frQNKcvnYOP2MQxkfKVRInP/pfzuux0Ni ErcFxQ== ---- END SSH2 PUBLIC KEY ----
Your
~/.ssh/authorized_keys
should contain:ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIBx8jcskAQwgmw2ZR18K1cyW4NyQDFhLYiva4WLDHyVgxBuo95ndyeYHoc1lk6FpRpV9jdvTCD4rGx8OT28dFyVFvDSiNxbwm/qMHhvY9Vtu7842h0Hkelb5w2DU8Qvp33OQ67frQNKcvnYOP2MQxkfKVRInP/pfzuux0NiErcFxQ==
- create a file called
If you want only public authentication, and never a password (recommended), add the following line to
/etc/ssh/sshd_config
:PasswordAuthentication no
restart your OpenSSH server:
sudo /etc/init.d/ssh restart
- on your Windows computer
Load
the session to your server- In
Connection
>SSH
>Auth
, put the path to your private key in tehePrivate key file for authentication
field.
Linux
screen
is a Linux command which allows you to leave a script running even though you log out of the computer, and to go back interacting with it when you log back in, as if you had never logged of. On the OpenLBR, we use the script [openlbr.py openlbr.py] to interact with the attached mote. We start that script as soon as the Ethernet connection is up, by adding the following line to /etc/network/interfaces
:
post-up screen -d -m /etc/network/if-up.d/openlbr/openlbr.py
The double flag -d -m
of screen
start in "detached" mode. This creates a new session but doesn't attach to it.
Whenever the interface is up, the script is running. When logging on to the OpenLBR, use the flag -list
to see the identifier of the screen
session running:
openlbr:~# screen -list There is a screen on: 1290..openlbr (06/03/10 19:40:56) (Detached) 1 Socket in /var/run/screen/S-root.
Then, reconnect to that session using the -r
flag:
openlbr:~# screen -r 1290
To "detach" from a screen session (i.e. leave without terminating it), type Ctrl-A d
. If you type exit
, you will terminate it.
For some reason, it happens sometimes that the screen -list
command tells you there is no session running, although a ps -aux
tells you there is. You can force a screen session to recreate the sessions number (in fact a file in /var/run/screen/S-root/
) by sending it a CHLD
signal. The following shows you a typical sequence of commands:
openlbr:~# screen -list No Sockets found in /var/run/screen/S-root. openlbr:~# ps -aux Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND [...] root 1290 0.0 3.2 3000 948 ? S<s 19:40 0:00 SCREEN -d -m /etc/network/if-up.d/wsnlbr/wsnlbr_reportdata.py [...] openlbr:~# kill -CHLD 1290 openlbr:~# screen -list There is a screen on: 1290..openlbr (06/03/10 19:40:56) (Detached) 1 Socket in /var/run/screen/S-root. openlbr:~# screen -r 1290
kill -9 `ps -aef | grep 'python' | grep -v grep | awk '{print $2}'`
From a terminal cd to the desired directory then do the following:
mkdir ../theNewDirectory for i in `find . -type d`; do mkdir -p ../theNewDirectory/"$i"; done for i in `find . -type d`; do sed 's/oldString/newString/ig' "$i"; done
Use only /g
for the command not to ignore case.
ifconfig eth0 | sed -n '/inet addr:/s/.*addr:\([^ ]*\) .*/\1/p'
echo 'openlbr5' > /etc/hostname
You need to reboot for this to take effect.
# apt-get install ntp
MAC OSX
Install Xcode from Mac OS X install DVD. This adds developer support applications. You must check Unix development tools
or something like that during the install to get unix support for the typical gcc, perl, etc. Python 2.5.4 is run by typing python2.5
at the terminal. NOTE: this may change with future releases of Apple xcode.
Install pyserial from http://pyserial.sourceforge.net/
Install virtual com port driver from http://www.ftdichip.com/Drivers/VCP.htm for MAC OSX.
A Crossbow TelosB mote shows up as something like /dev/tty.usbserial-XBRAHH4P
.
Git and GitHub
You will be removing the branch directly on GitHub. If you have not merged it back into another branch, the changes in the branch you delete will be lost.
- Hold
Shift
and right-click on your source code directory. ChooseTortoiseGit
,Browse Reference
. - On the left, expand
remotes
and selectorigin
. - Right-click on the branch you want to delete and select
Delete remote branch
. - Accept the warnings if you know what you're doing.