Posts Tagged tinyos
Email is Broken: A Case Study
Facebook’s “email” announcement is generating quite the buzz. Some speculate that Gmail and Hotmail will soon be on their deathbeds. While Mark Zuckerberg describes email as “slow and formal,” there is a much more pertinent problem: email abuse and misuse. Anyone with an email account gets bucketfuls of spam every day. I know I do.
With email nearly as old as the internet, the protocol still in use today assumes that: 1) All users trust each other, and 2) All users have a moderate level of skill to send and receive email properly. The failure of the first assumption has led to the high levels of spam and phishing emails we see today. There is no trust: how does anyone know that a link supposedly send by a friend isn’t a botnet client? The failure of the second assumption is just as bad: how many jobs have been lost due to a hasty “reply all” click? The remainder of this post will focus on the second assumption: email misuse.
Mailing List Misuse
The timing of Facebook’s email announcement coincided with an incident that really demonstrates that it’s well past time for email to die. I have subscribed to a fair number of mailing lists throughout the past 15 years or so I’ve been using email. As per Wikipedia, electronic mailing lists fall into two categories: 1) Discussion lists, and 2) Announcement lists. Discussion lists, such as the TinyOS programming help mailing list, allow all subscribers to send questions to everyone else in the list. Someone poses a question in the email, puts the mailing list address in the “to” header, and once sent, all other subscribers get the email. Anyone with an answer “replies all” to the list so that everyone can benefit from the discussion.
Announcement lists, on the other hand, are only a one-way broadcast. Only a single owner is permitted to send announcements to all subscribers on the list with the recipients unable to reply to all. That’s the idea, anyway.
In September, I joined an alumni mailing list which I would estimate has at least several hundred subscribers. The list owner sent out regular updates at an interval of roughly once per two weeks, as illustrated in the figure below. However, following the most recent announcement, chaos ensued. On September 15th (see figure), a subscriber learned that he could “reply all” to the list and not only email the list owner, but all of the other subscribers as well. For whatever reason, the announcement list was set up like a discussion list, allowing any subscriber to reply. It only got worse from there.
Soon, a torrent of emails followed in the steps of the first subscriber as one person after another typed up a response and hit “reply all.” Being an alumni list, the discussion circulated among a group of individuals of about the same class year, discussing subjects that made no sense to anyone else. The responses quickly got out of hand: through the afternoon of September 15th, the sending rate soared to well past 1 email per minute.
Following a mad surge of random discussion on the 15th and another resurgence on the afternoon of the 16th, subscribers began to email the list complaining about the onslaught. One after another, again surging past the rate of 1 email per minute, subscribers demanded that they be unsubscribed and that the discussion be taken to a message board. Finally, the message was heard: everything died down and stopped completely by the evening of the 16th.
So what went wrong? First, the list owner should have ensured that he was the only one able to send emails to the list. Second, a significant number of subscribers emailed the list in an attempt to unsubscribe instead of emailing the list owner. Both mishaps plus the breach of protocol for announcement lists made things quite a mess in only a few hours.
Some other interesting statistics can be computed in the aftermath. Since the list’s inception, about 10% of the total volume can be attributed to announcements, 50% for misuse/discussion, and 40% for complaints about the discussion. Next, we show the age distribution of senders:
Since this is an alumni list, I was able to determine the age of just about every sender within two or three years, however, beyond some quick Googling, about 2% of the senders have an undetermined age. The above figure shows that those who abused the mailing list for discussion are all older than 45. Conversely, there is a roughly even distribution of age for those complaining. There is also slightly lower percentage of users under 45. From the figure, we can conclude that the younger generations are savvy enough to avoid either: 1) Misusing the announcement list as a discussion list, or 2) Sending the list an unsubscribe email instead of the owner.
Another interesting fact is that 37% of all senders used a business email address to reply to the list. 37% of senders used their business email for personal reasons! That’s insane. Another 9% had nasty hundred word “disclaimer” signatures at the end of their messages. Stuff like: “THIS IS A LEGALLY PRIVILEGED AND CONFIDENTIAL COMMUNICATION THAT IS INTENDED TO BE VIEWED ONLY BY THE INTENDED RECIPIENT…ANY DISSEMINATION, DISTRIBUTION, OR COPYING OF THIS TRANSMISSION IS STRICTLY PROHIBITED.” I think the distribution and copying prohibition went out the window the minute they hit “reply all.” It’s a wonder more people don’t get busted for stuff they put in emails.
In conclusion, this case study demonstrates exactly why email ought to be abandoned. There are too many avenues for abuse, misuse, and unintended consequences. It would be nice to see Facebook come up with something appropriate for today’s internet.
Q&A: TOSSIM
I’ve been pretty busy lately to post much, but I think I’ll try something new. Since, I receive a lot of questions regarding TinyOS, I’ll post my responses here instead of via email so that more people can benefit (if I’ve got time). The first question:
When using python (tossim) to test the application code written using nesC, how did you make nesC code and python dependent on each other or how did you control the nesC code from python? Did you use swig to export the interfaces from C to python or ran the application code directly on nesC by hard-coding them thus making nesC and python independent?
The TinyOS tutorial for TOSSIM does a pretty good job of explaining this. The idea is to write your TinyOS application code as if for a real mote. Then you can compile it for TOSSIM:
$ make micaz sim
This will automatically create the wrappers needed for your TinyOS program to interact with Python. You don’t need to do anything with SWIG yourself, the TinyOS makefile does this all for you.
My goal here is to compute throughput, packet delivery ratio, end-to-end delay for an arbitrary number of nodes say 10 to 50.
You can access nesC variables directly from a Python script that runs your simulation. You can easily access a sequence number variable or a variable that tracks the number of retransmissions of a specific node in the simulation. Again, the TinyOS TOSSIM tutorial explains this in greater detail, but in your Python script you can have something like:
m = t.getNode(0)
v = m.getVariable("MyAppC.seq")
Low Level Serial Control in TinyOS
Posted by Matt in development on March 30, 2010
It’s been awhile since my last TinyOS post, but a new project required me to return to programming motes. In this case, we needed to send ASCII characters over the serial port to the PC, bypassing the default TinyOS serial stack.
The TinyOS serial stack is designed to work with Active Messages so that packets received over the radio can be easily forwarded on to the PC. To that end, the high-level serial and radio components provide the same interfaces. The TinyOS serial stack has layers for packet formatting, error checking, and a read/write buffer. However, for our project, we wanted to simplify the PC side so we didn’t have to use the TinyOS JNI libraries to receive TinyOS Active Message packets. A simple program to read ASCII characters over the serial connection would suffice for our purposes — Minicom does this quite well and is easily installed on Ubuntu Linux and can be configured to read from attached USB devices.
The goal was to produce a TinyOS component that provided a command for transmitting ASCII character strings over the serial connection to a PC. The implementation is very similar to the Pulse Oximeter code I wrote for Atmel-based devices, however this time I targeted MSP430-based devices, such as the TelosB or Tmote Sky. The implementation uses the Msp430Uart1C component for accessing the serial connection. This component provides the UartByte or UartStream interfaces for reading and writing and the Resource interface for gaining control of the UART. Msp430Uart1C also provides the Msp430UartConfigure interface for setting the baud rate.
The control flow for writing a character string is as follows: First, request the UART resource. Second, when the resource has been granted, call UartStream.send() to transmit the string. Lastly, when UartStream.sendDone() is signaled, signal the higher level application that the character string has been sent or an error message if something went wrong. In my SerialAscii module, I have the following command to send a character string:
command error_t SerialAscii.sendAscii(char *str)
{
bufferLength = strlen(str);
if(bufferLength > BUFFER_SIZE)
return FAIL;
memcpy(strBuffer,str,bufferLength); // copy string into a buffer
call Resource.request(); // request access to the UART
return SUCCESS;
}
I copy the string into a buffer to keep the application from modifying it before being transmitted. When the resource request is granted, I transmit the string:
event void Resource.granted()
{
error_t result = call UartStream.send(strBuffer,bufferLength);
if(result == FAIL)
post sendDoneFailTask(); // return failure message to the user if something bad happened
}
Lastly, when the string is sent, I release the resource and signal the higher level application:
async event void UartStream.sendDone(uint8_t *buf, uint16_t len, error_t error)
{
// call Resource.release() in each of these tasks
if(error == SUCCESS)
post sendDoneSuccessTask(); // signal SerialAscii.sendAsciiDone(SUCCESS);
else
post sendDoneFailTask(); // signal SerialAscii.sendAsciiDone(FAIL);
}
I’ve made my code available here. Let me know if you find any bugs or have any comments or suggestions.
BCI Pulse Oximeter in TinyOS 2.1
Posted by Matt in development on June 15, 2009
After days of getting lost in TinyOS 1.1 and 2.1 low level hardware abstractions, the Harvard design BCI pulse oximeter now works in TinyOS 2.1.
Prior to writing the driver/interface code, I had to procure the pulseox hardware. Detailed descriptions of hardware, software, and applications are found at the Harvard CodeBlue website. I first ordered a Smiths Medical OEM Digital Micro Power Pulse Oximeter Board. I was able to get in contact with sales staff by emailing Smiths Medical. The pulseox board comes with a finger sensor and runs about $200.
Next, I needed an interface board to connect the BCI pulseox board to the 51 pin connector on the Crossbow IRIS. The Harvard CodeBlue source code has documentation for a PCB layout and suggests that you order the PCB from an online manufacturer. You also have to purchase some other components that must be soldered onto the interface board. Fortunately, I was able to “skip” this step with the help of Leo Selavo, who graciously supplied me with two interface boards. He emphasized that soldering the components onto the interface board requires a lot of skill and experience and if I were to try on my own that I would most likely break the PCB or components several times until I got it right. The setup with pulseox board, interface board, IRIS mote, and finger sensor is illustrated below:
With the pulseox board, interface board, and of course IRIS mote, I was ready to get my heart rate. The biggest challenge still lay ahead: writing code to interface with the pulseox. The CodeBlue pulseox code was written in 2005 for TinyOS 1.0. All of the low level UART and mote hardware interfaces have changed drastically since then, so the old code wouldn’t just work right out of the box. I had seen plenty of posts on the CodeBlue mailing list about implementations for the pulseox in TinyOS 2.x, but nobody had bitten the bullet and actually written anything.
What I wanted was to be able to use the pulseox like a sensor on the MTS300/310 sensorboard: call a Pulse.read() or Oxygen.read() command and get back a uint16_t with pulse or blood oxygen saturation. This is fairly straightforward since I had experience modifying the MTS310 sensorboard code to power on the sensors manually. I created configurations PulseC and OxygenC to provide SplitControl and Read interfaces to power on the sensor and read, respectively. I then wired PulseC and OxygenC to a PulseoxP, which functioned as an intermediary between the application and the low-level pulseox driver code. Like in the original CodeBlue source, I created a BciC configuration and BciP implementation to communicate with the pulseox directly through the UART and return data back to PulseoxP.
The key changes between the CodeBlue TinyOS 1.0 code and my implementation are all found in BciP (or BCIM.nc in the original CodeBlue source). Two issues come to mind. First, setting the mote hardware pins is done differently in TinyOS 2.1. Calls like TOSH_SET_PW0_PIN() are replaced by abstractions. I had to wire MicaBusC.PW0 to the GeneralIO interface in BciC and then call GeneralIO.set() in BciP.
The second difference is with the UART. TinyOS 1.0 uses the HPLUART interface for low level UART communication, but this has been replaced by Atm128Uart0C for the Atmel 1281 architecture. The CodeBlue source code initializes the low level UART to its default state, turns it off, and then sets the hardware registers to the desired UART configuration so that the mote can communicate with the pulseox board. After figuring out what the CodeBlue UART configuration code did, I can’t believe that you can actually write to the registers directly! Imagine if you could do that with user-level code on a PC! To enable transmissions and reception along with interrupts for the UART in TinyOS 1.x, you had to do the following:
// Enable tx/rx interrupts and tx/rx
outp(((1 << RXCIE) | (1 << TXCIE) | (1 << RXEN) | (1 << TXEN)) ,UCSR0B);
TinyOS 1.0 uses the outp() macro to set bits of a given register, but this macro does not exist in TinyOS 2.x. Instead, the UART register bits are configured in a struct with fields for each bit in the register. For the above example in TinyOS 2.1, the following union represents the control register in Atm128Uart.h:
/* UART Control Register */
typedef union {
struct Atm128_UCSRB_t {
uint8_t txb8 : 1; //!< UART Transmit Data Bit 8
uint8_t rxb8 : 1; //!< UART Receive Data Bit 8
uint8_t ucsz2 : 1; //!< UART Character Size (Bit 2)
uint8_t txen : 1; //!< UART Transmitter Enable
uint8_t rxen : 1; //!< UART Receiver Enable
uint8_t udrie : 1; //!< USART Data Register Enable
uint8_t txcie : 1; //!< UART TX Complete Interrupt Enable
uint8_t rxcie : 1; //!< UART RX Complete Interrupt Enable
} bits;
uint8_t flat;
} Atm128UartControl_t;
The flat uint8_t is a real slick way to convert all the elements in the struct to a single word, which can then be written to the register. Following the code that initializes the UART in tos/chips/atm128/HplAtm128UartP.nc, I was able to configure the UART to run with the pulseox board requirements: 4800 baud, double rate, transmission and reception interrupts enabled, no parity checking, 1 stop bit, and 8 bit word size. So, with the previous example to enable transmissions and reception, you do the following in TinyOS 2.x:
Atm128UartControl_t ctrl;
ctrl.bits = (struct Atm128_UCSRB_t) {rxcie:1, txcie:1, rxen:1, txen:1};
UCSR0B = ctrl.flat; // ctrl.flat
I ran my concerns by the CodeBlue mailing list, which elicited a reply from Prof. Matt Welsh that I was headed in the right direction. I finished my implementation, worked out some compile errors, and loaded the new pulseox and general data collection code onto a mote to see what would happen. Almost never does my TinyOS code run correctly on the first try — usually I spend hours or days debugging, but this time it was magic. A number jumped onto the screen in the data column of my PC Java application, which was connected wirelessly though a base station mote to the pulseox mote. The sensor readings seemed reasonable for a heart rate, for jumping up and down and breathing hard made it go up and laying down and trying to breathe slowly made it slow down.
I have made my code available here and any feedback, suggestions, or questions are encouraged. To use it, place the pulseox directory into the tos/sensorboards directory in TinyOS 2.x. In the makefile for your application, add the line “SENSORBOARD=pulseox”.
MTS300/310 Sensorboard: Sampling multiple sensors simultaneously
Posted by Matt in development on May 14, 2009
My current project involves sampling data with the Crossbow Iris and MTS310 sensorboard. I wish to sample data at regular intervals, say 20ms, using all available modalities on the MTS310: x and y-axis accelerometer, x and y-axis magnetometer, light, temperature, and acoustic. Every 20ms, a timer fires and collects data samples from each sensor using the Read interface. As it turns out, the current TinyOS 2.x code for the MTS300/310 does not allow this.
I found that every time I called Read.read() for some of the sensors, that there would often be a delay in getting my data back with Read.readDone(). This delay was because each call to Read.read() would power on the sensor, requiring a warm-up time before a sample could be retrieved. While the warm-up time for the accelerometer is 17ms, the warm-up time for the light sensor is an excruciatingly long 1200ms! So, I would call Read.read() at 20ms intervals, but have to wait over a second to get data from the light sensor. When the data sample is returned at Read.readDone(), the sensor would power off again, thus requiring another warm-up the next time a sample is requested. Basically, the constant warm-up lag in the current TinyOS code prevents sampling at a reasonably fast rate using Read.
I also found that if I wished to get both axes of the accelerometer or magnetometer simultaneously, that only one axis would ever return data. The accelerometer, magnetometer, and light/photo sensors use the ArbitratedResource interface to block all other sensors that use the same resource when one sensor has a lock on the resource. If the x-axis accelerometer was sampling with Read.read(), it would have a lock on a UQ_ACCEL_RESOURCE identifier, preventing the y-axis from sampling simultaneously, since its resource is also identified by UQ_ACCEL_RESOURCE. I wasn’t the only one with these problems, as illustrated by this TinyOS mailing list post. The mailing list poster also points out that the ReadStream interface blocks data sampling for all sensors but the first one that calls it: if you try using ReadStream to get streaming data for the accelerometer x-axis and the magnetometer x-axis, the call to ReadStream.read() for the accelerometer would block the sampling of the magnetometer if it was called first. With ReadStream, all sensors use the same resource identifier, so when one is sampling, it has the lock, and all others must wait. The resource arbitration effectively prevents multiple sensors from sampling data simultaneously using ReadStream.
This automated power control for Read as well as the blocking for Read and ReadStream really limits the functionality of the sensorboard. Initially, I thought it was a hardware constraint. You would think that since the board has all those sensors on it, the manufacturers would have designed it such that you can use all the sensors at the same time. It turns out, that it isn’t a hardware problem — it’s just that the MTS300/310 sensorboard code is written so you can only effectively use one sensor at a time. I managed to change this by modifiying the behavior of the Read.read() of every MTS sensor.
The current TinyOS code uses SplitControlPowerManagerC to power on the sensor when you call Read.read(). Read.read() triggers the power manager to call the sensor’s SplitControl interface. Supposedly, when Read.readDone() is signaled and the sensor data is ready, the power manager will keep the sensor powered on for some amount of time in case the sensor is needed again — this is from the comments in PowerManagerP.nc. However, from my testing, there is no evidence that the sensor stays on after Read.readDone() is signaled. The warm-up routine starts all over again the next time Read.read() is called. It’s possible that 20ms is too much time between samples, but it appears from the power manager code that the sensor is turned off immediately if no resource requests for that sensor are pending. Currently, I can’t find anywhere in the MTS310 sensorboard code or in the power manager code where some kind of backoff timer is set before powering down the sensor.
To that end, I eliminated this automated power control through the power manager. I altered each sensor’s interface in the mts300 code library so that each sensor provided a SplitControl interface. This now allows me to manually power on each sensor I want to use before I start sampling. I then have a timer call Read.read() at regular intervals for each sensor I want, which returns the data with Read.readDone(). When I’m done sampling, I can turn the sensors off.
The current code is more a less a hack and has a weird side effect. For example, since the x and y-axis accelerometers use the same AccelP module with the same SplitControl power interface, only one accelerometer has to call SplitControl.start() to turn the sensor on. The same goes for the magnetometer and the light/photo sensors, as well as for calling SplitControl.stop() to power down the sensors. Otherwise, the warm-up/power on sequence is triggered twice for the same sensor if you want to use both axes of the accelerometer or magnetometer, or wish to use both light and temperature sensors. Edit: this issue has been fixed in the code. Calling SplitControl.start() for both axes of the accelerometer/magnetometer will only run the power on sequence once, but both calls will return SplitControl.startDone(). The same applies for SplitControl.stop().
The modified sensorboard code can be downloaded here, which is a zipped directory of all the mts300 sensor code, but changed to mts310. Just unzip it into the tos/sensorboards directory. The configurations AccelXC, AccelYC, MagXC, MagYC, MicC, PhotoC, and TempC have all been modified to provide the SplitControl interface, so for example you can call AccelXC.start() to power on the accelerometer, then AccelXC.read() to get data, and then AccelXC.stop() to power the accelerometer off. I’ve used this extensively with the accelerometers, magnetometers, acoustic, and light sensors and it seems to work without any issues.
Sidewinder: A Predictive Data Forwarding Protocol for Mobile Wireless Sensor Networks
Here is a link to the final version of my SECON 2009 paper:
Sidewinder: A Predictive Data Forwarding Protocol for Mobile Wireless Sensor Networks
Matthew Keally, Gang Zhou, Guoliang Xing
IEEE SECON 2009
June 22-26, Rome, Italy, acceptance ratio: 81/431=18.8%
When motelist doesn’t see your motes…
Posted by Matt in development on February 28, 2009
Since I’ve upgraded to TinyOS 2.1, motelist always reports “no devices found” for my Iris motes when they are plugged in to the interface board. A search of the TinyOS mailing list showed that the motelist script may not be including the correct Product ID when looking for motes. I was able to get the script to recognize the interface board by altering /usr/bin/motelist to include the product id “6010″ instead of the default “6001″:
grep { ($_->{UsbVendor}||"") eq "0403" && ($_->{UsbProduct}||"") eq "6010" }
The manufacturer, product ID and other information about USB devices can be found in /sys/bus/usb/devices and running dmesg can tell you the path of the stuff you just plugged in. For now, the script only prints out the path of the interface board but not the attached Iris mote. The path of the interface board is needed for installing TinyOS programs, but the path of the mote is needed to listen for data packets from the mote. So far, I haven’t found a way to get motelist to recognize the mote, but if I find it, I’ll post it.
Enabling ACKs in TinyOS 2.x
Posted by Matt in development on February 25, 2009
I’ve seen a lot of questions about how to enable ACKs in TinyOS and not too many responses. Unlike a lot of TinyOS problems I’ve had, this one isn’t too bad. Some sample code for enabling ACKs is available in $TOSROOT/apps/tests/cc2420/TestAcks. In your configuration .nc file, just wire the PacketAcknowledgements interface:
implementation {
...
MainC.PacketAcknowledgements -> ActiveMessageC;
}
Then, in your implementation file:
module TestAcksP {
uses {
interface PacketAcknowledgements;
...
Then, just before you call AMSend.send() for a message_t testMsg:
call PacketAcknowledgements.requestAck(&testMsg);
When a packet arrives with an ACK request, the ACK will be sent automatically. In the sender’s AMSend.sendDone(), you will want to make sure the packet was ACKed to determine if a retransmission is required:
if(!call PacketAcknowledgements.wasAcked(&testMsg))
retransmit();
And that’s pretty much it.
Upgrading to TinyOS 2.1
Posted by Matt in development on February 25, 2009
I recently upgraded my TinyOS version from 2.0.2 to 2.1 and discovered that it makes use of Java 6. I was testing my installation and kept getting the following when compling TestSerial:
java.lang.UnsupportedClassVersionError: Bad version number in .class file
Changing my java complier and runtime to Java 6 fixed this problem.
TinyOS and NesC syntax highlighting
Posted by Matt in development, info on February 20, 2009
Since I’ve been doing some more work with TinyOS, here is a gedit .lang file that provides nesC syntax highlighting. I got the file from the author of this post on the TinyOS mailing list and it’s been pretty useful. To install it in Ubuntu, place the file in /usr/share/gtksourceview-2.0/language-specs/. Unfortunately, you’ve got to be root to do this and I don’t know of another way to add .lang files if you aren’t. This is a problem for the departmental machines where I don’t have root access, so I can’t use custom gedit syntax highlighting.
There is a more heavyweight solution, if you like Eclipse. Since I’ve been using Subclipse with Eclipse on several machines to keep all my code in sync, I’ve found Eclipse to be pretty useful. A TinyOS 2.x Eclipse plugin is available on this site that provides syntax highlighting and it appears as though it will compile and install source code as well (though I haven’t tried that part).
2/21/2009: Since I’m on the topic of Eclipse, I’ve noticed that the Ubuntu repository Eclipse version is 3.2, but 3.4 is available from the Eclipse website. Following this guide, it seems that you can override the /usr/eclipse directory with the new version if you want to upgrade. Plugins will have to be reinstalled, though.





Recent Comments