Windowsにもエアドロしたい。Raspberry PiでAirDrop受信機「LilBitDrop」を作った(CloseBox)

テクノロジー AI
松尾公也

テクノエッジ編集部 シニアエディター / コミュニティストラテジスト @mazzo

特集

AirDropは今では少なくなってしまった、Appleエコシステムの「ないとなると困る」機能の1つです。何かイベントがあったときに写真をその場にいる人に送るのに著しく便利。ここではiPhoneとそれ以外で大きな格差が生まれ、そのような機会の多い女子学生の中ではiPhone所有率が格段に高いというのも頷けます。

ただ、最近ではAndroidのファイルシェア機能であるQuick ShareにAirDrop互換機能が搭載されるようになり、Androidに関してはその差は埋まりつつあります。ただし、それは最近の機種限定。うちのPixel 7は対象外なので、「エアードロップなんか来やせん」(CV:菅原文太)と笑われたような気がします。

太陽を盗んだ男 [DVD]
¥2,212
(価格・在庫状況は記事公開時点のものです)

Quick ShareのAirDrop対応は、まずPixel 10シリーズで始まり、2026年2月にPixel 9シリーズへ広がりました(9to5Google)。Googleのヘルプによると、AirDropで受け取れるのはPixel 9以降(Pixel 9aを除く)。この他にも一部の Samsung、Oppo、OnePlus、Vivo、Xiaomi、Honor、Transsion、Motorolaの端末が対象となっているようです。

Googleは機種を絞る理由を公表していません。ただ、AirDropが使う「AWDL」という通信方式には、Wi-Fiチップ側の対応が必要だからだという見方があります。アナリストのMax Weinbach氏は、AWDLを扱えるのは主にフラッグシップ級のWi-Fiチップで、ソフトの更新だけでは解決しないと指摘しています(Android Headlines)。この見方が正しければ、Pixel 7に対応が来る見込みは薄そうです。

一方、Apple側でAirDropに対応した最も古いiPhoneは、iPhone 5です。AirDropがiPhoneに来たのは2013年のiOS 7で、対象はiPhone 5以降でした。iPhone 5の発売は2012年なので、14年前の製品です。

Macはさらに古く、2011年のOS X LionでAirDropが始まり、2008年後半以降の一部のMacが対象でした。こちらは約18年前です。ただし当時のMac版はiPhoneとは通信できず、MacとiPhoneの間で送れるようになったのは2014年のOS X Yosemite(10.10)からです(Apple)。Appleは10年以上前の端末でもAirDropを動かしているのに、Androidではここ数年の機種に限られているわけです。

WindowsにもAirDropしたい。我が家では最近、Windows PCがブイブイ言わせてて、気軽に転送できるAirDropはぜひ使いたいところ。でも、こちらはさらに手段がない状況です。

この分断はなんとかならないものか。謎を解き明かそうと考えた筆者がたどり着いたのは、とあるオープンソース技術でした。

最初はChatGPTに「接続するだけでAirDrop対応にしてしまうようなデバイスってできないかな」と尋ねてみました。

iOS 18搭載iPhoneとLinux間でのAirDrop転送を実現する「OpenDrop」というプロジェクトが存在しています。

これを小型で携帯できるデバイスで動かせれば目的は達成できそう。ということで、初期プログラム「AirBridge」を作ってもらいました。

必要な機材としては、Debian Linuxを搭載するRaspberry Pi 4と、無線通信部分を担当するOWLに対応したWi-Fiアダプター。写真・ファイルは受信可能で、現状で対応している無線チップはAtheros AR9170/carl9170のみで、これを搭載している安いアダプターを探す必要があります。現行新品ではないので中古品を探すしかないのが大変なところ。筆者はNEC Aterm WL300NU-AGを購入しました。802.11n/a/b/gですってよ!

なぜAR9170でなければいけないのか。ここでも影響しているのは、やはりAWDLです。AWDLでは、端末同士が時刻を合わせ、決まった時間に決まったチャンネルで電波をやり取りします。普通のWi-Fiアダプターはこの方式に対応していません。そこでLinuxでは、アダプターを「モニターモード」にし、ソフトで組み立てた電波のフレームをそのまま送り出す(フレーム注入)ことで、AWDLを再現しています。

