preloader
軟體工程

Android Wi-Fi Direct 無法使用 Multicastsocket

Android 從 4.0 以後的版本開始支援 Wi-Fi Direct,看來是選擇不錯的通訊科技。

程式中欲使用Wi-Fi Direct必須import wifi.p2p library還有在manifest.xml宣告權限,本篇只介紹 Android 實作的 WifiP2pManager class、和其相關的class,以及與其對比的WifiManager class,不會介紹如何在程式中使用WiFi Direct和相關的class。

 

以下是參考本人在 本Google issue 的#6回覆,有興趣者可以參考,測試環境是Nexus 7(2012), Android 4.2和 32G capacity with 3g and wifi connectivity。

 

WiFiP2pManagerWiFiManager預設都是丟棄收到的Multicast封包,只是WiFiManager有額外的函式可以控制接收Multicast封包時不丟棄,換句話說,就是App程式收得到對方設備發出來的Multicast封包;WifiP2pManager則不行,因為它沒有WiFiManagercreateMulticastLock 函式,所以也無法進行後續的aquire函式。

即使你使用 MulticastsocketjoinGroup(SocketAddress, NetworkInterface)函式時,執行程式沒有跳出錯誤訊息,以及即使使用Wi-Fi Direct的network interface的supportMulticast函式,函式答覆是支援Multicast,程式依然也是收不到Multicast的封包,根本的原因是WifiP2pManager目前沒有和WifiManager一樣能請Driver不要丟棄Multicast封包。

提醒 :啟用Wifi Direct時,Android會自己創一個network interface,名稱是p2p-p2p0[\-][0-29];WiFi 則只使用wlan0 network interface;p2p-p2p0和wlan0在app使用概念上是不同的interface。

 

WifiManager建立和結束MulticastLock的流程:

  1. 呼叫位於本身之內的inner class:MulticastLock
  2. 使用MulticastLock class的 acquire()/release()函式。
  3. acquire/release會經由WiFiStateMachine.java呼叫WiFiNative.java裡的{start/stop}Filtering{V4/V6}packet 函式。

達成建立和結束接收Multicast封包的功能。

 

觀察WifiP2pManager原始碼,其現階段並沒有呼叫WiFiNative.java{start/stop}Filtering{V4/V6}packet這四個函式,本人希望Android能加入MulticastLock在現有的WiFiP2pManager class,不然沒看過本文章和上述google issue連結的人,還以為WifiP2pManager與其network interface雖然API reference文件沒寫,也和WifiManager一樣都有支援MulticastLock。

所以,目前在Wi-Fi Direct network interface上,運用所有會用到MulticastSocket的程式和協定可能都不能作用。舉例,同樣是參照上面的Google issue連結,WiFi Direct結合Upnp目前運作是有問題的,因為upnp需要使用multicast的相關參數,細節請參照上述連結的#1。個人建議,如果要在Wi-Fi Direct的network interface上達到類似Multicast效果,目前只能先用DatagramSocketsetBroadcast(true)函式。

題外話WiFiP2pManager則是透過WiFiP2pService.java,呼叫WiFiNative.java的函式;WiFiNative.java則是操作WiFi Driver的java檔案。