D-RATS in QST

The September issue of QST arrived in my mailbox yesterday, complete with my D-RATS article on page 34!

The idea to write an article about D-RATS came much earlier in the year (way back in February), once we had used it rather extensively in our Tuesday night on-the-air testing sessions.  As such, a couple of the screenshots show version 0.1.6, which seems ancient to me now.  It also means the article mentions only features that have been around for a long time.  Thus it leaves out most of the interesting mapping features and the new session support for unattended transfers, tunneling of TCP traffic, etc.

Anyway, it’s nice to see it there and hopefully people will check out the D-RATS wiki for the updates.

The article is available in PDF format here .  The editors of QST have graciously allowed me to reproduce the article on my personal web site.  Please note the QST copyright and do not distribute it further.

In other D-RATS news, we did a fair bit of real-life work with it over the weekend at the Hillsboro Air Show.  We used the forms capability to send several “lost child” reports back and forth between the first aid tents and the command post, which worked quite well.  We also used the text messaging capabilities to send some tactical messages while loud jets were overhead.  The text messaging also helped to notify someone of a non-critical event instead of tying up the voice frequency and net control operator.

We did run into some issues both mornings, which seemed to be caused by some sort of weird RFI corrupting packets in just the right way to trigger a bug.  I still haven’t been able to reproduce it locally, but I did get some debug information captured which might be enough to spot something.  I hope I don’t have to wait until next year’s show to try out the changes!

We also tested the image sending (resize/resample) functionality a little bit, but didn’t use it heavily because of timing.  However, below is an image of some guy with a callsign of KK7DS who posed (against his will) for a sample shot:

Image

Posted in Radio Tagged ,

Show UTC as a location in Gnome International Clock

I love the new international clock applet in Gnome.  It makes it easy to see a list of alternate time zones for coordinating with colleagues.  However, it seems to be missing the ability to add UTC as a timezone.  UTC, GMT, and Zulu are missing from the zone list, even though they’re present in /usr/share/zoneinfo.  Attempting to add a zone manually just results in a silent failure for some reason.

I’m sure there is a less insane way to do this, but hacking the gconf entries works.  First, figure out which applet number represents your clock.  To find out, I searched gconf for one of my configured locations:

% grep -lr Hillsboro .gconf
.gconf/apps/panel/applets/applet_7/prefs/%gconf.xml

This tells me that my clock is applet_7.  Next, fire up gconf-editor and navigate to apps/panel/applets/applet_7/prefs.  Edit the cities key and add a value of the following:

<location name=”Zulu” timezone=”UTC” code=”UTC” current=”false”/>

Save, quit gconf-editor, and pop open your location list to verify.

Posted in Linux

ARRL Field Day 2008

On Saturday, I participated in the ARRL Field Day for the first time.  For those who don’t know, Field Day is a annual event where Amateur Radio operators head out to fields, forests, and mountain tops to make as many contacts as possible in 24 hours.  The idea is to operate off of emergency and battery power for as long as possible, but this is not always how it’s done.

So, John Core (KX7YT) and I went out to the Hillsboro Trap and Skeet club to set up a station in the parking lot.  John had a travel trailer with an awning, which worked very well.  We put up a 160-10m fan dipole on a 40-foot fiberglass pole at one end.  On top of the trailer, John had a 20-10m vertical dipole.  We took turns with each antenna while operating because the fan dipole was clearly the better one.

I took and used my ICOM IC-718, AT-7000, and my 80 AHr battery.  I was on battery power for almost the whole event (well, the six hours of it that I worked) but plugged into my power supply for a bit to juice up the battery a bit.  It all worked pretty well, and I was pleased with the contacts I made, considering the poor propagation conditions of late.  The farthest west I made it was Alaska,  the farthest east was Tennessee, and the north-south winner was Alberta, Canada.

In total, I made 37 contacts in six hours.  This includes several breaks to rest the ears and shovel in some food.  Of those, twelve were new (or interesting) locations for me, to which I sent QSLs.  I have never (in my life) packed and sent so many envelopes at once.  Each got a card, and a self-addressed stamped envelope.  My neighbors must have thought I was starting a junkmail business when I walked to the mailbox with the stack:

Image

The destinations were: AK(2), ID, UT. MT, TN, AZ, TX, MN, NV, British Columbia, and Alberta.

Posted in Radio

Dayton Hamvention 2008