ところが多くのアダプターは、モニターモードに対応していても、注入したデータのフレームを黙って捨ててしまいます。opendrop-rsの作者によると、Realtekのチップ(rtw88)では制御用のフレームしか送れず、AirDropのデータを運べませんでした。

時刻合わせの精度にも大きな差があり、許容範囲を外れた割合はRealtekのRTL8822BUが12~21%、AR9170は約0.4%でした。この両方を満たせると確かめられているのが、今のところAR9170だけなのです。

Pixelの対応機種が絞られているのと、根っこは同じです。AirDropを話せるかどうかは、結局Wi-FiチップがAWDLに付いていけるかどうかで決まります。

Raspberry Piはキーボード搭載型の400を持っているのですが、それとは別にRaspberry Pi 4 Model Bを購入しました。

それからしばらくChatGPTとやりとりしながらターミナルに入力して設定を進めていったのですが、さすがに面倒になり、仕様書をまとめてもらい、Claude Codeにバトンタッチ。

これ以降は、Raspberry Pi 4で動作させたClaude Codeとのやり取りになります。

SSHでRaspberry Pi 4にログインし、操作をしては、iPhoneのAirDrop相手先にちゃんと表示されるか、転送されるかを確認する長い作業が始まりました。

最初の壁:iPhoneの一覧に出てこない

Claude Codeに引き継いだ時点で、Raspberry Pi 4ではAirDropの受信プログラムが一応動いていました。それでも、iPhoneのAirDrop共有シートに受信機の名前が出てきません。

使ったのはOpenDropそのものではなく、Rustで書き直された「opendrop-rs」です。AirDropは、Apple独自の無線方式「AWDL」の上で動いています。opendrop-rsは、AWDLを担当する「filin」と、AirDropの受信を担当する「luftlift」の2つでできています。

最初に見つかった原因は、ソフトではなく電波でした。Wi-Fiアダプターの5GHz帯のチャンネルに「no IR(電波を出してはいけない)」という印が付いたままになっていたのです。こうなると、Linuxのカーネルは送信しようとしたフレームを、エラーも出さずに捨ててしまいます。

Claude Codeはカーネルの関数に計測用のフックを仕掛け、フレームを1つずつ追いかけました。20秒間で、2.4GHzのフレームは16件すべてドライバまで届いていました。ところが、5GHzのフレームは172件中1件も届いていません。iPhoneから見れば、こちらは何も言っていないのと同じだったわけです。

日本の電波法では、屋内なら5GHz帯の36~48チャンネル(W52)で送信できます。ドライバを読み込み直すと日本向けのルールが正しく当たり、この印が消えました。規制をごまかしたわけではなく、本来送信してよいチャンネルが誤って止められていた、という話です。

これで電波は出るようになりましたが、まだ一覧には出ません。試したiPhoneはiPhone Air(iOS 27)です。一方、opendrop-rsが動作を確認していたのはiOS 18.6.2まででした。

iPhoneの電波を拾って中身を分解すると、原因がわかりました。iOS 27のiPhoneは、AWDLの制御フレームの中に「自分はこういうサービスを持っています」という情報を埋め込んで知らせ合っていたのです。filinはこの情報を一切送っていませんでした。

そこで、filinがAirDropの受信機であることをこの形式で知らせるように改造しました。すると、共有シートを開いた途端に受信機が表示されるようになりました。

写真が途中で止まる

一覧に出たところで、いよいよ写真を送ります。最初に届いたのは、103KBの小さな写真1枚でした。iPhoneに「送信済み」と出たときは、さすがに声が出ました。

