What is it?

Wi-Fi Direct allows devices to connect directly to each other using methods similar to traditional Wi-Fi, except without a pre-established access point. Instead, they negotiate to establish one peer device to act as a software access point for all the other devices in the group.

Devices can connect simultaneously to a Wi-Fi Direct group and a traditional access point.

How to use it on Android

There are two methods of finding nearby peers:

  1. Peer discovery finds all nearby peers with WiFi Direct.
  2. Service discovery finds all nearby peers with WiFi Direct that are running the same app.

For the purposes of a peer-to-peer app, service discovery is more useful.

  • Initiate service discovery

Follow the developer guide

Using Wi-Fi P2P for Service Discovery tells you how to advertise a service on your device so other devices can find you. In our demo, our app advertises itself using a unique string that identifies it as a peer-to-peer Facebook app. This allows devices to find each other using the Data Link Layer before they have established a connection.

Watch out for these quirks

In order to find each other, both devices must call WiFiP2pManager.discoverServices, not just one. This method puts the devices in the FIND phase, in which they both advertise and listen for nearby services. If you do not call WiFiP2pManager.discoverServices, your device will not advertise itself, and other devices will not be able to find it. Issue report on the Android issue tracker.

The Android specification claims that service discovery continues until the phone finds a device, but it was not very reliable in our tests. Sometimes devices failed to find each other, but later found each other if we called WiFiP2pManager.discoverServices a second time.

  •    Connect to peers

Follow the developer guide

Skip the “discovering peers” section. If you’ve followed the previous guide, you’re already using service discovery to find peers that are running the specific service you want.

Instead, use the code from the “connecting to peers” section.

Watch out for these quirks

If you already have a pending connection with a peer, you cannot attempt to connect to a second peer. If you wish to automatically connect to all the peers you discover, you must add the devices to a queue, and connect to them one at a time. We recommend sorting peers into three queues:

  1. available
  2. connecting (max size: 1)
  3. connected
  • Make peers talk

Every phone has a MAC address and an IP address. By the nature of the WiFi Direct connection, the group owner is aware of all the clients MAC addresses, but the clients are not aware of each other.

In order to get clients to talk to each other, they must be aware of each other. To solve this problem, we needed to make the group owner distribute a list of the clients MAC and IP addresses to all clients.

Unfortunately, the Wi-Fi Direct API does not give the group owner direct access to the IP addresses of the clients. The group owner only has access to its clients’ MAC addresses. To get access the clients’ IP addresses, we decided to initiate a socket connection from the client to the group owner.

Once that socket connection was established, we had the client send a string containing its MAC address to the group owner, so the group owner would be able to add the IP of the socket connection to the known MAC of the client, thereby creating a MAC, IP pair.

We then had the group owner store all IP, MAC address pairs in a hashmap, and we distributed this hash map via socket connection back to all the clients.

Limitations of the protocol

All connections must be approved by the user

As it stands, the Wi-Fi Direct implementation on Android requires a user to accept an incoming connection the first time the phones connect. There is a pending Android feature request for a way to automatically accept connections in Wi-Fi Direct.

Issue report on the Android issue tracker.

You can automatically reconnect to a group to which you have already connected, because Wi-Fi Direct contains a specification for remembering “persistent groups,” but these groups are fairly rigid, because the group owner of the previously formed persistent group must remain the group owner, when the group is re-formed.

Stack Overflow question.

A spoke network is the only possible topology

The network requires one, and only one, peer to act as a software access point.

There are no ad-hoc capabilities

The network cannot dynamically change. If a group owner drops out, the network dies.

Issues to watch out for

Only use Wi-Fi Direct on Android 4.2 Jelly Bean and above

It is buggy on versions below 4.2. Issue report on the Android issue tracker.

The MAC address of a device reported by service discovery differs from the hardware address of the network interface that is actually used by the connection.

This is intentional, but can be confusing if you are unaware.

Issue report on the Android issue tracker.

Wi-Fi Direct is not fully supported on all hardware, even if it running Android 4.4.2 or later.

For example, the Moto G cannot connect to a Wi-Fi Direct group and a standard Wi-Fi AP at the same time.

In addition, we encountered some problems when running on the Nexus 5 with Android 4.4.2.

We were unable to find bug reports for any of the following issues we encountered, but they are worth noting. Some of them may be due to bugs in our demo app; some of them may be bugs in the Wi-Fi Direct implementation. We never found fixes for them, so instead we implemented workarounds.

Sometimes when running our app, service discovery would fail with Error code 3 (No Service Requests). This occurred randomly and no pattern was found. The simple solution to this is to stop service discovery and reinitiate it after resetting the service requests. Resetting service requests without cancelling service discovery leads to an infinite loop of Error code 3. You can see an example of this solution below:

                
                if (code == WifiP2pManager.NO_SERVICE_REQUESTS) {

                    // initiate a stop on service discovery
                    manager.stopPeerDiscovery(channel, new WifiP2pManager.ActionListener() {
                        @Override
                        public void onSuccess() {
                            // initiate clearing of the all service requests
                            manager.clearServiceRequests(channel, new WifiP2pManager.ActionListener() {
                                @Override
                                public void onSuccess() {
                                    // reset the service listeners, service requests, and discovery
                                    setServiceListeners();
                                }

                                @Override
                                public void onFailure(int i) {
                                    Log.d(TAG, "FAILED to clear service requests ");
                                }
                            });

                        }

                        @Override
                        public void onFailure(int i) {
                            Log.d(TAG, "FAILED to stop discovery");
                        }
                    });
                }   
        
            

One device would sometimes initiate a connection, but the other device would not connect back.

When a new device would join a group, the other devices would sometimes momentarily think they were disconnected from everyone. We observed this behavior several times.

Alternatives to Wi-Fi Direct

Mobile Ad-hoc Networking (MANET) using 802.11 ad-hoc mode and IETF routing protocols

Mobile Ad-hoc Networks are decentralized networks designed for situations where nodes are moving around, and forming new neighbors frequently. In a MANET, every node is a router.

A MANET can be created by implementing peer-to-peer communication in the Data Link Layer (layer 2) and implementing a routing protocol in the Network Layer (layer 3) of the OSI model.

IEEE 802.11 has an ad-hoc mode that can be used for peer-to-peer communication, and the IETF has developed routing protocols to sit on top of that.

Wi-Fi Direct ≠ 802.11 ad-hoc mode

The Wi-Fi alliance decided to build Wi-Fi Direct on top of the 802.11 infrastructure mode, because it is much more widely supported among devices. In Wi-Fi Direct, all devices in a group must still be connected to a Group Owner, who acts as a software access point.

Wi-Fi Direct uses the common 802.11 infrastructure mode because it is more widely supported, it avoids power consumption issues that are still being ironed out in ad-hoc mode[1], and it can easily use WPA-2. Wi-Fi Direct more easily implements power-saving modes because a Wi-Fi Direct group is always fully connected, which makes it much easier to synchronize power saving state among peers.

A MANET allows for much more flexible network configurations than Wi-Fi Direct. Clearly, a MANET would be optimal for creating a peer-to-peer version of Facebook because peers are constantly moving in and out of range of new peers. Unfortunately, 802.11 ad-hoc mode is not supported in Android (there is a pending feature request).

[1] Quorum-Based Asynchronous Power-Saving Protocols for IEEE 802.11 Ad Hoc Networks