Miracast標準-新しいラッパーの古いプロトコル

少し前(JellyBean 4.2以降)、GoogleはAndroidにMiracastテクノロジーのサポートを追加しました。

この記事は、リバースエンジニアリング手法によるこの技術の実用的な研究に専念しています。



簡単に言えば、Miracastとは何ですか? これは、Wi-Fiアライアンスのもう1つの子孫です。これは、ピアツーピアモードでWi-Fiネットワークを介してマルチメディアコンテンツを送信するための標準です。 ユーザーにとって、これはまず第一に、テレビに接続するために、Wi-Fiルーターが必要ないことを意味します。 同盟が構想した2つのデバイスは、互いに直接通信する必要があります。 これは、同じ組織のオーサーシップにWi-Fi Direct標準を使用することにより保証されます。 つまり、この新しい標準は、AppleのAirPlay、IntelのWiDi、または古き良きDLNAに非常によく似た問題を解決します。



なぜ庭をフェンスで囲んだのですか? 既存のソリューションを活用してみませんか? 答えるのは難しいでしょう。 直接の競合他社やIntelからのライセンスソリューションがコーシャーオプションではなく、 致命的な欠陥があることは明らかです。 しばらくの間流行のピアツーピアの言葉で、何か新しいものが欲しかったのでしょうか? 推測しません。 いずれにせよ、このテクノロジーはAndroidに実装され、Nexus 4やSamsung Galaxy S3などの新しい携帯電話には搭載されています。



テレビメーカーの状況はさらに悪い。 DLNAのサポートが、ほぼすべての最新テレビで十分に高いレベルですでに利用可能な場合、Miracastでは事態がさら​​に悪化します。 チップの存在にもかかわらず、Miracastを受け入れることができるTVモデルとプロジェクターは指で数えることができます。 ただし、2014年には状況が変わる可能性がありますが、現時点では、ユーザーはWi-Fi信号を受信して​​HDMIに変換する多数のガジェットに満足できます。 このようなことはテレビのHDMIコネクターにはまり込んでおり、Miracast対応デバイスができました!



Broadcomチップを使用したエンジニアリングサンプルの1つが、私の粘り強い手に落ちました。



外観



Androidスマートフォンですべてが正常に動作することを確認した後、質問について考えました。Linuxから直接Miracast経由でブロードキャストすることは可能ですか? 結局のところ、内部のAndroidとは何ですか? 同じLinux ...



まず第一に、私はMiracastプロトコルスタックがどのように見えるかを理解したいと思いましたか? 美しい名前の背後にあるものは何ですか? ビデオ信号がイーサネットフレームで直接追跡されるのか、IPおよびさらに高レベルのプロトコルが使用されるのか。 残念なことに、 標準自体は、オープンではありますが無料ではありません。そのため、他のより伝統的な研究方法を見つける必要がありました。 プレゼンテーションで、MPEG-TSとRTSPというキーワードを取得しました。これにより、もつれをさらに解くことができました。 私が何かを知っている場合、 RTSPはTCPであり、TCPはIPです。 IPはtcpdumpでリッスンする適切なプロトコルです! Nexusでtcpdumpを実行し、設定で[ワイヤレス]ディスプレイをオンにして、5分後に、さらに分析するためのパケットダンプを受け入れました。



Wi-Fi経由で接続することの困難さを一時的に延期し、すぐにTCPストリームの分析を始めました。 そしてここに私が見たものがあります:



オプション* RTSP / 1.0
日付:2013年3月8日金曜日12:37:54 +0000
サーバー:鉱山/ 1.0
 CSeq:1
必須:org.wfa.wfd1.0

 RTSP / 1.0 200 OK
 CSeq:1
パブリック:org.wfa.wfd1.0、GET_PARAMETER、SET_PARAMETER

オプション* RTSP / 1.0
 CSeq:1
必須:org.wfa.wfd1.0

 RTSP / 1.0 200 OK