ところが、普通に撮った数MBの写真になると届きません。転送が途中で止まったり、最後まで届いても保存されなかったりします。原因は3つ重なっていました。

  1. 速度が出ない。 転送速度は秒速約150KBという遅さで、iPhoneが途中で送信をあきらめていました。AWDLでは、端末同士が「この時間はこのチャンネルにいる」という予定表を共有しています。filinはその予定表だけを見て送信してよいかを判断していたため、受信確認の返事が1回につき約0.4秒待たされていました。転送中は、無線が実際に合わせているチャンネルで判断するように直しました。

  2. 圧縮されていない部分を読めない。 AirDropはファイルを圧縮して送ります。ただしJPEGのようにそれ以上縮まない部分は、圧縮せずにそのまま詰めます。luftliftはこの「そのままの塗分」に対応していませんでした。実際に届いたデータを保存して解析し、形式を突き止めました。

  3. 「これで終わり」の合図が来ない。 iOS 27は、データの最後に付くはずの終わりの印を送ってきませんでした。luftliftはそれを待ち続け、iPhoneは返事を待ち続けるというお見合い状態です。中身のアーカイブが終わった時点で受信完了とみなすようにしました。

3つとも直した結果、3.7MBの写真が約7秒で届きました。ファイルサイズはiPhoneが予告した値と一致し、画像としても正しく開けました。

一覧からすぐ消える

届くようにはなったものの、使い勝手はまだ悪いままでした。受信機が一覧に出るのは約2分おきで、出てもすぐに消えてしまいます。写真を送るには、出た瞬間を狙ってタップするしかありません。

電波を採取して調べると、原因は先ほどの「予定表」にありました。AWDLの端末は、周りのどれか1台に時刻を合わせます。filinは、その相手の予定表まで丸ごとコピーしていました。ところが周りのApple製品は8台ほどあり、合わせる相手が数秒ごとに入れ替わります。そのたびに、こちらの予定表もコロコロ変わっていたのです。

共有シートを開いたiPhoneは、4チャンネル(5GHz帯)を中心に待ち受けていました。ところがこちらの予定表は、ほとんどが48チャンネルでした。16ある時間枠のうち、両者が同じチャンネルにいるのは2~3枠しかありません。さらに、日本では使えない149チャンネルも予定表に入れていました。その時間は、何もしていないのと同じです。

そこで、時刻だけは周りに合わせ、予定表は自分で決めるように変えました。基本は44チャンネルにいて、決まった1枠だけ2.4GHz帯の6チャンネルに移ります。これは、Apple製品自身の予定表と同じ形です。使えないチャンネルは、動作中に自動で予定表から外すようにしました。

効果はてきめんでした。起動から11秒でiPhoneから問い合わせが来て、一覧に表示されたまま消えなくなりました。2.85MBの写真は、約2.2秒で転送できました。

電源を入れるだけで動くように

持ち歩くデバイスにするなら、電源を入れるたびにSSHで操作するわけにはいきません。ところが、再起動のたびに何かしらが壊れました。

  • 起動の順番が循環していた。 サービス同士の「これの後に起動する」という指定が輪になっていて、Linuxはそれを断ち切るために受信機の起動を取り消していました。

  • 「no IR」は再起動のたびに戻る。 最初に直した電波の問題は、起動するたびに再発しました。そこで、起動時にチャンネルを確かめ、必要ならドライバを読み込み直す仕組みを入れました。

  • その読み込み直しで事故が起きた。 試験で約90秒のうちに3回続けて読み込み直したところ、Wi-FiアダプターがUSB機器として認識されなくなりました。ソフトでは復旧できず、筆者が物理的に抜き差ししてようやく戻りました。それ以来、読み込み直しは1回の起動につき最大2回までと決めています。

  • 翌朝、Wi-Fiにつながらなかった。 後述するUSB接続の設定で、Claude Codeがネットワーク設定の再読み込みを実行しました。このとき、自宅Wi-Fiの接続設定が空っぽになっていたのです。その日は動いている接続がそのまま残ったため気づかず、翌朝の起動で初めて発覚しました。元凶の設定は、そもそも不要だったこともわかり、取り除きました。

  • 1回目の読み込み直しが間に合わない。 別の日の起動では、読み込み直し直後の確認でまだ「no IR」が残っていました。AWDL側は自動で再試行して直りましたが、受信機は「必須の部品が失敗した」と起動を諦めたままでした。受信機が自分で再試行し続けるように直しています。

