How to set up a Wifi-Direct connection between Android and Linux

Kida picture Kida · Aug 7, 2015 · Viewed 50.5k times · Source

I want to connect two devices using Wifi-Direct. One is a pc with Linux (during my test I'm using Linux Mint 17.2), the other is an Android smartphone (Samsung Galaxy S3 with Android 4.3. Not rooted and don't want to root).

Reading a number of guides on the internet, I decided to use wpa_supplicant in Linux and to create an app for Android. This is one of the best guides I found for wpa_supplicant: http://processors.wiki.ti.com/index.php/OMAP_Wireless_Connectivity_NLCP_WiFi_Direct_Configuration_Scripts#p2p_group_add

When I run iw list I see that the "Supported interface modes:" allows P2P_client and P2P_GO. My wpa_supplicant.conf contains:

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

The app is very similar to this example (it's from a book) http://kurser.iha.dk/eit/itsmap/basic/MEIER/Professional%20Android%204%20All%20downloads/9781118102275%20PA4AD/Code%20Snippets/Chapter%2016/PA4AD_Ch16_WiFiDirect/src/com/paad/wifidirect/WiFiDirectActivity.java (I removed the whole "socket part").

It works as expected. When I try it with two Android devices, they can see each other and connect (it appear the Wifi-Direct icon).

Now I am trying to connect Android and Linux, but I guess I don't really understand how wpa_supplicant works. I also saw this question that is very similar to what I asked, but it doesn't really answer my doubts... Direct Wifi Communication between android smartphone and other devices

My problem is that I can't understand how to do the handshake between the two devices and how to set up the network.

Wpa_supplicant is my problem. I run:

sudo wpa_supplicant -wlan0 -Dnl80211 -c/etc/wpa_supplicant.conf
sudo wpa_cli

But I had a lot of problems: - The device_name (and other parameters) weren't set as I specifiend in the .conf file - wpa_supplicant continues to try to connect to all the networks - p2p_find was really slow...

so I went into /usr/share/dbus-1/system-services and moved away the two files

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

Now I can

sudo killall wpa_supplicant

and it really dies, disconnecting me from Wifi without reconnecting the following second. Now I can launch wpa_supplicant and the three problems are resolved.

I go into wpa_cli, launch "p2p_find" and at the same time, I enable the search from within the app.

Android and Linux can now see each other.

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

With "p2p_peers" I can see the cellphone MAC.

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

Here I can't go ahead. I tried various possibilities, but none of them worked. My objective is to have Linux as Group Owner.

  • Question 1.1: Which is the correct way to handshake the two devices?
  • Question 1.2: When I try p2p_connect I often get "Michael MIC failure detected" between the results, what does it means in this contest?
  • Question 1.3: Android currently tries to connect with PBC. There is a way to connect with PIN?

Seeing that I couldn't connect Android/Linux, I tried to do some practice with Linux/Linux (Linux Mint as GO, Ubuntu as Client), following examples from internet like the ones in the first link. I have a number of problems even here.

In Mint I try

p2p_connect MAC_UBUNTU pin auth

in Ubuntu I try

p2p_connect MAC_MINT PIN_GENERATED_BY_MINT

When I write the psp_connect in Mint, it creates a new interface p2p_wlan0 _0, and it returns

P2P-DEVICE-LOST p2p_dev_addr=MAC_UBUNTU

then the p2p_connect launched from Ubuntu fails.

  • Question 2.1 Why it switches interface when creating the group?
  • Question 2.2 What is the correct way to handle this change? After the change I can't p2p_find Ubuntu anymore (I have to wait some time or restart everything)
  • Question 2.3 Should Ubuntu change it's interface?
  • Question 2.3 In the new interface I should set the IP for both Ubuntu and Mint... how should I do this with static IPs?
  • Question 2.4 If I want to set up for example a DHCP server and client?

  • Question 1.4 And with Android(client) / Linux(GO)?

Answer

Kida picture Kida · Nov 5, 2015

I worked a lot on this problem and here is the answers that I found:

I wanted Linux as a GO and Android as a client, so what worked for me in Linux is:

// 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();
}

N.B. To destroy P2P connection and restart the normal one I use this script:

#!/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

Here the server listens for a connection and the android client connects to it. I used a very easy TCP server found on the first website and it worked like a charm. It's important to start the udhcpd or you won't get the "connected" icon in Android. For the Android side, I followed what I saw on http://developer.android.com/training/connect-devices-wirelessly/wifi-direct.html and it worked perfectly.

  • Answer 1.2 From wpa_cli you can get a lot of different warnings and errors. I saw that simply calling the function (like I did in the previous snippet) made everything work despite the warnings. I ignored them.

  • Answer 1.3 The connection using PIN works, when I tried it I wasn't starting the udhcpd and that crashed my connection every time. It was not due to PIN or PBC.

  • Answer 2.1 Both the server and the client are switching interface. It is a very similar behaviour to what you usually do with sockets. You create a listening socket, somebody connects, you create a new socket to handle that client in a separate thread while the listening socket is still there, waiting for other users. You do the same with interfaces. Starting a wpa_cli that monitors the wlan0 interface and one that monitors the p2p-wlan0-0 interface gives a good idea of what is happening during the change.

  • Answer 2.2 The client "went" to the other interface and is now ready to receive an IP. Start the DHCP and TCP servers!

  • Answer 2.3 Don't use static IP. Only only for the server is ok, the client should use a DHCP IP. Maybe there is a way to handle static IPs, but it was not useful for my objectives.

  • Answer 2.4 Done. That was the problem all along

  • Answer 1.4 This works perfectly even with Android/linux.

Sorry if I made some mistake in my answer, I still don't get the whole picture of WiFi-Direct connections, I simply hope that this can help someone else.