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:
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:
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:
The destinations were: AK(2), ID, UT. MT, TN, AZ, TX, MN, NV, British Columbia, and Alberta.
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 :)
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:
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.
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:
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.
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
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?
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:
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.
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, ...) { . . . 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.
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:
After building, you get a nice "dist/" (or, in the backwards Windows world, "\dist") 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.
I've never had to debug a multi-process program with GDB before. Mostly because I do a lot of my debugging with printf() and elbow-grease. However, a CIM provider is in an environment where a crash happen within the broker, which means you can't (easily) add print statements to the appropriate place. If you pass something broken to a CBFoo() call, the CIMOM will crash a ways down the line.
With Pegsus, you can turn off provider processes, which forces thread-only mode. This means that the whole CIMOM is vulnerable to a bad provider, but it also means that running the cimserver in gdb is easy and straightforward. Doing the same in SFCB, however, is not as simple. Your bad provider ends up in a child of the main process, which crashes without GDB's full attention, which isn't very helpful.
While helping to debug a particularly nasty crash with an Indication provider, I learned a (relatively) easy way to catch the crash with GDB. First, I started SFCB and subscribed to the indication. This forked off a process to host the provider. While in the simple case, the PID of the new process will be the highest-numbered sfcbd process, you can also find out which one it is with something like this:
% PROV=libVirtComputerSystemIndication % for i in $(ps ax | grep sfcbd | awk '{print $1}'); do > grep -q $PROV /proc/$i/maps && echo $i; > done
That checks all of the currently running sfcbd processes to see which has your provider loaded and prints the PID. Next, I attached to the process with gdb and allowed it to continue:
% S gdb /usr/local/sbin/sfcbd GNU gdb 6.6 Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "x86_64-suse-linux"... Using host libthread_db library "/lib64/libthread_db.so.1". (gdb) attach 5832 <snip> (gdb) c
Next, I triggered the crash and GDB caught it, allowing me to get a stack trace and examime the situation a little. After that, figuring out the issue was easy.
One of the nice things about getting the upstairs movie room finally bootstrapped is the return to having a real Dolby Digital receiver and more than just stereo sound. I've always been a big fan of loud bass-booming movies with surround sound, but we decided to put the receiver in a closet until the upstairs was ready, instead of sqeezing it into the living room.
The last time I was really using a receiver, I didn't have an HDTV, and thus didn't have an HD capture card for Myth. This meant that analog stereo out to the receiver was about as good as anything. At the time, I didn't have a Myth machine fast enough to reliably do DVDs, so digital audio was pointless.
Yesterday I set out to get S/PDIF output working from the Myth machine to the receiver. My Myth machines all netboot a read-only copy of FC6 from a server on the network, so upgrading too much software and certainly bumping to a newer version of Fedora is a bit of an ordeal; I was hoping that FC6 would have everything I needed.
I started reading about digital sound with myth, and decided that most of the configuration should be done for me already. I downed the box, and put in a spare SoundBlaster Live! card that I had lying around. The card has a "digital output" jack on the back, which I connected to the Coaxial digital input of the receiver with a mono headphone-to-RCA adapter.
If I used something like mplayer to just play audio files (or a DVD) directly, I could see digital audio going to the receiver, but only stereo, and not Dolby Digital. I think this is to be expected, as I wasn't telling mplayer to pass the AC3 stream directly to the card. Thus, alsa, or mplayer, or something, was dumping the regular audio out over the digital connection. A good start, but not quite enough.
So, after reading a howto, I tried the following command:
mplayer -ac hwac3 -ao alsa:spdif dvd://
From this, I would get nothing. Not even regular 2-channel audio. Not even a blip on the receiver that something had happened on the digital audio line. So I played around with things, including the mixer, and lots of mplayer settings. I couldn't figure out why the raw dump of the AC3 stream wasn't working. In my frustration, I tried turning back on the integrated sound, since ALSA claimed that it had a subdevice for IEC958 (S/PDIF) audio. However, pointing mplayer at that resulted in an error, instead of just the appearance of playback without any actual sound (which is what the SoundBlaster was doing).
I put the SoundBlaster back in and fiddled some more. I could see that the subdevice listing showed the analog surround output jacks, but no IEC958 like the integrated audio had:
I figured that perhaps one of these subdevices was actually responsible for the digital audio, but perhaps ALSA wasn't detecting it. So, I started pointing mplayer directly at the subdevices hoping to get a result:
mplayer -ac hwac3 -ao alsa:device=hw=0.2 dvd://
Finally, I saw the blue "Multichannel Decoding" light illuminate on the receiver and the Dolby Digital logo appear! The receiver reported 6.1 channel decoding and everything. I was curious if I had just picked the right subdevice right off, so I tried hw=0.1 and hw=0.0, and both worked just the same. Confused about this, I tried without a subdevice using just hw=0 and that also worked. I then thought that perhaps it was the ALSA aliases that were misdirecting the audio, but device=default worked as well. So, it appears that only the spdif alias was wrong, and that unless you tell mplayer otherwise, it tries that alias.
So, I set off to get Myth setup to pass the AC3 from HD programs through to the card in a similar fashion. Analog recordings already worked by just sending the stereo audio out the digital output. To configure the passthrough, I went into Setup->Setup->General, and on the third page, I enabled AC3 and DTS to SPDIF passthrough. I also left the passthrough device as "Default", even though the SPDIF device was an option.
After these changes, I can watch HD programs and DVDs through Myth with full 6.1 Dolby Digital or DTS surround sound!