こうした修正を重ね、今では電源を入れると約25秒で受信機が立ち上がります。その後、AirDropファイル共有シートに表示されるようになりました。

USBでつなぐだけで写真を取り出す

受け取った写真は、Raspberry Piの中にたまっていきます。これを手軽に取り出せなければ意味がありません。そこで、PCとUSBケーブル1本でつなぐだけで、ブラウザから写真を保存できるようにしました。

Raspberry Pi 4のUSB-C端子は、設定を変えると「PCにつなぐUSB機器」になれます。ここではUSB接続のネットワークアダプターのふりをさせています。PCをつなぐと自動でアドレスが割り当てられ、ブラウザで http://10.55.0.1:8080/ を開くと、受信した写真が並びます。PCのインターネット接続には影響しません。

最初は、Windowsが標準で使える「RNDIS」という方式だけで作りました。ところが手元のiMac(M1)につなぐと、USB機器としては認識されるのに、通信が1パケットも流れません。macOSにはRNDISのドライバがないのです。

そこで、MacやLinuxが使える「ECM」という方式も用意し、PC側が使える方を自動で選ぶ形にしました。これでiMacは、アドレスの割り当てからブラウザでの一覧表示、写真のダウンロードまで成功しました。

Windowsでは、最初に試したPCとケーブルの組み合わせでは、USB機器として認識されませんでした。別のPCと別のケーブルに替えると、WindowsはRNDISを選んでつながり、ブラウザから写真をダウンロードできました。

これで、iPhoneからWindowsマシンに画像をAirDropしてダウンロードすることが簡単にできるようになりました。

それならiPhoneからOneDriveやGoogle Driveに転送すればいい?  まあ、そうですけど。ロマンがないなあ。

LilBitDropとして公開

必要なことが一通り動いたので、GitHubで公開することにしました。ただし、その前に片付けることがいくつかありました。

まず名前です。「AirBridge」で検索すると、日本でも使われている韓国AB180の広告計測サービスが出てきます。App Storeには、iPhoneとMacの間で写真を送る同名のアプリがありました。GitHubにも、AirPlayなどApple関連の同名プロジェクトがいくつもあります。そこで、重なるものが見つからなかった「LilBitDrop」に改名しました。共有シートに出る名前もLilBitDropです。

次に、公開前の見直しで深刻な脆弱性が見つかりました。受信プログラムは、送られてきたファイル名をそのまま保存先に使っていました。そのため、名前に「../」を含めれば、受信フォルダの外にも書き込めます。しかも受信プログラムは管理者権限で動き、「すべての人」モードでは転送を自動で受け入れます。近くにいる誰でも、Raspberry Piの任意のファイルを書き換えられる状態だったのです。

保存時にはファイル名だけを使うように直しました。ついでに、同じ名前の写真を再送すると上書きされる問題も直し、「名前-1.jpg」のように連番を付けて保存するようにしています。

opendrop-rsはGPL-3.0のソフトです。LilBitDropにはその改造部分(パッチ11本)を含むので、全体をGPL-3.0で公開しました。

リポジトリはこちらです。matsuo-koya/LilBitDrop

まとめと今後

約2日の作業で、iOS 27.2のiPhoneからRaspberry PiへAirDropで写真を送れるようになりました。3~4MBの写真なら、受信の確認から完了まで数秒です。届いた写真は、USBでつないだMacのブラウザから取り出せます。

その後、Windowsでも接続実験に成功しました。Edgeブラウザで転送された画像をダウンロードできます。

筆者がやったのは、iPhoneで共有シートを開いて写真を送り、結果を伝えることが中心。電波の採取や解析、カーネルの計測、Rustの修正は、Claude Codeが仮説を立てて確かめながら進めています。一方で、Wi-Fi設定を消したりアダプターを認識不能にしたりと、実機ならではの事故もありました。そのたびに原因を突き止め、記録と再発防止策を残しています。