I was lucky enough to travel to the Dayton Hamvention this year.  I was demoing D-RATS in the dstarusers.org booth with the K5TIT folks.  I received a lot of good feedback both about the current and future uses of D-RATS, as well as suggestions for additional features.  People seemed mostly interested in the form and mapping pieces, which isn’t too surprising.  I had the demo machine linked to my home machine for connectivity with other users in RF range of my home in Hillsboro, Oregon, as well as the VK3UR station in Ballarat, Australia.

This was also my first trip to Dayton, which was quite an experience.  I was warned about the level of geekiness I would be exposed to, but I assured people that I hang around some pretty hard-core geeks that run in different circles.  I wasn’t quite expecting to see so many people with HF antennas mounted on their backs, or VHF antennas mounted on helmets, but I wouldn’t say I was surprised.

I got to interact with a lot of smart and interesting people, and was rather encouraged to see the impressive demonstration of amateur radio passion.  The place was packed with people, and it was really hard to take pictures since you almost can’t stand still long enough to get a decent shot.  However, I did grab a couple and have posted them here .  If I get to go back another year I will be more prepared and try to get more.

There were definitely some good “deals” to be had, although I had expected them to be a bit better.  I did manage to talk myself into buying an IC-2820H from the HRO booth while I was there Smilie: :)

Posted in Radio

Ubuntu from a USB key on a Samsung Q1 Ultra

Man I love Linux.  Uh-lot.

I am setting up these extremely sweet Samsung Q1 Ultra machines for a D-RATS demo.  These uber-slick ultra-portable tablet PCs are pretty amazingly small.  The biggest problem is that they run Vista.  I’ve read all the stuff out there about being extremely horrible, but this was my first hands-on experience.  I thought “Sure, it’s horrible, but it’s Windows so horrible is the name of the game.”  I had no idea of the level of suckiness I was in for.

To make a long story short, the Prolific USB-to-Serial adapters, which are in just about everything, don’t work well in Vista.  Prolific seems to be ignoring Vista in favor of pushing support for the new version to the resellers.  However, most of the resellers that Prolific recommends to people seeking Vista support don’t have updated drivers.  Thus, a significant amount of serial activity with these devices in Vista leaves you with a locked machine that won’t even shutdown.  It’s pathetic.  Luckily Keyspan, continuing with their reputation of high-quality everything, has Vista drivers and their devices work well. 

For the demo, however, I thought it might be nice to have a backup plan.  I don’t want to alter these machines, of course, since they’re not mine, so I can’t install another OS to the hard drive, even for a dual-boot.  This, however, doesn’t stop me from booting something like a live CD.  Luckily, the ubuntu live environment is transferrable to a USB key with a few steps .  The result is a wonderful thing: Ubuntu booting completely from a USB key.  I can copy a few of the libraries I need to the key and install them from a script on boot to run D-RATS:

Image

The tablet stylus doesn’t work out of the box, and I won’t spend the time to fix it since this is just a backup plan.  However, the on-board pointing stick or a USB mouse would suffice.  The sad part is, it boots to this environment just a hair slower than Vista boots from the hard drive.

Posted in Linux

D-RATS gets map support

Last week, I released D-RATS 0.1.11 with preliminary GPS support.  This meant parsing the NMEA GPS strings that are broadcasted by ICOM radios, calculating the distance and direction from current, as well as a temporary way to plot known stations on a Google Maps map.  This was a stunning visualization of the data being sent across, but it only works in the presence of a (good) internet connection.

Since then, I’ve been working to integrate a map viewer that can do most of what the fantastic Google Maps application can do, but with local data fetched from OpenStreetMap.org.  The result is 0.1.12 with integrated station mapping capabilities that can be operated completely offline:

D-RATS map

I wasn’t aware of the OSM project until I had a need for access to free map data without the Google terms of service (which only allow the data to be used by free and public web sites).  I was surprised by how well the OSM stuff worked and applaud the group for their efforts.  I’ll be offering up my CPU cycles to help render map tiles soon.

Posted in Radio Tagged ,

Making a KVM-bootable image

I’ve lost count of how many times I’ve had to re-learn how to create a bootable image from a filesystem tree (such as a tarball of a root filesystem, or a Xen partition image).  If for no other reason than recording it for next time, here it is.

Create an image file (lets assume 4MB will do it), partition it, mount the partition, and copy in the root filesystem

% dd if=/dev/zero of=test.img bs=1M count=4
% parted test.img mklabel msdos
% parted test.img mkpart primary 0 4
% losetup /dev/loop0 test.img
% kpartx -a /dev/loop0
% mount /dev/mapper/loop0p1 /mnt
% cp -rav /path/to/root /mnt/

