If you build it they will come.
Well I built it and nobody came. At least not yet. PiBox has one developer: Me. Seriously. That’s it. Let’s face it: I’m far better at coding than selling. Not that I care that much since if I did I wouldn’t still be doing this. PiBox is an obsession. Not like gaming or tweeting or even shoes. More like running or The Great British Baking Show. You know: a healthy obsession. Or at least I keep telling myself that.
It took a few years for the core development platform (re: the build system) to stabilize and become exactly what I’d hoped: easy to use. I can flip it around to any platform with only a little effort figuring out the toolchain requirements. But then PiBox needed a new direction. A custom distribution doesn’t do much on it’s own. It needs applications. Typically end users like to drop an AMP (Apache, MySQL and PHP) stack on a Linux distribution, or the more modern variations that provide Python and/or NodeJS. That stack is a collection of software providing a set of services beyond what might be provided by the Linux distribution. But even with that stack there still isn’t an actual application, only an idea with no substance. Kind of like Lost. Or Republican health care.
Software stacks are an old idea. I remember discussing them with Ada Lovelace (yes, I’m older than the hills). They are, in fact, a core part of every electronic product consumers purchase. Each stack is a set of middle-tier software providing services required to make the consumer facing software perform in the most efficient and secure method possible. The web world calls these stacks frameworks. Potato, Potahto. It’s a bunch of software supporting your shiny new box. But software stacks are everywhere. Consumer products without software stacks these days are known as pet rocks.
But back to my problem with finding a new direction for PiBox. When I started to implement a few consumer facing applications I quickly found that the apps shared a need for some common services. One of the first was the ability to configure the network. There are a bunch of network configuration tools out there already: Network Manager, Connman, etc. These are generally UI tools tied to UI frameworks like GNOME or KDE. But surprisingly I was unable to find any libraries for doing the same thing.
Since the existing tools required environments I wasn’t working with I decided to build my own network tools. Initially I implemented a C program (pibox-network-config, a.k.a. pnc) that provided a series of functions to configure Debian-style networking. Then, as an experiment and to learn a little about Javascript, I implemented the same UI as a web application. This made me move the code out of pnc and into another application, piboxd which is a daemon that provides services that require root privileges. But before I moved it there I needed to extract it from pnc, which then turned into a library I could link to piboxd. The beginnings of the middleware software stack were staring me in the face.
Once I realized these middle layers would need to be established before creating any apps I went looking for examples of how I should create a stack. The best example I found was the Android stack. Android splits the stack into three middle components: an application framework, support libraries and hardware abstraction. The framework layer builds on APIs in the support libraries which in turn build on the hardware abstraction APIs. This is a simplified description but the gist is that this stack provided a simple template for the PiBox stack.
The PiBox stack starts with a layer of 3rd party software at the OS layer, most of which comes from one GitHub repository or another. These provide basic support for the Raspberry Pi but could just as easily provide support for other hardware. It also provides the custom Linux distribution through the use of Buildroot and BusyBox, which provide a basic set of utilities. This layer, plus the pnc application and libpnc (which is generated as part of the pnc build), provide the PiBox Core Distribution.
Just above this layer are additional third party tools for networking. While these tools are included in the core distribution their configuration varies on the use case for higher layer software. Above this are the configuration files for various components, from hardware support to networking to the UI to a stock web server (sans content). Again, these are stock configurations that are often updated the specific use cases. One of the most interesting of these is the custom mdev device handling, specifically with respect to USB devices which is really the only expansion bus available on the Raspberry Pi.
The next layer contains two custom libraries, libpnc and libpibox, is also part of the core distribution. The former is the network configuration library mentioned earlier. The latter provides a set of utility functions for applications such as touch screen support, debugging and Raspberry Pi bootloader configuration. While libpibox is included in the core distribution, libpibox is a separate opkg installed package. At this point, everything higher in the stack is installed as a separate opkg package.
A set of packages are used to customize the UI. The psplash package is a simple boot logo for miot, the overriding idea of “My IoT”. The pmsui package provides a GTK+-based theme wrapping the Matchbox window stacked window manager. The stacked window manager implements one of the design intents for applications: only one application runs at a time and is the only application visible. This attempts (but doesn’t quite manage) to follow the principles found at suckless.org.
The appmgr package is a daemon that handles starting and stopping apps under the X.org server. This app has no UI and it’s primary duty is to start and keep running the launcher. The launcher is a package that displays icons for the available apps and handles app selection through either an input device or a touchscreen. The launcher is modeled after launchers available on smartphones or, more accurately, the Roku interface.
The backbone of the software stack if piboxd, a daemon responsible for message passing between apps. Think of this as a really bad dbus implementation, but for the sake of trying to keep the suckless philosophy as much as possible. It also doesn’t handle network port proxy. It’s just a message passing interface. It also happens to handle performing actions that non-privileged apps cannot such as network configuration.
All of these layers provide the services required for applications to do something useful under PiBox. The top layer in the above diagram shows the many apps created using these services, including a few dependent third party packages like the Raspberry Pi omxplayer. Together, these form the structures of the multiple PiBox projects: the media system, the kiosk, and IronMan home automation. And they show the potential for many new projects that are possible.
The stack will continue to grow for PiBox, providing services that are yet unrequested. But the goals will remain the same: keep them simple, keep them small and then tie them together. It’s the Unix way. And it still makes sense.