日付:2013年3月8日金曜日12:37:54 +0000
サーバー:鉱山/ 1.0
 CSeq:1
パブリック:org.wfa.wfd1.0、SETUP、TEARDOWN、PLAY、PAUSE、GET_PARAMETER、SET_PARAMETER

 GET_PARAMETER rtsp://localhost/wfd1.0 RTSP / 1.0
日付:2013年3月8日金曜日12:37:54 +0000
サーバー:鉱山/ 1.0
 CSeq:2
 Content-Type:テキスト/パラメーター
コンテンツの長さ:83

 wfd_content_protection
 wfd_video_formats
 wfd_audio_codecs
 wfd_client_rtp_ports

 RTSP / 1.0 200 OK
 CSeq:2
 Content-Type:テキスト/パラメーター
コンテンツの長さ:751

 wfd_content_protection:なし
 wfd_video_formats:00 00 02 10 0001bdeb 3fffffff 00000fff 00 0000 0000 11なしなし、02 08 0001bdeb 3fffffff 00000fff 00 0000 0000 11なしなし、02 04 0001bdeb 3fffffff 00000fff 00 0000 0000 11ffなし、02 02 0001bdeb 3fffffなし、02 01 0001bdeb 3fffffff 00000fff 00 0000 0000 11なしなし、01 10 0001bdeb 3fffffff 00000fff 00 0000 0000 11なしなし、01 08 0001bdeb 3fffffff 00000fff 00 0000 0000 11なし、01 04 0001bdeb 3fffffff 00000fff 00 0000 01 02 0001bdeb 3fffffff 00000fff 00 0000 0000 11なしなし、01 01 0001bdeb 3fffffff 00000fff 00 0000 0000 11なしなし
 wfd_audio_codecs:LPCM 00000003 00
 wfd_client_rtp_ports:RTP / AVP / UDP;ユニキャスト6500 0モード=再生
 SET_PARAMETER rtsp://localhost/wfd1.0 RTSP / 1.0
日付:2013年3月8日金曜日12:37:54 +0000
サーバー:鉱山/ 1.0
 CSeq:3
 Content-Type:テキスト/パラメーター
コンテンツの長さ:248

 wfd_video_formats:28 00 02 02 00000020 00000000 00000000 00 0000 0000 00なしなし
 wfd_audio_codecs:LPCM 00000002 00
 wfd_presentation_URL:rtsp://192.168.16.40/wfd1.0/streamid=0なし
 wfd_client_rtp_ports:RTP / AVP / UDP;ユニキャスト6500 0モード=再生

 RTSP / 1.0 200 OK
 CSeq:3

 SET_PARAMETER rtsp://localhost/wfd1.0 RTSP / 1.0
日付:2013年3月8日金曜日12:37:54 +0000
サーバー:鉱山/ 1.0
 CSeq:4
 Content-Type:テキスト/パラメーター
コンテンツの長さ:27

 wfd_trigger_method:セットアップ

 RTSP / 1.0 200 OK
 CSeq:4

セットアップrtsp://192.168.16.40/wfd1.0/streamid=0 RTSP / 1.0
 CSeq:2
トランスポート:RTP / AVP / UDP;ユニキャスト; client_port = 6500

 RTSP / 1.0 200 OK
日付:2013年3月8日金曜日12:37:55 +0000
サーバー:鉱山/ 1.0
 CSeq:2
セッション:1219569791;タイムアウト= 30
トランスポート:RTP / AVP / UDP;ユニキャスト; client_port = 6500; server_port = 15550

 PLAY rtsp://192.168.16.40/wfd1.0/streamid=0 RTSP / 1.0
 CSeq:3
セッション:1219569791

 RTSP / 1.0 200 OK
日付:2013年3月8日金曜日12:37:55 +0000
サーバー:鉱山/ 1.0
 CSeq:3
セッション:1219569791;タイムアウト= 30
範囲:npt = now-

 SET_PARAMETER rtsp://localhost/wfd1.0 RTSP / 1.0