Now, you need to put a kernel and an initrd on it.  Assuming a RedHat-like system:

% mkdir -p /mnt/boot/grub
% cp /boot/vmlinuz-`uname -r` /mnt/boot/vmlinuz
% mkinitrd –with ata_piix –with rtl8139 /mnt/boot/initrd `uname -r`

Next, you need a bootloader:

% cat >/mnt/boot/grub/grub.conf <<EOF
default 0
timeout 5
title My System
kernel /boot/vmlinuz root=/dev/sda1
initrd /boot/initrd
EOF
% cat >/tmp/grub_setup <<EOF
device (hd0) /path/to/image       # NB: Put your full path here
root (hd0,0)
setup (hd0)
EOF
% grub < /tmp/grub_setup

That’s it!  Now you can unmount your image:

% umount /mnt
% kpartx -d /dev/loop0
% losetup -d /dev/loop0

The resulting image should boot normally in QEMU, KVM, etc.

Posted in Codemonkeying, Linux Tagged ,

2008 ARRL International DX Contest

This past weekend was the 2008 ARRL International DX Contest.  I participated with the help of some borrowed equipment graciously loaned to me by John, KX7YT.  This weekend marked several “firsts” for me.  I made my first contact on HF, participated in my first contest, and had my first twinge of “antenna envy”.

On the first note, I was using a borrowed a Kenwood TS-830S hybrid radio and an MFJ-969 antenna tuner.  I built a quick 20-meter dipole to use just before the weekend.  I initially had it in my attic, but that turned out to be much too noisy to use (likely due to proximity to my server room).  I moved it outside and strung it up about 10 feet from the ground between a window and a tree.  Using the Kenwood was quite an experience.  Learning to tune it up for each band I wanted to transmit on was a bit of an effort, especially when you have to also tune the antenna tuner as well.  I feel rather privileged to have made my early contacts on such an unique legacy radio.  Now I can say “back in my day, we used to have to warm up the tubes and tune the radio before we could talk on HF…”

On the second note, I made several interesting contacts in the contest.  None were too surprising or rare, nor were there any distance records being won.  However, for my first time out, with an unknown radio and makeshift antenna, I think I did okay.  I made contacts in Alaska, Hawaii, Jamaica, Mexico, Japan, and Brazil across a total of 15 QSOs on the 20 and 15 meter bands.

Finally on to the antenna envy.  After removing the antenna from the attic, I strung it up between two trees for a maximum height of about 5 feet.  This made a huge difference over the attic from a noise standpoint.  However, repositioning it again at a height of about 10 feet was another large improvement.  Now I understand why people want big antennas, up high, and away from sources of noise!  I’m  already scheming about how to build a unobtrusive wire antenna between a few of the peaks of my roof.  It will take some work, but I think that, given the positioning of my house, I’ll be able to make something that works well without being too noticeable by the neighbors.

I had a lot of fun with this, and I’m now trying to decide which radio I should get for myself, as well as what other antenna options I may be able to construct before the next contest at the end of March.  What is that saying about boys and expensive toys?

Posted in Radio

When is foo == &foo?

The answer is “in the CMPI interface specification”.

So, CMPI defines this massive union of every possible data type, called CMPIValue.  It looks something like this (but with many more types):

union {
    uint32_t uint32;
    uint64_t uint64;
    char *chars;
    CMPIString *string;
} CMPIValue;

This is then thrown around way too much, using an enumeration called CMPIType to indicate which interpretation of CMPIValue you intend to use.  For example, to set a property of an instance, you would do something like this for an integer:

uint32_t myint = 123;
CMSetProperty(inst, “MyIntProperty”, (CMPIValue *)&myint, CMPI_uint32);

or this for a string:

const char *mystring = “We’re really asking for trouble here…”;
CMSetProperty(inst, “MyStrProperty”, (CMPIValue *)mystring, CMPI_chars);

Makes sense, right?  The above usage in the string case is, of course, the scenario intended by the interface designer, and it is (in my experience) almost exclusively used that way.  However, assuming you want to do something a little more complicated, such as write a CIMXML instance parser, you might want to pass around their CMPIValue and CMPIType objects.

So, lets say you do something like the following:

CMPIType parse_integer(char *string, CMPIValue *val) {
    val->uint32 = 123;
    return CMPI_uint32;
}

CMPIType parse_string(char *string, CMPIValue *val) {
    val->chars = strdup(“Oh, boy, here we go”Smilie: ;);
    return CMPI_chars;
}

