Welcome to One Week Hack!

Fifty Little Projects in Fifty Weeks

OpenVLC: A Network Remote Control

By Lawrence Statton — Aug 21, 2023 12:35 pm


I have an application installed on my phone called Samba Player which I use pretty much daily.

When it launches, it puts up an activity with an icon for each of the SMB servers in the house and their name. I never told it about them, it just figured it out. I have been using it for well over a year, and I never really thought about it, just believing there is some magic that allows SMB shares to be discovered. Eventually I asked myself, "How does this magic work, and what other uses might I find for it?" This led me into the amazing and delightful world of mDNS and DNS-sd and how these things work together.

Summarizing: multicast DNS uses the over-the-wire protocol of normal DNS (with a few minor tweaks) but isntead of asking a central name server, it multicasts the requests on a specific multicast IP address and UDP port. Each device on the network who is watching that multicast address will respond to any query that is appropriate.

So, if I ask, "Who on this local network is named wizbang?", instead of a name-server that has a database mapping names to IPv4 and IPv6 addresses, the machine that knows itself to be named wizbang will respond giving its address(es)

DNS Service Discovery is another protocol that also leverages the DNS protocol stack. This allows a nameserver to have an index of service instances by defined name. If configured, you can ask your nameserver, "What are all of the instances of the frobitz service in this domain?"

There are two places that I see this consistently used "in the wild": Mail services and XMPP (Jabber). If you have configured a new mail-client in the past ten years, it probably was able to guess the correct connection type for your domain, and find the names of the appropraite servers, even if they had quirky names. Service records played a role in that.

For example, I operate a single mail-server instance that handles IMAP and mail submission protocols for many domains, yet when I set up a new domain, the users of that domain need know nothing about the specific server that will serve them, their mail client learns it through Service records. Instead, their client asks of DNS, "Is there an IMAP server for mydomain.com?" and it gives the answer, (amongst other data), "Yes — mail103f.mailvendor.com offers IMAP for this domain on port 143". (There are other services besides IMAP that can be queried, I just picked that as a concrete example.)

The magic happens when we put these two protocols together. Instead of a central server being pre-configured with answers for which machines offer specific services, each server that is prepared to provide a service can announce itself on the network and respond to requests.

If I ask "Where is there a frobitz server?, all of the Frobitz servers will respond saying, "Me! offers the Marc's Amazing Frobitz Service on UDP port 59512!

Putting This Knowledge to Use

Watching a movie on our TV from the media server is a minor hassle; using the sixteen-button remote control that came with the Android TV gadget to navigate the directory tree is an exercise in tedium, and you scroll past the video you want, and you accidentally click the "up a level" button and then you yell at your husband, and he throws your popcorn to the dogs. Not a good look.

Kneeling in front of the television to use the attached mouse is no better, it leads to physical discomfort and the occasional visit to the chiropractor. Here is an application for a network protocol! I can write an application that runs on the Android TV box that advertises itself on the network, and other devices on the network can communicate with it asking it to play videos.

Like all software engineering projects, you break it into pieces. I tackled them in roughly this order

  • Listen on a network multicast socket for a trivial trigger and send an Intent to VLC to open a (specific hard-coded) movie
  • Expand the protocol to permit the UPD packet to include a parameter as to which movie should be opened.
  • Annonce yourself on the network. You build a datastructure describing the service (giving it a human-friendly name, a service name, and the address and port number to use.) Then you pass that data structure to an instance of the Android NsdManager class using the NsdManager#registerService method.
  • Set all this up into an Android <service>, which took me longer than it honestly should have.

There are some quirks. The application appears to only be able to send Intents to VLC when it is in the foreground, so I put up a giant Cloud Transponder graphic to show that the application is listening.

In the next article, I will go on to describe the application that runs in my phone and communicates with the transponder.

Source and Binary Release

Side Widget
You can put anything you want inside of these side widgets. They are easy to use, and feature the Bootstrap 5 card component!