IPをQRコードで実現する

**更新**
現在のスループットについて質問をいただきました。今のところ100バイト/秒程度ですが、もっと改善できるのではないかと思います。🙂

**更新2**
カスタムなSEQ/ACKヘッダを取り除いても、動作しています。速度は約2倍10倍で、およそ200Bps1kBpsから2kBpsです(今は新しいデータについてQRコードを生成する場合に限ります)。しかし、依然としてレイテンシが問題です。

ずいぶん前に、私は、オーディオ/マイクジャックでデータを送信することを思いつきました。そして、今ひとつながらも、テキストメッセージを何とか送れるだけの実装をしました(実にあやしいものですが)。それがこちらhttp://seiferteric.com/?p=319です。これは、かなり前にHackadayで取り上げられました。

今回は、モニタとWebカメラを使ってデータを送信しようと思いました。一体どうすれば、あまり手間をかけずに、確実にデータを送れるでしょうか。それはQRコードです。というわけで今回は、TUNデバイスを使用して、パケットを読み込み、QRコードに変換し、画面にQRコードを表示するというアイデアをご紹介します。そして、受け取った側はカメラを使ってコードを確認してデコードし、自分のTUNデバイスにパケットを投入します。

この過程で、いくつかの課題に突き当りました。1つ目は、受け取り手がメッセージを読んだという受信確認が必要だということです。そこで、SEQ/ACK形式のシンプルなヘッダを追加しました。そのヘッダに、新しいQR毎のシークエンスと、相手のQRコードをうまく読み取れた場合の受信確認をインクリメントします。2つ目は、データをエンコードする方法が必要だということです。QRコードはバイナリモードをサポートしていますが、これは最も効率が悪いので、その代わりに英数字とBase32を使ってパケットデータをエンコードすることに決めました。このモードのQRコードは大文字しかサポートしていないので、Base64は機能しません。次に問題となったのは、QRコードを生成するのに使用していたqrtoolsです。このライブラリでデータをエンコードしていたのですが、デコードすると同じデータにならならないのです。そこで私はこれを見つけて修正しました。それでデータにパディングを追加し、それがうまく動作するまで試して、もう一方の側でパディングを取り除きます。

テストをしている間、正気を保っていることができたのは、リモートサイドのDockerコンテナでコードを実行することができたからです。そうするとWebカメラを使う代わりに、ボリュームマウントでQRコードのイメージファイルを渡すだけです。もちろん、これはずっと速くて、ほぼ使える接続でした(sshは問題ありませんでしたし、ping時間は50ミリ秒~60ミリ秒程度でした)。しかし、もちろんカメラを使うのが目標です。

sshのログインに成功しました!

改善が必要な項目

  • Speeeeeeed!
  • 新しいデータが有効な時にだけQRコードを書き換える
  • できるだけ多くのデータをQRコードにパックする(複数パケット?)
  • コードのクリーンアップとsyn/ackの修正により、パケットの重複を避ける(今は新しいパケットと古いパケットが等価かどうか調べ、手動で削除している)
  • より良い検出ライブラリがあるのか?ラップトップ用のもっと優れたカメラを手に入れるのか?
  • 縦型でないYouTube動画にする 🙂

コードの入手はGitHubで