int set_property(char *string, char *name, CMPIInstance *inst) {
    CMPIValue value;
    CMPIType type;

    if (/* value looks like an integer */)
        type = parse_integer(string, &value);
    else
        type = parse_string(string, &value);

    CMSetProperty(inst, name, &value, type);
}

That’s all fine, right?  We set the CMPIValue in our handler functions, and then we pass a pointer to our value to CMSetProperty().  Obviously nothing to see here, CMSetProperty() takes a CMPIValue *……doesn’t it?

The answer is a big fat “NO, no it doesn’t”.  If you were paying close attention before, we passed in the pointer to a CMPIValue stack variable in the integer case, but in the string case, we passed in a pointer to an actual string buffer.  Thus, if we put that string pointer in the CMPIValue itself, and then pass a pointer to it, you get a double pointer, the equivalent of a char **.  Because the type is correct, the compiler doesn’t complain, but the CIMOM explodes.

I’m really shocked and horrified that the CMPI interface includes this semantic difference in the setProperty() broker call.  To verify that I wasn’t just hallucinating on a Friday afternoon, I tracked the call down to the following bit of truly spectacular OpenPegasus code:

CIMValue value2CIMValue(const CMPIValue* data, …Smilie: ;) {
    . . .
    else if (type==CMPI_chars) {
          if (data) v.set(String((char*)data));
          else return CIMValue(CIMTYPE_STRING,false);
    }

Right there, they take the CMPIValue and cast it directly to a char * if you tell them that you’re passing in CMPI_chars!  Just to illustrate how the interpretation of the CMPIValue parameter fundamentally changes depending on the type you passed in, the following appears directly below:

   else if (type==CMPI_charsptr) {
      if (data && *(char**)data) v.set(String(*(char**)data));
      else return CIMValue(CIMTYPE_STRING,false);
   }

So, if you pass in CMPI_chars, then it expects a char*.  If you pass in CMPI_charsptr, then it expects a char ** (which would actually cast a the example above to the correct thing).  IMHO, it would have been better for them to just call it a void * and be done with it.  They think they have made it cleaner, but they’ve actually made it worse.

What a great way to end a Friday.

Posted in Codemonkeying Tagged

Python programs for Windows with py2exe

If you know me, you know that I don’t often acknowledge the existence of Windows as an OS worth my attention.  However, I’m working on some code for a group of people who are predominantly Windows users that, aside from their choice of OS, are pretty quality individuals.  Since I would certainly not spend my time writing a native win32 application, I decided to use Python, which is one of my preferred languages for Linux.

I knew that Python ran on Windows, but I didn’t realize how extensive the list of necessary add-on packages would be; I’m spoiled by modern Linux distributions.  For this app, I would need Python, pyGTK, and pySerial.  Those packages require the GTK runtime, the win32all package, pygobject, and pycairo.  Thus, any poor Windows user would be stuck installing a raft of packages totalling about 50MB (download size) before they could run the app.

I figured there had to be a better way.  I had considered getting the source for all of the python code and putting it into a single tree and rebuilding the installer to install them all at once, but that wouldn’t cover GTK and would be a bit of a pain.  After a bit of searching, I came across py2exe.

This nifty little tool extends the python distutils and gives you a new build target.  During the build process, it determines all of the required Python packages that your app will need and copies them into a distribution directory.  It then copies in the Python runtime itself, as well as any necessary DLLs to run.  Finally, it turns your toplevel .py file into a .exe.  Zip that up and post it.  All someone needs to do is extract it and run your .exe file.  How nice is that?

Given that pyGTK is rather large and complex, it didn’t go as smoothly as it should have.  I had to do two extra things: Add a list of required packages to assist the detection and copy in the GTK share files.  My setup.py ended up like this:

from distutils.core import setup
import py2exe

opts = {
“py2exe” : {
“includes” : “pango,atk,gobject,cairo,pangocairo”,
}
}

setup(windows=[“mainapp.py”], options=opts)

After building, you get a nice “dist/” (or, in the backwards Windows world, “dist”Smilie: ;) directory.  To complete the GTK distribution, I copied the share, etc, and lib directories from C:GTK into dist.  To cut down on the extra crap, I also deleted everything but “en” from the “share/locale” directory.  The result is a nice and neat little package that OS-challenged people can handle.  I think I’ll also need to figure out how MacOS distributes such things at some point, but I’m sure there will be less groaning and eye-rolling during that process.

Posted in Codemonkeying Tagged ,