如何在安卓和Linux之间建立Wifi-Direct连接。

25

我想使用Wifi-Direct连接两个设备。一个是运行Linux的个人电脑(在测试期间我使用的是Linux Mint 17.2),另一个是Android智能手机(三星Galaxy S3,搭载安卓4.3系统,未经root,也不想root)。

在网上阅读了许多指南后,我决定在Linux中使用wpa_supplicant,并为Android创建一个应用程序。这是我找到的最好的wpa_supplicant指南之一: https://web.archive.org/web/20210114180304/https://processors.wiki.ti.com/index.php/OMAP_Wireless_Connectivity_NLCP_WiFi_Direct_Configuration_Scripts

当我运行iw list命令时,我看到“Supported interface modes:”允许P2P_client和P2P_GO。我的wpa_supplicant.conf文件包含:

ctrl_interface=/var/run/wpa_supplicant
update_config=1 

ap_scan=1
device_name=My-pc
device_type=1-0050F204-1
driver_param=use_p2p_group_interface=1

p2p_go_intent=15
p2p_go_ht40=1
这个应用和这个例子非常相似(出自一本书):https://github.com/retomeier/Wrox-ProfessionalAndroid-4E/blob/9741a8b62005d49519b1decfea21e7213fdd94a3/Snippets_ch18/app/src/main/java/com/professionalandroid/apps/myapplication/WiFiDirectActivity.java,它的功能正常。当我使用两个 Android 设备尝试时,它们可以看到彼此并连接(Wi-Fi Direct 图标出现)。现在我正在尝试连接 Android 和 Linux,但我想我不太明白 wpa_supplicant 如何工作。我还看到了这个问题,它与我的问题非常相似,但它并没有真正回答我的疑问...Direct Wifi Communication between android smartphone and other devices。我的问题是我无法理解如何在两个设备之间进行握手以及如何设置网络。Wpa_supplicant 是我的问题。我运行:
sudo wpa_supplicant -wlan0 -Dnl80211 -c/etc/wpa_supplicant.conf
sudo wpa_cli

但我遇到了很多问题:

  • 设备名称(以及其他参数)没有按照我在.conf文件中指定的设置
  • wpa_supplicant继续尝试连接所有网络
  • p2p_find非常缓慢...

所以我进入了/usr/share/dbus-1/system-services并将这两个文件移走了

fi.epitest.hostap.WPASupplicant.service
fi.w1.wpa_supplicant1.service

现在我可以

sudo killall wpa_supplicant

然后它真的死了,没有在下一秒重新连接我到Wifi。

现在我可以启动wpa_supplicant并解决这三个问题。

我进入wpa_cli,启动"p2p_find",同时在应用程序内启用搜索。

Android和Linux现在可以看到彼此。

P2P-DEVICE-FOUND 00:11:22:44:88:ff p2p_dev_addr=00:11:22:44:88:ff
pri_dev_type=10-0050F204-5 name='GT-I9300' config_methods=0x188
dev_capab=0x24 group_capab=0x0 vendor_elems=1 new=0

使用“p2p_peers”我可以看到手机的MAC地址。

> aa:bb:cc:dd:ee:ff

在这里我无法前进。我尝试了各种可能性,但都没有奏效。我的目标是将Linux作为组所有者。

  • 问题1.1:两个设备之间握手的正确方式是什么?
  • 问题1.2:当我尝试p2p_connect时,经常会在结果中得到“检测到Michael MIC失败”,这在此情况下意味着什么?
  • 问题1.3:Android当前尝试使用PBC连接。有一种方法可以使用PIN连接吗?

看到我不能连接Android/Linux,我尝试使用Linux/Linux进行一些练习(Linux Mint作为GO,Ubuntu作为客户端),按照互联网上的示例(如第一个链接中的示例)进行操作。即使在这里,我还有一些问题。

在Mint中,我尝试:

p2p_connect MAC_UBUNTU pin auth

在Ubuntu中,我尝试

p2p_connect MAC_MINT PIN_GENERATED_BY_MINT

当我在Mint中写psp_connect时,它会创建一个新的接口p2p_wlan0_0,并返回结果。

P2P-DEVICE-LOST p2p_dev_addr=MAC_UBUNTU

然后在Ubuntu上启动的p2p_connect失败。

  • 问题2.1:为什么创建群组时它会切换接口?

  • 问题2.2:处理此更改的正确方法是什么?更改后,我无法再在Ubuntu上找到p2p_find(我必须等待一段时间或重新启动所有内容)

  • 问题2.3:Ubuntu应该更改其接口吗?

  • 问题2.4:如果我想设置DHCP服务器和客户端怎么办?

  • 问题1.4:Android(客户端)/ Linux(GO)如何处理?