日付:2013年3月8日金曜日12:38:07 +0000
サーバー:鉱山/ 1.0
 CSeq:5
 Content-Type:テキスト/パラメーター
コンテンツの長さ:30

 wfd_trigger_method:TEARDOWN
 RTSP / 1.0 200 OK
 CSeq:5

 TEARDOWN rtsp://192.168.16.40/wfd1.0/streamid=0 RTSP / 1.0
 CSeq:4
セッション:1219569791

 RTSP / 1.0 200 OK
日付:2013年3月8日金曜日12:38:09 +0000
サーバー:鉱山/ 1.0
 CSeq:4
セッション:1219569791;タイムアウト= 30
接続:閉じる




真実ではありません。通常のRTSPに似ています。 そのため、仕事の一部が完了しました。 MiracastベースのRTSP実装が標準実装とどのように異なるかを理解する必要があります。 RTSP(リアルタイムストリーミングプロトコル)に遭遇したことがない人のために、クライアントのサーバーからのマルチメディアストリームを制御するために使用されることを思い出させてください。 つまり、PLAY、PAUSE、TEARDOWNなどのコマンドを発行できます。 オプションを交換し、設定を構成することもできます。 {GET | SET} _PARAMETERが分析の主な頭痛の種になりました。 手元に標準がないため、これらすべてのwfd_video_formats、wfd_audio_codecsなどの意味がわかりませんでした。 しかし、私は推測できました!



MPEG-TSフレームの分析から、標準解像度が720x480、およびH.264(AVC)コーデックであることがわかったため、まったく同じパラメーターを使用してビデオファイルを作成することをお勧めします。 DVDを調べて、クラッカーテレビシリーズの小さなVOBを、ffmpegを使用して必要な形式に変換しました。 残ったのは、ファイルをサーバーにフィードすることだけでした。 ただし、このためにはサーバーを見つける必要があります!



RTSPサーバーを自分で作成しないようにするため(計画の一部ではありませんでした)、Miracastと互換性のある状態に簡単に変更できるオープンソースオプションを検討し始めました。 tcpdumpからのログを注意深く見ると、いくつかの奇妙なことに気付くかもしれません。 従来のクライアントサーバーRTSPモデルは、ピアツーピア相互作用に置き換えられました。 つまり、リクエストのアクティビティは、クライアント(この場合はTVまたはプロジェクター)からだけでなく、「サーバー」(つまり、電話またはコンピューター)からも発生する可能性があります。 なぜこれを行う必要があったのかは明らかではありませんが、事実は残っています。「クライアント」と「サーバー」の両方が必要に応じてリクエストを送信できるため、従来の役割が無効になります。 それでも、ビデオ信号を送信する側をサーバーに呼び出し続けます(この場合、これはLinix-PCです)。ビデオを受信して​​デコードする側はクライアントになります(この場合、これはプロジェクターになります)。



そこで、数時間の検索の後、私はlive555に落ち着きました。 このサーバーはC ++で記述され、LGPLライセンスの下で配布され、RTSPとMPEG-TSでのブロードキャストの両方をサポートします。 RTSPハンドラーを見ると、Miracastのピアツーピア仕様の下で処理することが非常に可能であることに気付きました。 しかし、クライアント(つまり、Miracastガジェット)にLinuxへの接続を強制することは残っています!



この作業はゲーテのファウストよりも困難でした。 以前は、Linuxで通常のWi-Fiを設定することも一度もなかったので、配線の信頼性がある程度高いと正しく信じていました。 Wi-Fi Directについて何が言えますか。 しかし、多くのマニュアルを読んだ後、私は神秘的なWPAサプリカントの方向に向かって掘り下げなければならないことに気付きました。 このサプリカントの目的は何ですか? Wi-Fi経由でアクセスポイントまたは別のノードに接続するときに認証を提供するのは彼です。 上で書いたように、Miracastはp2pモードで動作します。 デバイスはルーターをバイパスして直接通信します。 この機能はwpa_supplicantの最近のバージョンで幸いにもサポートされています。 p2pサポートがいつ追加されたか正確にはわかりませんが、バージョン2.1-develでは既に存在しています。



