NetDVD: Building a Network-Attached Peripheral with Linux

Use Linux to build your own network-attached peripheral.
User Control without a Keyboard or Monitor

Although we usually had a monitor and keyboard hooked up to the NetDVD device during development, it is meant to appear to the customer as if it were a network-based peripheral, like a network printer. Because the user cannot type shutdown -h now to tell the NetDVD to shut down, it must do a clean shutdown when the user presses the power button.

Conveniently, modern motherboards supply the Advanced Configuration and Power Interface (ACPI). When the user presses the power button, the motherboard sends a signal to the processor. Then the processor is responsible for actually shutting the computer off. Linux has good support for this interface, so all we had to do was install the acpid Ubuntu package. This package comes already configured to do a clean shutdown when the power button is pressed.

But, a clean shutdown takes several seconds to complete. If the device doesn't appear to respond immediately to the power button press, a user is likely to press it repeatedly, maybe even hold it down for several seconds. This is both frustrating for the user and potentially harmful to the device, because holding down the power button forces the machine to power off immediately before the shutdown is complete.

So, we needed a way to tell the user, “I got your message. I'm turning off now. Give me a minute.” As the NetDVD has no display, the natural choice was to beep using its PC speaker. For this we used the beep program written by Johnathan Nightingale. The beep package isn't part of the base Ubuntu installation, but it's still available from Ubuntu's Universe archives. Using this program, I wrote some init scripts that would make the machine start beeping once per second during boot up or shutdown and finish with an upward or downward arpeggio of beeps, respectively. This had the added benefit of informing the user when the device was ready for client connections. Unfortunately, it wasn't quite enough.

Several seconds still would pass between the user pressing the power button and the first beep. To make the NetDVD start beeping immediately, I edited the shell script responsible for responding to the power button press, /etc/acpi/, so it invokes my beep-start init script immediately before running the shutdown command. With this change, the NetDVD starts beeping immediately in response to the power button press.

Handling Network Configuration

Because the NetDVD device must communicate over a TCP/IP network, the user must have some way to tell it what IP address, network mask and default router to use. This is a tricky problem, because you can't easily communicate with a machine that doesn't have its network parameters set properly. Thankfully, all machines on the same subnet can receive UDP broadcast packets even if they aren't configured properly for that subnet. So, I designed a simple protocol allowing a client machine to locate and configure NetDVD devices on its subnet using UDP broadcast.

To locate NetDVD devices on its subnet, the client program broadcasts a packet asking all NetDVD devices to respond. When a NetDVD device sees this packet, it responds by broadcasting its Ethernet MAC address and other network parameters to the UDP port specified in the request. The client program receives this information and displays it to the user. Users will know which NetDVD device they want to configure, because every NetDVD device has a label displaying its Ethernet MAC address.

To reconfigure a NetDVD device on its subnet, the client program broadcasts a packet containing the target device's Ethernet MAC address and the network parameters it should use. The target NetDVD will reconfigure its network parameters and broadcast a response back to the client's UDP port. All other NetDVD devices ignore the request.

In order to make this scheme work, I had to disable the spoofprotect Linux kernel feature by changing spoofprotect=yes to spoofprotect=no in /etc/network/options on the NetDVD device. The spoofprotect feature causes the kernel to ignore packets that come from the local subnet but appear to come from an invalid IP address for that subnet. If we left this feature enabled, a NetDVD with incorrect network parameters would ignore the UDP packets intended to correct them.

Hardware and OS Problems

Once we got things working and started really exercising our prototype, we began having problems with burn failures. After discussing the issue with Ed Jamison at MBX, we decided the problem was the laptop-size DVD burner. Due to their small size, these burners have more reliability problems than the full-size drives. He recommended switching to a Plextor PX-716A 16x Double Layer DVD+RW/-RW drive. Plextor has a reputation for making extremely reliable DVD burners, and this drive is also capable of faster burn speeds than the laptop drive we were using, which our customers will appreciate.

Sadly, this meant we couldn't use the little Casetronic C134 case we loved so much. But, moving to a larger case meant we could move to hardware that was less expensive and more stable overall. As a result, we got a faster processor, a faster and larger hard drive and a Gigabit Ethernet interface. Just as important, we reduced the problems we'll have in the future due to obsoleted hardware, because desktop hardware generally stays on the market much longer than laptop hardware. Because we still were trying to minimize the size of the device, Ed recommended the Aria case from Antec shown in Figure 2.

Figure 2. Second prototype NetDVD in Antec Aria Case

Figure 3. Inside of Case

By this time, we were using Ubuntu 5.04 Hoary Hedgehog, but when I tried to install it on the new machine, it hung while detecting network devices. After a little research, we discovered that the SysKonnect SK-98xx Gigabit Ethernet interface on the Intel D915GUXLK motherboard we were using wasn't supported properly by the Linux 2.6.10 kernel provided with Ubuntu 5.04. Luckily, a kernel patch was available from the manufacturer, so I downloaded the kernel source code, applied the patch and rebuilt the kernel.

That fixed the problem with the Ethernet controller, but the kernel also had trouble with the motherboard's ACPI. This caused a lot of boot error messages and prevented the machine from handling a power button press correctly. To fix this problem, I had to upgrade to Linux and apply the Gigabit Ethernet driver patch to that. This was difficult to get right, because Ubuntu didn't have a package for that version of the kernel. I had to do a lot of experimentation with kernel parameters before I was sure I had all of the kernel features that Ubuntu relied upon.

Once the kernel problems were settled and we had the machine functioning as a NetDVD, we discovered another problem. The DVD burns actually were taking longer than they had with the original hardware, and the DVD activity light showed that the drive was frequently idle during the burn. The Ubuntu installation had not enabled Direct Memory Access (DMA) for the drive, so the drive wasn't getting data fast enough. Once we corrected this, the burns came up to the speed we had expected. It's really a tribute to the quality of the Plextor DVD drive that it successfully burned several DVDs even when it was starved for data.

When Ubuntu 5.10 Breezy Badger came out, I was pleased to find it corrected all of the problems that required a custom kernel build, but it introduced another problem I had no idea how to correct. In Ubuntu 5.10, exportfs fails sporadically, though it always exits with a 0 status. This isn't much of a problem for static exports, but as all of our exports are dynamic, it's a serious problem for us. So, we had to go back to Ubuntu 5.04.