Voice Announcements via Modem

We have a PBX system through which it’s possible to make announcements, some of which I find myself making regularly.  Having an old voice modem lying about, I decided to program it to make regular announcements for me.

Rather than dedicate a modem to voice announcements, I decided to share a modem that’s also used for HylaFAX, on the principle that the less hardware to have to worry about, the better.  HylaFAX shares a locking system with minicom, meaning that if I use minicom for the voice announcements, I don’t have to worry about who has control of the modem, or of relinquishing control to HylaFAX.

I located an ancient voice command  manual for my US Robotics voice modem online.  While it took some trial-and-error, I eventually whanged together this script:

if [ "$1" = "--help" ] || [ "$1" = "" ] || [ "$2" = "" ]; then
echo 1>&2 Usage: $0 [# to dial] [voicefile.rmd]
echo --help      this message
exit 1
cd /tmp
echo print "starting" > /tmp/minicom.$PID
echo send "ATZ" >> /tmp/minicom.$PID
echo expect { >> /tmp/minicom.$PID
echo \"OK\" >> /tmp/minicom.$PID
echo } >> /tmp/minicom.$PID
echo send "AT#CLS=8" >> /tmp/minicom.$PID
echo expect { >> /tmp/minicom.$PID
echo \"OK\" >> /tmp/minicom.$PID
echo } >> /tmp/minicom.$PID
echo send "AT#VRN=0" >> /tmp/minicom.$PID
echo expect { >> /tmp/minicom.$PID
echo \"OK\" >> /tmp/minicom.$PID
echo } >> /tmp/minicom.$PID
echo send "AT#VRA=0" >> /tmp/minicom.$PID
echo expect { >> /tmp/minicom.$PID
echo \"OK\" >> /tmp/minicom.$PID
echo } >> /tmp/minicom.$PID
echo send "AT#VSM=129,8000" >> /tmp/minicom.$PID
echo expect { >> /tmp/minicom.$PID
echo \"OK\" >> /tmp/minicom.$PID
echo } >> /tmp/minicom.$PID
echo send "ATS46=255" >> /tmp/minicom.$PID
echo expect { >> /tmp/minicom.$PID
echo \"OK\" >> /tmp/minicom.$PID
echo } >> /tmp/minicom.$PID
echo send "AT#VRA=0" >> /tmp/minicom.$PID
echo expect { >> /tmp/minicom.$PID
echo \"OK\" >> /tmp/minicom.$PID
echo } >> /tmp/minicom.$PID
echo send "ATDT,$1" >> /tmp/minicom.$PID
echo expect { >> /tmp/minicom.$PID
echo \"VCON\" >> /tmp/minicom.$PID
echo } >> /tmp/minicom.$PID
echo "sleep 1" >> /tmp/minicom.$PID
# here's the voice part
echo send "AT#VTX" >> /tmp/minicom.$PID
echo expect { >> /tmp/minicom.$PID
echo \"CONNECT\" >> /tmp/minicom.$PID
echo } >> /tmp/minicom.$PID
echo "sleep 1" >> /tmp/minicom.$PID
echo "! cp $2 /dev/ttyUSB0" >> /tmp/minicom.$PID
# end
echo >> /tmp/minicom.$PID
echo sleep 2 >> /tmp/minicom.$PID
echo ! killall minicom >> /tmp/minicom.$PID
/usr/bin/minicom -S /tmp/minicom.$PID
cat /tmp/minicom.$PID
rm /tmp/minicom.$PID

It’s fairly linear — it puts the modem into voice mode, sets a number of parameters, and escapes to the shell to copy a file to the device.  What remained is to create a file in a format that the modem could consume.

Luckily, Ubuntu has a package called mgetty-pvftools which contains all the binary files necessary to make it happen.  (These files are bundled with vgetty on Gentoo, but vgetty conflicts with HylaFAX, and all I need are the audio conversion binaries.)

It’s several steps to convert, but this script does it handily:

if [ "$1" = "--help" ] || [ "$1" = "" ] || [ "$2" = "" ]; then
echo 1>&2 Usage: $0 [from.mp3] [to.rmd]
echo --help      this message
exit 1
echo "mp3->wav"
sox -V --norm $1 -r 8k -c 1 /tmp/$PID.wav
echo "wav->pvf"
wavtopvf /tmp/$PID.wav /tmp/$PID.pvf
echo "pvf->rmd"
pvftormd US_Robotics 4 /tmp/$PID.pvf $2
rm /tmp/$PID.wav
rm /tmp/$PID.pvf

So, all that’s left to do is to set up the first script in an “at” or “cron” job.  However, it turns out that minicom requires an interactive terminal to run, so simply running the first script from an “at” job resulted in this error:

No cursor motion capability (cm)

Since the script will run minicom without being attended, a simple way around this is to use the “screen” program to provide an interactive terminal for minicom to use within cron/at:

screen -d -m announce.sh 111 announcefile.rmd

LED Isolators for HDD LEDs

LED Isolator

LED Isolator

A while ago, I posted a design for a home-made circuit designed to connect multiple hard drive add-on cards (and the motherboard) to a single case LED.  I made a handful of these for the servers around here, and in the three years or so since then, I’ve yet to see anything similar.  It’s possible that nobody but me actually cares if their case light reflects drive activity across all their drives — then again, it’s also possible that the people who actually cared simply made their own.

On the off chance that anybody wants one, I went to the trouble of making some professional-looking boards.  More detail is available here.


Fun with the Secretary of State

A short while ago, I was traveling through New York, and somehow managed to leave my driver’s license with the TSA. This wouldn’t have been so bad, except that I needed to fly out of Chicago the next day, and I needed to rent a car at my final destination, which probably isn’t possible without an actual driver’s license.

My strategy was to go to the Secretary of State’s office downtown (this is the Illinois equivalent of the DMV) before it opened, in what seemed like a futile effort to acquire a license before I needed to be at the airport. Fifteen minutes before it opened, there was already a crowd of fifteen people waiting for the doors to open.

After a moment, a lady with a clipboard came out, carefully locking the door behind her. She announced that she would be coming to each of us in the order that we showed up, and giving us numbers to speed things along. She came to each of us and asked why we were there and confirm that we had the required documentation. Ahead of me in line:

  • A man from Michigan wanting an Illinois driver’s license, who didn’t have his Michigan license because he lost it for driving under the influence. (Sent away)
  • A woman who wanted a state ID, but didn’t have her Social Security card, because it “got wet.” (Sent away, with the suggestion that she replace that first.)
  • A man in a suit with some kind of letter instead of one of the required documents. “They told me over the phone this would be sufficient,” he insisted. “Nobody told you that,” she said flatly, and sent him away.
  • A teenager with no paperwork whatsoever, seeking a state ID. (Sent away.)
  • A man seeking a driver’s license. After looking at his paperwork, she asked, “where do you live?” “Indiana,” he answered. She politely explained that you have to live in Illinois to get an Illinois driver’s license, and sent him away.

After a few variations on the above, she got to me last, and I showed her my paperwork, she handed me the number two. The doors opened, and $5 and 5 minutes later, I was holding a brand new driver’s license. I was utterly unprepared for this jaw-dropping display of government efficiency, which left me with plenty of time to catch my flight — time enough to go home first.

At home, the TSA from New York called, to let me know they had my driver’s license, which they offered to send me immediately. (Since I had to fly in a few hours, I would have needed a duplicate anyway, but I received my old license the next day.)

I contrast this sharply with my experience just a few years earlier at the same office of the same agency. I received in the mail a renewal notice for my license plates that had somebody else’s name on it. I tried calling first, and after an hour on hold, was informed that I’d have to go sort it out in person, and bring the physical license plates from my car.

After another hour and a half waiting in line, I explained the situation to the bored, slow-moving woman behind the counter who didn’t quite appear to be listening. “You want to change your name?”

I explained again that the name on my renewal notice was wrong, and handed her my license plates. She looked at the plates, at my renewal notice, and my driver’s license. After a few minutes of contemplation, she typed something into her computer.

“These aren’t your plates.”

Now we’re getting somewhere. “So, how do I get this corrected?”

“You have to bring in both sets of plates,” she explained.

“This is the only set I have. This is the set I was given… by you guys,” I tried to clarify further. “I only have one set.”

“Well, these are the ones you have to bring in,” she said, and gave me a plate number nothing like the ones I’d placed on the desk.

“So, you want me to find these license plates somewhere in the State of Illinois, detach them from whoever’s car they’re mounted on, and bring them in?”

“That’s right,” she beamed, apparently pleased that she had finally gotten through to me.

“So… Do you think the person whose name is on my renewal form has those plates?”

(blank stare)

“So… Can you tell me where you mailed the renewal notice for my plates?”

She looked this up on her computer, and compared it to the address on my driver’s license. “It doesn’t match your address here, so for security purposes, I can’t tell you what it is.”

“And this is the guy whose house you want me to drive to in order to retrieve the plates you sent him by mistake?”

(blank stare)

“Fine. I just want to renew these plates and correct my name.”

“You can’t do that, these aren’t your plates.”

It was my turn to stare blankly.

“You’ll get arrested if you put these on your car,” she explained slowly.

One of the two state troopers now standing immediately behind me said, “do we have a problem here?”

“If I didn’t have a problem, I don’t think I would’ve stood in line for so long,” I explained. “That’s kind of the whole point.”

Apparently deciding that I wasn’t a threat, they backed up … a little.

“Okay, look, I just want valid plates on my car that I can actually renew and that won’t get me arrested.”

She thought about this for a moment. “You can get new plates for $20 more.”

Unhappy, but with no alternatives, I handed over the money and she gave me a new set of plates.

“Just out of curiosity, are you going to tell the guy who has my plates? So he doesn’t accidentally renew them or whatever?”

“Oh, I’ve already updated the system,” she said languidly, “and there’s a warrant out for his arrest for the guy who stole your plates.”

“Wait… what? He didn’t steal my plates, you mailed them to him.”

“Yeah, but we don’t have a way to put that in the computer. I’m sure he can explain that when they pick him up.”

Epilogue: In an effort to spare some poor guy from being arrested for no particular reason, I called information and what little I knew and tried to call the guy whose name appeared on my renewal notice. The girl who answered the phone said he’d already sold the car “to some guy out of state.”


No Good Samaritan … Something Something

After witnessing several hundred seizures at the rehabilitation center where I worked, I came to recognize the early signs of a seizure.  They may be different for many people, but often there was a glassy look, a slight roll of the eyes, a twitch … some little sign that something major was about to happen.

In the days when the El actually had a conductor as well as an engineer — on a train with no seats available, and a smattering of people standing or leaning around the doors, I stood in the aisle.  In those days, it was common to see people walking between the trains, and it wasn’t unusual for people to pull the emergency cord at every stop.

An old man got in the train and made his way over to the aisle facing me as the train groaned and lurched forward.  He nodded slightly by way of greeting, then winked a little … then winked a bit more, with his eyes rolling back a bit … As he fell stiffly backwards, I took a look at where he was falling, and saw nothing but hard surfaces and metal seat supports everywhere.  I’ve seen people injure themselves with fewer hazards around during a grand mal, so I caught the old man, pulled him toward the doors where there was more room in the car, and held my hand under his head so it wouldn’t bang on the floor.

After a few minutes, the old man had stopped seizing and fallen into a deep sleep.  I checked to make sure he was breathing and stood up.  I now noticed that the train was stopped in the station, and all of the passengers had left the car.  The conductor made a nearly incomprehensible announcement over the PA system that the train would be stopped for a while.

The conductor walked over and I explained what happened.  He mentioned that he had called for paramedics and he’d appreciate it if I explained to them directly.  Within moments, they were carrying away the man on a gurney.  They didn’t ask me anything right there, but one of them said, “come with us” as they carried the gurney down the steps to the waiting ambulance.

It was a short trip to the hospital and they asked me to sit in the emergency room waiting room and they’d be back shortly to get my information.  At this point, I wasn’t entirely clear on what useful information I could provide, but thought they may have some more specific questions about anything I might have noticed that could be medically relevant.  Whatever it was, I hoped they would hurry up, since I was already pretty late for work.

After a while, a nurse came out, and said, “We have a few questions for you, if you don’t mind.”

“Finally!”  I said, “What would you like to know?”

“Well, first, what kind of insurance does your dad have?”

“What?”  I said, slightly off kilter.  “Did something happen to my dad?”  (In addition to being perfectly fine, my father was 800 miles away, so it was a nonsensical question, but it didn’t immediately occur to me why she asked.

“Your dad’s had a seizure.  Didn’t you come here with him?”

“No,” I said slowly.  “I came here with a man who had a seizure on the train, whom I do not actually know at all.  I don’t even know his name.”

At this, the nurse seemed slightly incredulous, as if I were involved in some kind of insurance scam.  “Why would you come all the way to the hospital and wait for somebody you don’t even know?”

At this moment, the paramedic who said, “come with us” walked through the waiting room.  I pointed to him and said, “because that guy asked me to.”

The paramedic gave me a sheepish grin, and explained, “uh, sorry, the conductor figured you must be related since you didn’t just leave the guy there.”

I had a heck of a time explaining why I was so late for work.


BackupPC and Bare Metal Restore of Windows XP

While it’s not well documented, it’s possible to do a bare-metal restore of a machine running Windows XP that’s been backed up via BackupPC (assuming, of course, that some method, such as that documented here, has been used to back up open files, such as the registry.)

Step 1:  Build a local tar file using BackupPC_tarCreate

The alternative, BackupPC_zipCreate, proved problematic; the gigantic archives that it created could not be completely recovered, yet tar archives proved intact.  At any rate, this is best accomplished from the command line, as the backuppc user:

BackupPC_tarCreate -t -n -1 -h borkstation -s C / > borkstation.tar

“borkstation” is the name of the host to recover, “-n -1” means the latest backup, and you’ll obviously need to have enough space where the tar file is going to store the entire backup, which will not be compressed.  Note the space between the “C”, which represents the share to restore, and the “/”, which represents the directory to restore.

Step 2:  Prepare bare XP

Basically, you want to install a working copy of the operating system.  Aside from network drivers, it really doesn’t matter if anything’s installed or working, you’re going to wipe it all out anyway.  The filesystem and the partitions will stay, so configure those the way that you want your system to finally end up.

Step 3:  Prepare Recovery Console

Using the same install CD, you can install the recovery console to speed things up a little versus booting from the CD, although either option will work.  To install the recovery console, use Start->Run, then

d:\i386\winnt32.exe /cmdcons

Where D: is the letter if the CD-ROM.  Whether you choose to install it or not isn’t really important, but what is important is that you open up the permissions for Recovery Console, or some of the remaining steps won’t work.

  1. Start->Run, then type secpol.msc
  2. Go to Security settings->Local policies->Security options
  3. Scroll down to “Recovery console: Allow floppy copy and access to all drives and all folders” and make sure it is enabled.

Step 4:  Install Cygwin

You’ll need a “tar” utility you can rely on for the next step, and experimenting with a plethora of them has shown that unless you build your own, you’ll really need Cygwin.  While installing, be sure to select the gnu tar package.  (Unless your backup contains Cygwin, you can just delete the c:\cygwin directory later to get rid of it all.)

Step 5: Unpack the tar file to the local drive

A prerequisite to this step is that you get access to the tar file created in step 1 — which you’ll have to wait for if it isn’t finished being built yet.  The simplest way to get access to the file is to map a drive to the *nix box that has the tar file. I mapped mine to the Z: drive, which was a pretty arbitrary choice.

Next, create a directory to put the recovered files into, because you do not want them going into the root directory yet.  I created a directory called “recovery.”  Launch Cygwin, then:

cd /cygdrive/c/recovery
tar -xvf /cygdrive/z/borkstation.tar

This part takes a while, but when it’s complete, the entire system as backed up will be in the c:\recovery directory.  N.B.:  this goes a little faster if you leave off the “v” parameter, but then you don’t see anything in the way of progress.  It also helps to occlude or minimize the cygwin window.

Step 6:  Rename and move files

There are three hardcoded paths in XP, that are probably the only folders in root on your minimal installation:  Program Files, Documents and Settings, and WINDOWS.  Within the c:\recovery directory, rename these to something else.  I chose “Program Files.recovery” and so on.

Once these three directories are renamed, cut and paste everything from c:\recovery to c:\.  There’s no need to replace any files in c:\, and there shouldn’t be any overlaps, so if Windows asks if you want to overwrite any files, say “no.”

Step 7:  Boot to Recovery Console and rename key folders

Here’s where Step 3 becomes pretty important.  Once you boot into Recovery Console, you’ll need to allow yourself to work in the root of the drive using the “set” command:

set AllowAllPaths = TRUE

Once that’s done, you can rename the three hardcoded directory paths, moving the originals out of the way for your recovered files.  For the sake of having a fallback position, I rename rather than delete them at this point:

ren "Program Files" "Program Files.delete"
ren "Program Files.recovery" "Program Files"
ren "Documents and Settings" "Documents and Settings.delete"
ren "Documents and Settings.recovery" "Documents and Settings"
ren WINDOWS.recovery WINDOWS

The suffix “.delete” has no inherent meaning, it just gets the folders out of the way and signals that I don’t need them any more.  Once this is done, and you’re sure there were no unfortunate typos, you can type “exit” to reboot to a recovered system.

Step 8:  Clean up

After rebooting, pretty much everything should be as it was, although you’ll have three extra directories with a “.deleted” suffix plus the cygwin directory to get rid of.  It may be necessary to take ownership and grant yourself permission to do so, but there’s really no reason not to wipe them all out, since your original folders and files should be intact.

While the “read only” flag has been preserved for recovered files, the “hidden” and “system” attributes have not.  For most files, this doesn’t seem to matter much, but the “desktop.ini” files that dot the drives can have weird side effects, like launching an editor upon boot and showing up.  It’s easy enough to fix from the command line:

cd \
attrib +h +s /s desktop.ini

This will grind away for a while, since it will reset all the desktop.ini files on the drive.  Once complete, you’re back to where you were upon your last backup.


Hyper-V Serial Ports and Windows 2008

Unlike many other virtualization solutions, it’s not particularly easy to connect a Windows 2008 Hyper-V guest to its host serial ports.  Perversely, there are settings to connect the guest COM ports to “named pipes,” but there’s no way on the host to connect COM ports to named pipes.  (It appears that this option is used primarily for debugging programs, rather than for using actual serial ports — it doesn’t appear to have been intended to be used to provide actual serial port access from the guest.)

The Hyper-V Deployment guide contains little more than this:

“Note:  No access to a physical COM port is available from a virtual machine.”

What follows is a recipe to access the physical COM ports on the host from a guest using com0com, and its related utilities.  The idea is to make a COM port on the host available via TCP/IP, and then attach to it via the guest, then make this process automatic.

First, on the guest, you’ll need an appropriate version of hub4com, and the batch file bundled with it, com2tcp-rfc2217.bat.  Naturally, I’m running 64-bit Windows 2008, and there doesn’t appear to be a version compiled for 64-bit Windows, so I had to compile my own.  This can be kind of a pain, especially if you’re using Visual Studio Express, so you’re welcome to download my 64-bit hub2com binaries here.

My device is on COM3, and I can make it available on port 7000 using the following command line:

com2tcp-rfc2217 COM3 7000

This gives me a DOS Window that shows me what’s going on — this is handy for debugging, but hardly something I want to leave on my screen all the time.  The simplest solution is to create a launcher script:

Set objShell = CreateObject ("WScript.Shell")
objShell.Run "cmd /K CD C:\Program Files (x86)\com0com & com2tcp-rfc2217 COM3 7000", 0, false

This script effectively hides the program so that it can run in the background, so all that remains is to have it launch when the system starts.  That’s best accomplished using the registry to create a new “Expandable String Value” under “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run”.  It doesn’t matter what the Name of the String Value is, but the Data should be the command line necessary to launch the script:

%WinDir%\system32\wscript "C:\Program Files (x86)\com0com\com3-listen.vbs"

When done this way, the port is made available whether or not anybody is actually logged into the machine.

The guest is only slightly trickier, requiring both com0com and hub2com binaries to be installed.  Since my guest is 32-bit Windows XP, I could use the precompiled “i386” binaries directly from the c0m0com sourceforge page.

The com0com installer wants to create a null modem pair from “cnca0” to “cncb0.”  You’ll need this pair of virtual devices, and you’ll want to turn on “baud rate emulation,” and rename one end like a regular COM port.    This can be accomplished from the com0com command line setup:

install EmuBR=yes EmuBR=yes
change CNCA0 PortName=COM3

Once the virtual port pair is available, one end can be connected to the host, using the hub2com batch file com2tcp-rfc2217:

com2tcp-rfc2217 \\.\CNCB0 host-hostname 7000

As before, this opens a DOS Window where you can see what’s going on.  At this point, COM3 on the guest is communicating directly with COM3 on the host.  As before, a small launcher script is created to hide this window:

Set objShell = CreateObject ("WScript.Shell")
objShell.Run "cmd /K CD C:\Program Files\com0com & com2tcp-rfc2217 \\.\CNCB0 skypiea 7000", 0, false

And, as before, a registry string is added to the guest to launch this automatically in its own “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run” key.

%WinDir%\system32\wscript "C:\Program Files\com0com\com3-client.vbs"

Simple, eh?  Well, perhaps not, but once it’s set up, the guest Hyper-V machine can communicate via COM3.  Additional ports can be added in the same way.


SIIG Cyber Serial under Windows 2008, or getting old drivers to work

I’m in the process of “upgrading” a server from Windows 2003 server to Windows 2008 server, and one of the things this server does is manage a few serial devices.  Therefore, it contains an old PCI serial board, but the manufacturer has since moved on to newer hardware, and hasn’t bothered to update the drivers.

Trying to install the Windows 2003 drivers yielded the following:

a service installation section in this inf is invalid

And, naturally, refused to install.  To track down the source of this error, there is a file created in \Windows\inf called “setupapi.dev” that logs details about the driver installation process.  Reading through this file, the reason for the error is evident:

inf:       ServiceBinary=C:\Windows\system32\DRIVERS\mf.sys  (mf.inf line 39)
!!!  dvi:       Add Service: Binary 'C:\Windows\system32\DRIVERS\mf.sys' for service 'mf' is not present.
!!!  inf:  {Install Inf Section [MFINSTALL.mf.Services] exit(0xe0000217)}

Intriguingly, a quick search through C:\Windows\System32\DriverStore\FileRepository showed that the driver does exist, it just happens not to be installed.  There’s a folder called mf.inf_Identifier (where “Identifier” appears to be random junk) that contains a file called mf.sys.  Copying this file into C:\Windows\System32\Drivers allowed the device drivers to install, and they appear to work perfectly well.


Tales of a Triumph

Triumph GT6+

Triumph GT6+

I once owned, and loved, a 1968 Triumph GT6+.  It had a beastly inline 6 cylinder engine with twin carburetors, and the drive wheels were attached with fancy little doodads called “rotoflex” connectors, which were essentially big rubber bands.  The net effect was that this car could move really well.

The car wasn’t without its problems — the gas gauge never worked all that well, it leaked from a few places, the carburetors would stick, and the electrical system was designed to work only when the stars and planets were perfectly aligned — none of which really dissuaded me from taking it out on lesser-used stretches of road and opening up the throttle.

After a few times of doing this, I agreed to let my girlfriend drive.  It was a much more harrowing experience from the passenger seat, for some reason, and when I wasn’t trying to climb under the seat I noticed that she had the speedometer well above the 140 mark.  In between flashes of my life up until that point, I wondered how good my tires really were.

On the way back from one of these forays, I saw flashing red and blue lights in my rear view window, clearly signaling for me to pull over.  I had just enough time to contemplate how often the third digit on police radar gets used when the cop approached the car.  I was poking through the tiny glove compartment for my insurance information when the cop said, “What year is this car?”

“Uh.  1968.”

“Can I look under the hood?” he said, with a sheepish enthusiasm.

“Sure!” I said, equally enthusiastic to not be getting a ticket, or worse.

Triumph GT6+

Triumph GT6+

While driving down Lakeshore Drive, the car’s temperamental electrical system shorted out and overheated, evidenced by some spectacular flames shooting up from the dashboard and in front of the windshield.   This had no discernible effect on the drivability of the car, so I decided to ignore it until I got home, about a mile away — since the alternative was to pull over on Lakeshore Drive (four lanes of crazy in each direction with no real shoulders or breakdown lanes) and try to fix it.

After a moment, a car pulled up beside me, its passenger gesturing wildly.  She then mouthed exaggeratedly, “your car is on fire!” while pointing frantically.

I’ll emphasize that the flames were right in front of my face.  I was looking through them to be able to drive the car down the road at all.  I paused a moment to consider what this good Samaritan thought I could possibly be looking at in order to miss the flames leaping up in front of my face?  Did she think I was sleep-driving?  Perhaps I thought the city was burning to the ground and didn’t realize my car was on fire?

In order not to dissuade this kind person from helping somebody truly stupid and in  need of having the obvious pointed out, I pretended to understand what she meant, gave her a thumbs-up, and a non-sarcastically exaggeratedly mouthed, “thanks!”

Perhaps the next life she saves will be somebody playfully pretending to ignore a “do not eat” label.


RCS TX10-B X10 Thermostat Protocol

A little over 10 years ago, I bought an open-box RCS TX10-B thermostat control unit to replace a TX10 unit.  “Open Box” means it came without any documentation, but it should, in theory, be a drop-in replacement for the TX10 — the “B” designator indicates that it’s capable of reporting status and temperature, unlike the TX10.

Unfortunately, “open box” means it came without any documentation whatsoever.  On the plus side, the wiring is similar to the TX10 (with the additional feature of a physical connection for a “setback switch”) but without knowing the X10 protocol it required, I was left without any means to actually get status reports from the unit.

3039bdgmUsing the Internet Wayback Machine to go back to 1998, I located a nifty diagram of the system from Smart Home, from whom I originally purchased the unit.  Ten years ago, it was in the process of being replaced by the TX15-B, a more modern-looking unit — and the only one mentioned on the web site of the manufacturer.

Some experimentation demonstrated that the TX10-B substantially uses the same procotol as the TX15-B, which is documented here.  It doesn’t seem to support the “autosend” feature, nor does it respond to requests for the outdoor temperature, but otherwise, the document appears to be accurate.

The unit uses the venerable TW-523 to communicate, and I was mildly surprised to discover that my TW-523 was capable of receiving, but not sending.  Since the TX10 it was connected to wasn’t capable of sending, either, it may have been defective on the day I bought it, and I’d never have known.

(Yes, it took me 10 years to get around to this project, but now all that’s left to do is the software…)


The Fujitsu Stylistic 3500 Tablet, Linux and Xubuntu

I have an old Fujistu Stylistic 3500 Tablet that I picked up cheap as hospital surplus, which usually sits in its cradle in the kitchen, handy for looking up recipes and playing music.  It came with Windows 2000 preloaded (and as surplus, ravaged by viruses) which it ran until last week, when I finally decided I have had enough of the venerable operating system, and decided to switch to something both more modern (unsurprisingly, a growing number of applications and updates refuse to run under Windows 2000 at all) and better able to make use of its aging hardware: a 500 Mhz Celeron with 256M of RAM.

Fujitsu Stylistic 3500

Fujitsu Stylistic 3500

In addition to upgrading the operating system, I decided to replace the hard drive with an IDE-SSD drive that I found on special.  This made an intuitive kind of sense, since if anything went wrong, I could just put the old hard drive back in.  On the minus side, this meant I had to install an operating system from scratch.

Hurdle #1:  Booting

The tablet is capable of booting from a grand total of two things:  the internal hard drive, and an external floppy drive on a proprietary port.  That’s it.  I do happen to have the Fujitsu floppy drive, so I figured all I have to do is boot a Linux installer from a floppy drive, and I’m all set.

Easier said than done, I guess.  The tablet has one USB port, and the tablet itself needs software to drive the pen interface, so a USB hub and keyboard are necessary, plus a mouse for virtually any operating system’s installer these days.  After some trial-and-error, I burned Xubuntu’s installer to a physical CD, and attached a CD-ROM drive to a USB->IDE interface on the same hub.

It looked like a DOS boot disk was the way to go, since the tablet couldn’t directly boot from the CD-ROM drive, and Xubuntu doesn’t seem to have a ready-made boot floppy.  Naturally, this would require keyboard, mouse, and CD-ROM to first be available to DOS.

However, certain USB drivers would disable the mouse and keyboard when they loaded — which put a damper on being able to actually do anything once they located the CD-ROM drive.  I finally located a combination of drivers that allowed my mouse and keyboard to keep working while mounting the CD-ROM drive (rather oddly, as C:, since there were no recognizable partitions on the IDE-SSD drive, it didn’t show up at all.  No problem, though, the Linux kernel will sort it out.)

Once DOS booted and I could see the CD-ROM, I used lnload97.com to actually boot the kernel from the CD-ROM.

For those wishing to follow a similar path, I present the Fujitsu Stylistic 3500 boot diskette:  [Stylistic-3500.zip]

This is based on a USB driver diskette I located and updated; if your CD-ROM doesn’t show up as C:, or you’re installing a Linux distribution other than Xubuntu 9.10, you’ll need to edit “bootl.bat” before you run it — it should be pretty straightforward.

And the first hurdle is cleared as the Xubuntu installer is able to install Xubuntu on the tablet’s new SSD hard drive.  However, I’m not out of the woods yet.

Hurdle #2:  Networking

I decided to get the network working first, because experience has shown that everything is simpler when a computer can connect to the network.  I have a PCMCIA card for connecting to the wireless network, a Netgear WN511B, that frankly was a little flaky under Windows.  Xubuntu recognizes it, sort of, but can’t communicate to it.

First, I tried ndiswrapper to load the Windows drivers, which worked in the sense that it looked like I had a wireless card, but wpa_supplicant proved unable to connect to my WPA2-encypted network.  I also tried bcm43xx-fwcutter, which failed even more dismally.

The output of my lspci led me to seek a new path:

01:00.0 Network controller: Broadcom Corporation BCM43XG (rev 01)

As it turns out, Broadcom released a proprietary driver for BCM43?? chipsets, and although the BCM43XG isn’t specifically listed on the driver’s page, it works beautifully, at full n- speeds.

The driver’s page is here:  [802.11 Linux STA driver]

Aside from everything in the README.txt listed on that page, I added “lib80211” and “wl” to /etc/modules in order to have the driver loaded on boot.  Upon booting, the card was recognized, the wireless lan came up, and … it asked for my keyring password.

On a side note, I got the driver onto the Xubuntu tablet in the first place by loading it onto a USB flash drive; Xubuntu recognized the drive right away, and it was a simple matter of copying over the file.

Hurdle #3:  Keyring Password

With a keyboard, typing a keyring password isn’t really a big deal, as I did the first time I connected to my wireless network.  Without a keyboard, this is a considerable chore, if not outright impossible.

This is pretty easy to fix — go to ~user/.gnome2/keyrings and delete the keyring, then reboot, and next time, don’t enter a keyring password at all.  While this is less secure (the keys are stored in plaintext) it does have the advantage of not having to enter the password each time.

At this point, I installed sshd, so I could log in to it remotely, and make my life a little easier.

sudo aptitude update
sudo aptitude install openssh-server

Hurdle #4:  The Touchscreen

The touchscreen on a Stylistic 3500 shows up as a serial device, and some kind soul has already written a driver for X.

sudo aptitude install xserver-xorg-input-fpit setserial

The serial device needs to be set up, too, which can be done by creating a file called “/etc/serial.conf” and adding:

/dev/ttyS1 uart 16450 port 0xfd68 irq 5 low_latency baud_base 115200 spd_normal skip_test

The next step is to add the driver to xorg.conf … except that Xubuntu, like a lot of modern Linux distributions, doesn’t actually provide or ship with xorg.conf at all, instead relying on autodetection.  So in order to get the stylus to work, one must first create an xorg.conf.  This is most easily accomplished by killing X — Xubuntu helpfully tries to respawn X, so I took the hack-ish but expedient route of putting a junk file into /etc/X11/xorg.conf (I simply wrote the word “sampo” in it, which is not a valid configuration, which keeps X from respawning) then issued a kill command to the pid running X.  Then:

X -configure

Generated an xorg.conf that I could edit to add in the touchscreen bits.  (Parts already there are in red, my additions are in black.)

Section "ServerLayout"
 Identifier     "X.org Configured"
 Screen      0  "Screen0" 0 0
 InputDevice    "Touchscreen"
 InputDevice    "Mouse0" "CorePointer"
 InputDevice    "Keyboard0" "CoreKeyboard"

Section "InputDevice"
 Identifier "Touchscreen"
 Driver "fpit"
 Option "Device" "/dev/ttyS1"
 Option "BaudRate" "9600"
 Option "Passive"
 Option "CorePointer"
 Option "SendCoreEvents"
 Option "MinimumXPosition" "0"
 Option "MinimumYPosition" "0"
 Option "TrackRandR"      "on"

And I now have a working stylus.  I spent a surprising amount of time fooling around before I discovered the “TrackRandR” configuration parameter — during which my stylus worked on a postage-stamp sized corner of the tablet while the pointer shot everywhere.

Hurdle #5: remote Administration

I can administer the tablet via sshd already, but it’s handy to have remote console access, since a lot of settings are much easier to set via a GUI than by poking around the command line.  So, to provide VNC-capability for the console:

sudo aptitude install xinetd x11vnc

I considered it a good idea to set a password:

x11vnc -storepasswd

Then created a file called /etc/xinetd.d/x11vnc to launch it on demand:

service x11vnc
 port            = 5900
 type            = UNLISTED
 socket_type     = stream
 protocol        = tcp
 wait            = no
 user            = root
 server          = /usr/bin/x11vnc
 server_args     = -inetd -o /var/log/x11vnc.log -display :0 -auth /var/lib/gdm/:0.Xauth -many -bg -rfbauth /root/.vnc/passwd
 disable         = no

Hurdle #6:  gksudo and an on-screen keyboard

I used Applications->Add/Remove to add Matchbox, an on-screen keyboard, and immediately gksu popped up to request administrative rights…  which greyed out the rest of the screen, making it impossible to actually use an on-screen keyboard to enter a password.  Luckily, this is just a setting in gksudo called “Disable-grab.”  Since I could already VNC into the tablet, this actually wasn’t much of a hurdle.


Between the IDE-SSD drive and Xubuntu, the tablet is dramatically faster than it ever was under Windows 2000.  A lot of the tablet’s use is surfing the net via Firefox, which launches and renders faster than it ever did.

Surprisingly, wireless networking is also much improved: Windows 2000 would often have trouble reconnecting to the network after rebooting, and despite being an “n” wireless card, seemed slow.  Now it’s quite stable, and runs at a full 130mbps.