残っている課題は次のとおりです。

  • スマホへの受け渡し。 今は写真をPC経由で取り出す形です。Pixel 7や他のAndroid端末に直接渡す方法は、これから考えます。

  • 入手しにくい部品。 対応するWi-Fiアダプターは、AR9170チップ搭載の中古品に限られます。

  • iOSの更新。 iOS 27で発見の仕組みが変わったように、今後のiOSの更新でまた動かなくなる可能性があります。

それでも、「つなぐだけでAirDrop対応になるデバイス」は、半分くらいまでは形になりました。続きが進んだら、また報告します。

ここまでやって分かったのは、AirDropの仕組みがとんでもなく込み入っているということと、iOS、iPadOS、macOSなどの各種OSのバージョンアップで、新しいデバイスに都度対応していくのは恐ろしく大変だろうということです。

Appleは自社製品ですからそれをやっているのは当然としても、Googleも今後はキャッチアップしていくと覚悟を決めた、ということなのでしょう。

ただし、そのためには対応製品を過去にさかのぼって広げていくことはおそらくやらないし、できないでしょう。なぜなら、先にも書いたように、問題がOSだけではなく、おそらくはWi-Fiチップを対応するものに変更する必要があるからです。

QuickShareのAirDrop互換機能をGoogle以外のAndroid端末でサポートしようとするならば、Wi-Fiチップの選定およびドライバの開発が必要となり、単にOSを導入すればすむ問題ではないのだろうな、というのが分かったような気がします。

ニーズはあるだろうに、類似プロジェクトがOpenDrop以降は生まれてこなかった理由も。

だって大変なんだもん。

とりあえず、ここまでの成果はGitHubで公開してあるので、あとはよしなに。

実はこのあと、内蔵Wi-Fiチップでも可能かどうか、さらなる探求をしました。

おまけ:内蔵Wi-Fiだけで動かせないか試した

外付けアダプターが要らなければ、デバイスはもっと小さくできます。そこで、Raspberry Pi 4の内蔵Wi-Fi(BCM43455)だけでAWDLを動かせないか試しました。結論から言うと、今回の環境では動きませんでした。

内蔵チップは、そのままではモニターモードを持ちません。そこで、ファームウェアにパッチを当てて機能を足す「Nexmon」を使いました。Kali Linuxが用意したパッケージを、Claude Codeが筆者のカーネルに合わせて移植しています。

落とし穴が1つありました。Raspberry Pi上のClaude Codeは、内蔵Wi-Fi経由でインターネットにつながっています。内蔵Wi-Fiを実験に使うと、Claude Code自身が止まってしまいます。そこでこの実験だけは、MacのClaude CodeからUSB経由で操作しました。

ファームウェアの差し替えは成功し、モニターモードも使えるようになりました。ところが、監視用のインタフェースを作ると、MACアドレスが「00:00:00:00:00:00」のまま変更できません。AWDLでは自分のMACアドレスを名乗るので、これでは通信できません。同じ症状はOWLのissue #63にもあり、「古いカーネル5.10に戻したら動いた」と報告されています。

さらに、内蔵チップは無線が1系統しかなく、自宅Wi-Fiへの接続が48チャンネルを掴んだままになります。AWDLに必要な44チャンネルと6チャンネルの行き来もできませんでした。

実験後はスクリプト1本で元に戻し、本番の受信機にも影響はありませんでした。内蔵Wi-Fiでも原理的に不可能とまでは言えませんが、MACアドレスの問題を直すには本格的な改造が要ります。当面は、15年物の外付けアダプターに頑張ってもらうことにします。

※この記事は筆者とClaude Codeとの対話によってClaudeが執筆したものを、筆者が整理・加筆しました。

《松尾公也》

Amazon売れ筋ランキング

松尾公也

テクノエッジ編集部 シニアエディター / コミュニティストラテジスト @mazzo

特集

BECOME A MEMBER

『テクノエッジ アルファ』会員募集中

最新テック・ガジェット情報コミュニティ『テクノエッジ アルファ』を開設しました。会員専用Discrodサーバ参加権やイベント招待、会員限定コンテンツなど特典多数です。