我遇到了类似的问题,你碰巧有任何进展吗? - broody
是的,我一直在继续努力并解决了很多问题。目前我还没有一个好的稳定解决方案,但我正在接近!只要我对所有问题都有答案,我就会在这里回答! - Kida
3个回答

10

我在这个问题上花了很多时间,以下是我找到的答案:

我想让Linux作为GO,Android作为客户端,在Linux中适用的方法是:

// Kill current supplicant and avoid its automatic recreation
system("mv /usr/share/dbus-1/system-services/fi.* .");
system("killall udhcpd");
system("wpa_cli -i wlan0 terminate -B");
usleep(300000);

// Start new supplicant
system("wpa_supplicant -Dnl80211 -iwlan0 -c /etc/p2p_supplicant.conf -B");
system("wpa_cli -iwlan0 p2p_group_add");
system("ifconfig p2p-wlan0-0 192.168.1.2");

// Connect with a peer
for (;;) {
  system("wpa_cli -ip2p-wlan0-0 wps_pbc");
  system("udhcpd /etc/udhcpd.conf");
  // Here start your TCP server on a port
  Server server([port]);
  server.startServer();
}

注意:为断开P2P连接并重新启动正常连接,我使用以下脚本:

#!/bin/bash
wpa_cli -i wlan0 terminate -B
wpa_cli -i p2p-wlan0-0 terminate -B
cp ./fi.* /usr/share/dbus-1/system-services/
service network-manager restart

在这里,服务器监听连接,而Android客户端连接到它。我使用了一个非常简单的TCP服务器,在第一个网站上找到它,它运行得很好。 重要的是要启动udhcpd,否则您将无法在Android中获得“已连接”图标。 对于Android方面,我遵循了我在http://developer.android.com/training/connect-devices-wirelessly/wifi-direct.html上看到的内容,它完美地工作。

  • 答案1.2 从wpa_cli中,你可以得到很多不同的警告和错误。我发现只是简单地调用函数(就像我在之前的片段中所做的那样)尽管有警告,但一切都能正常工作。我忽略了它们。

  • 答案1.3 使用PIN连接是可行的,当我尝试时,我没有启动udhcpd,这导致我的连接每次都崩溃。这不是由于PIN或PBC引起的。

  • 答案2.1 服务器和客户端都在切换接口。这与通常使用套接字的行为非常相似。您创建一个监听套接字,有人连接,您创建一个新的套接字来处理该客户端,在单独的线程中,而监听套接字仍然存在,等待其他用户。您可以使用接口执行相同的操作。启动监视wlan0接口和监视p2p-wlan0-0接口的wpa_cli可以很好地了解更改期间发生的情况。

  • 答案2.2 客户端“转移到”另一个接口,现在已准备好接收IP。启动DHCP和TCP服务器!

  • 答案2.3 不要使用静态IP。只有服务器使用静态IP是可以的,客户端应该使用DHCP IP。也许有一种处理静态IP的方法,但对于我的目标来说没有用。

  • 答案2.4 完成了。这就是问题所在。

  • 答案1.4 这甚至在Android / linux上都可以完美运行。

如果我的回答有误,请见谅。我对WiFi-Direct连接的整体情况还不是很清楚,但我希望这能帮助到其他人。


1
请问您能告诉我如何在Ubuntu 14.04中设置WiFi Direct吗? - Harshitha Palihawadana
太好了!感谢您的回答和解释。我的Wifi Direct应用程序基于这个代码,在Android 10更新后出现了问题。在Android 10中,WifiDirect有什么变化吗? - AdeleGoldberg
抱歉,但是我已经有一段时间没有使用wifi直连了。我无法帮助你:( - Kida
答案1.1中的链接已经失效。 - Shaked

2

(可能不是完整的答案,但是正确的方向)

问题出在Linux端。我在Cyanogenmod(Android 5)和Fedora 22之间遇到了类似的问题,试图使用Wifi Direct(Wifi P2P)来为Intel的Linux操作系统(WDS)提供无线显示软件。

具体来说,英特尔的connman于2009年从Linux标准的NetworkManager分离(从头开始编写)。Connman似乎是Linux中唯一实现Wifi Direct(Wifi P2P)的方式,并且已经为嵌入式(移动)市场编写。

由于RPM问题,connman在我的系统上仍未经过测试,但该软件应该提供Linux所需的dbus通信。

网站:https://01.org/connman


-2
你是否尝试在Android上激活热点选项?然后连接Ubuntu设备,检查Android热点选项中的连接IP,并将其提供给您的应用程序。这对我远程控制Ubuntu系统很有帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接