IP Over QR Code!

Some have ask the throughput I am getting, its just about 100 Bytes per second, but hopefully I can improve it 🙂

**UPDATE 2**
Removing my custom seq/ack header and it still works and is about 2x 10x faster @ about 200Bps 1-2kBps (only generating qr code on new data now) but latency is still the killer…

Waaay back I had the idea of sending data over the audio/mic jack, and made a crummy implementation that could only send text messages (very unreliable) http://seiferteric.com/?p=319 . This was on hackaday many moons ago.

This time I wanted to send data using your monitor and a webcam, but how could I send data reliably without too much work? QR Code! So the idea this time is to use a tun device, read packets from it, convert to QR Code and display on screen. Then the other side will see it with the cam and decode and inject the packet into it’s tun device.

I ran into a few issues along the way. First, you need some way to acknowledge that the other side read my message, so I added a simple header of the form SEQ/ACK where I increment the sequence with each new qrcode and increment the acknowledge when I successfully read the other sides qr code. Second I needed a way to encode the data. QR Codes support a binary mode, but this is the least efficient and decided to instead use alphanumeric and base32 encode the packet data. Base64 would not work because the QR Code in this mode only supports uppercase letters. Next was an issue were the library I used to encode the data, qrtools, would generate a qr code, but the data would not be the same when decoding! So I fixed this by detecting this, then adding some padding to the data and trying again until it works, then strip the padding off on the other side.

To maintain my sanity during testing, I was able to run the code in a docker container for the remote side, and instead of using webcam, just pass the qr code image file in a volume mount. This was of course MUCH faster and was almost a usable connection (ssh was okay and ping time was like 50-60 ms). But of course the goal was to use the camera!


Successful ssh login!


Needed Improvements

  • Speeeeeeed!
  • Only rewrite qrcode when new data is available
  • pack as much data into a qrcode as possible (maybe multiple packets?)
  • cleanup code, fix syn/ack to avoid packet dups (which I manually drop right now by checking if new packet == old packet)
  • better detection library? Get a better camera for the laptop?
  • Non-vertical youtube videos 🙂


Get the code on github!