ただし、サプリカントを更新するだけでは十分ではありません。 構成ファイルも必要です。 罪を半分にして、デバイス(NetGear、WNA1100 Wireless-N 150 [Atheros AR9271])に受け入れられる構成を作成しました。



したがって、/ etc / wpa_p2p.confファイルに次のように記述します。

ctrl_interface=/var/run/wpa_supplicant ap_scan=1 device_name=JellyFish device_type=1-0050F204-1
      
      







次に、サプリカントを実行するためのシェルスクリプトが必要です。



 sudo iwconfig wlan0 mode ad-hoc sudo ip link set wlan0 up sudo wpa_supplicant -Dnl80211 -c /etc/wpa_p2p.conf -i wlan0 -dt
      
      







以上です(この構成はUbuntuベースのLinux Mint 13 Mayaディストリビューションで動作することを明確にします。カーネルバージョンは3.2.0-57-genericです)。



次に、wpa_cliなどのユーティリティを習得する必要があります。接続を「手動で」制御できるのはこのためです。

スクリプトを介してwpa_supplicantを実行した後、別のコンソールを開いて次のようなものを発行する必要があります。



 sudo wpa_cli
      
      







これはサプリカントのコマンドインターフェイスです。 ガジェットをオンにすると、p2p_findコマンドを使用して、p2pモードで接続する準備ができている地区内のすべてのデバイスを検索できます。 次に、p2p_connectコマンドを使用して、接続自体を作成します。



デバイスのログの例を次に示します。



 wpa_cli v2.1-devel
選択されたインターフェイス 'wlan0'
インタラクティブモード

 > p2p_find
わかった
 <3> P2P-DEVICE-FOUND 02:90:4c:04:04:04 p2p_dev_addr = 02:90:4c:04:04:04 pri_dev_type = 7-0050F204-1 name = 'MLT-52-2123' config_methods = 0x4688 dev_capab = 0x25 group_capab = 0xa
 > 
 > p2p_connect 02:90:4c:04:04:04 pbc
わかった
 <3> P2P-FIND-STOPPED <---ここで、デバイスのボタンを押す必要があります
 <3> P2P-GO-NEG-SUCCESS 
 <4> APスキャンの開始に失敗しました
 <4> APスキャンの開始に失敗しました
 <4> APスキャンの開始に失敗しました
 <4> APスキャンの開始に失敗しました
 <3> CTRL-EVENT-SCAN-RESULTS 
 <3> WPS-AP-AVAILABLE-PBC 
 <3> SME:02:90:4c:04:84:04(SSID = 'DIRECT-fCMLT-52-2123' freq = 2412 MHz)で認証しようとしています
 <3> 02:90:4c:04:84:04(SSID = 'DIRECT-fCMLT-52-2123' freq = 2412 MHz)との関連付けの試行
 <3> CTRL-EVENT-SCAN-RESULTS 
 <3> WPS-AP-AVAILABLE-PBC 
 <3> SME:02:90:4c:04:84:04(SSID = 'DIRECT-fCMLT-52-2123' freq = 2412 MHz)で認証しようとしています
 <3> 02:90:4c:04:84:04(SSID = 'DIRECT-fCMLT-52-2123' freq = 2412 MHz)との関連付けの試行
 <3> 02:90:4c:04:84:04に関連付けられています
 <3> CTRL-EVENT-EAP-STARTED EAP認証が開始されました
 <3> CTRL-EVENT-EAP-PROPOSED-METHODベンダー= 14122メソッド= 1
 <3> CTRL-EVENT-EAP-METHOD EAPベンダー14122メソッド1(WSC)が選択されました
 <3> WPS-CRED-RECEIVED 
 <3> WPS-SUCCESS 
 <3> P2P-GROUP-FORMATION-SUCCESS 
 <3> CTRL-EVENT-EAP-FAILURE EAP認証に失敗しました
 <3> CTRL-EVENT-DISCONNECTED bssid = 02:90:4c:04:84:04 reason = 3 local_generated = 1
 <3> CTRL-EVENT-SCAN-RESULTS 
 <3> WPS-AP-AVAILABLE 
 <3> SME:02:90:4c:04:84:04(SSID = 'DIRECT-fCMLT-52-2123' freq = 2412 MHz)で認証しようとしています
 <3> 02:90:4c:04:84:04(SSID = 'DIRECT-fCMLT-52-2123' freq = 2412 MHz)との関連付けの試行
 <3> 02:90:4c:04:84:04に関連付けられています
 <3> WPA:02:90:4c:04:84:04でキーネゴシエーションが完了[PTK = CCMP GTK = CCMP]
 <3> CTRL-EVENT-CONNECTED-02:90:4c:04:84:04への接続完了[id = 0 id_str =]
 <3> P2P-GROUP-STARTED wlan0 client ssid = "DIRECT-fCMLT-52-2123" freq = 2412 psk = fd435c6683ae5d7c9e3398dab15cc1b80d7f308b3fe7330db044ea90dcf7ac31 go 04




原則として、デバイスアドレスの後にあるp2p_connectコマンドの不可解な単語「pbc」を除いて、すべてはログから明らかです。 それはどういう意味ですか? これは、Wi-Fiダイレクト経由で接続するときの認証オプションの1つです。 意味-プッシュボタンコントロール。 これは、ユーザーがパスワードやPINコードを入力する必要のない単純化された認証です。 接続の時点で、デバイスのボタンを押す必要があり、認証は成功したと見なされます。



そのため、ログから接続が成功したことがわかります。 これで、wlan0インターフェイスのIPアドレスを取得できます。

この場合のDHCPサーバーは、テレビまたはプロジェクターになります。 別の端末で紹介します:



 sudo dhclient wlan0
      
      







次にtcpdumpを実行すると、SYNパケットをポート7236に送信しようとすることがわかります。このポートはRTSPの標準ポート(554)とは異なりますが、これは心配する必要はありません。 最も重要なことは、ガジェットが私たちと交渉したいということです! このポート(7236)で既にわずかに変更されたライブメディアサーバーを起動することにより、実際の「クライアントサーバー」相互作用をデバッグする機会が得られます。



読者にプロトコルのデバッグの詳細を説明するのではなく、すべての問題が何らかの形で解決されたとしか言いません。 そして最後に、結果は明らかです-私はPCからビデオを新しいミラキャストで見ることができました!







必要ですか? 知りません いずれにせよ、新しい標準を理解することは常に興味深いものです(もちろん、ASN.1でない限り)。



技術的な詳細を詳しく調べるのが面倒な人のために、Miracastベースのデバイスの接続手順を簡単に説明します。



  1. Wi-Fi Directを使用して、デバイスはお互いを見つけます(通常、ビデオソースはディスプレイデバイスを見つけます)
  2. これまたはその形式の認証(この場合はpbc)を使用して、デバイスはP2Pグループに結合されます
  3. デバイスの1つがDHCPを介してIPアドレスを受け取ります(この場合、これはビデオデータのソースです)
  4. RTSPサーバーは、ポート7236のデータソースで起動します
  5. クライアントはRTSPサーバーに接続し、特定の定義済みURL(/wfd1.0/streamid=0)を要求します
  6. RTSPサーバーは、RTPパケットにパックされたMPEG-TSの形式でビデオ(および場合によってはオーディオ)データの送信を開始します。
  7. クライアントはデータを解凍し、出力デバイスに表示します。




Miracastの明らかな欠陥(Wikiには記載されていません)のうち、次の点に注意します。



それだけです。 ご質問がある場合は、コメントでお尋ねください。



All Articles